Changeset 2468562
- Timestamp:
- 02/04/2021 08:47:27 AM (4 years ago)
- Location:
- revenue-generator
- Files:
-
- 4 added
- 26 deleted
- 35 edited
- 11 copied
Legend:
- Unmodified
- Added
- Removed
-
revenue-generator/tags/2.0.1/languages/revenue-generator.po
r2466307 r2468562 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Revenue Generator 2.0. 0\n"5 "Project-Id-Version: Revenue Generator 2.0.1\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/revenue-generator\n" 7 7 "Last-Translator: Kimberly Moore <[email protected]>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2021-02-0 1T09:02:16+00:00\n"12 "POT-Creation-Date: 2021-02-04T08:24:31+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.4.0\n" … … 403 403 404 404 #: v1/inc/classes/class-frontend-post.php:780 405 #: v2/inc/classes/class-frontend-post.php:19 4405 #: v2/inc/classes/class-frontend-post.php:191 406 406 msgid "Contribution amount cannot be empty." 407 407 msgstr "" … … 1357 1357 1358 1358 #: v1/templates/frontend/contribution/partial-custom.php:35 1359 #: v2/templates/frontend/contribution/partial-amounts.php: 711359 #: v2/templates/frontend/contribution/partial-amounts.php:98 1360 1360 msgid "Enter custom amount" 1361 1361 msgstr "" … … 1366 1366 1367 1367 #: v1/templates/frontend/contribution/partial-donate.php:37 1368 #: v2/templates/frontend/contribution/partial-amounts.php: 621368 #: v2/templates/frontend/contribution/partial-amounts.php:89 1369 1369 msgid "Custom" 1370 1370 msgstr "" 1371 1371 1372 #: v2/inc/classes/class-frontend-post.php: 2011372 #: v2/inc/classes/class-frontend-post.php:198 1373 1373 msgid "Contribution details cannot be empty." 1374 1374 msgstr "" … … 1431 1431 msgstr "" 1432 1432 1433 #: v2/templates/frontend/contribution/partial-amounts.php: 721433 #: v2/templates/frontend/contribution/partial-amounts.php:99 1434 1434 msgid "Send" 1435 1435 msgstr "" 1436 1436 1437 #: v2/templates/frontend/contribution/partial-amounts.php: 761437 #: v2/templates/frontend/contribution/partial-amounts.php:103 1438 1438 msgid "Add to MyTab" 1439 1439 msgstr "" -
revenue-generator/tags/2.0.1/readme.txt
r2466307 r2468562 7 7 Tested up to: 5.6 8 8 Requires PHP: 5.6 9 Stable tag: 2.0. 09 Stable tag: 2.0.1 10 10 Author URI: https://laterpay.net 11 11 Plugin URI: https://github.com/laterpay/revenue-generator/ … … 82 82 == Changelog == 83 83 84 = 2.0.1 ( 4 February 2021 ) = 85 * Fixed issue with contributions on page cache enabled hosts. 86 84 87 = 2.0.0 ( 1 February 2021 ) = 85 88 * New for contributions-only merchants: on-page purchase and payment experience powered by all new Laterpay platform. … … 126 129 == Upgrade notice == 127 130 131 = 2.0.1 = 132 Fixed issue with contributions on page cache enabled hosts. 133 128 134 = 2.0.0 = 129 135 New on-page purchase and payment experience for contributions-only merchants. Added support for custom post types to paywalls. -
revenue-generator/tags/2.0.1/revenue-generator.php
r2466307 r2468562 4 4 * Description: Monetize your blog and content with Laterpay's Revenue Generator. 5 5 * Plugin URI: https://github.com/laterpay/revenue-generator 6 * Version: 2.0. 06 * Version: 2.0.1 7 7 * Author: Laterpay 8 8 * Text Domain: revenue-generator … … 15 15 defined( 'ABSPATH' ) || exit; 16 16 17 define( 'REVENUE_GENERATOR_VERSION', '2.0. 0' );17 define( 'REVENUE_GENERATOR_VERSION', '2.0.1' ); 18 18 19 19 if ( ! defined( 'REVENUE_GENERATOR_PLUGIN_FILE' ) ) { -
revenue-generator/tags/2.0.1/v2/assets/build/css/frontend.css
r2466307 r2468562 1 .amount-text,.rev-gen-contribution__amount{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;font-weight:600;line-height:1.21;text-align:center;color:#333}.rev-gen-contribution{position:relative;width:100%;margin:20px auto;height:auto;transition:height 0.2s ease-in}.rev-gen-contribution__inner{position:relative;height:100%;padding:18px 25px;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:250px}.rev-gen-contribution__question-mark,.rev-gen-contribution-info-modal__x-mark{position:absolute;top:10px;right:10px;z-index:20;cursor:pointer;width:18px;height:18px;border-radius:50%;font- weight:700;font-size:12px;background-color:#1d1d1d;color:#fff;text-align:center}.rev-gen-contribution__question-mark span,.rev-gen-contribution-info-modal__x-mark span{position:relative;left:1px}.rev-gen-contribution-modal .rev-gen-contribution__question-mark,.rev-gen-contribution-modal .rev-gen-contribution-info-modal__x-mark{top:13px;right:35px}.rev-gen-contribution-info-modal{position:absolute;top:0;left:0;z-index:50;padding:20px;border-radius:5px;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution-info-modal__x-mark span{position:relative;top:-1px}.rev-gen-contribution-info-modal__title{margin:0;font-weight:500;font-size:18px}.rev-gen-contribution-info-modal__steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.rev-gen-contribution-info-modal__step{display:flex;align-items:center;margin:0;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__step-text{margin-left:6px;margin-right:10px}.rev-gen-contribution-info-modal__step-number{display:flex;align-items:center;justify-content:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.rev-gen-contribution-info-modal__description{font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__description p{margin-bottom:1em}.rev-gen-contribution-info-modal__description p:last-child{margin-bottom:0}.rev-gen-contribution h2.rev-gen-contribution__title{margin:0;max-width:100%;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:bold;line-height:1.33;font-size:21px;text-align:center;color:#1d1d1d}.rev-gen-contribution h2.rev-gen-contribution__title::before,.rev-gen-contribution h2.rev-gen-contribution__title::after{display:none !important}.rev-gen-contribution__description{max-width:100%;font-size:14px;text-align:center}.rev-gen-contribution__amounts{display:flex;flex-flow:row nowrap;justify-content:space-between;margin-bottom:20px}.rev-gen-contribution--bar .rev-gen-contribution__amounts{justify-content:center}.rev-gen-contribution__form{margin:20px 0}.rev-gen-contribution__form.amp-form-submit-success,.rev-gen-contribution__form.amp-form-submit-error{margin:0}.rev-gen-contribution__form button[type="submit"]{max-width:100%;flex:0 1 100%;width:100%;padding:15px 0;font-size:15px;border:1px solid #000;border-radius:4px;font-weight:500;background:#1d1d1d !important;color:#fff !important;text-decoration:none;text-transform:none;text-shadow:none}.rev-gen-contribution__form button[type="submit"].show{display:block}.rev-gen-contribution .rev-gen-hidden{display:none}.rev-gen-contribution__amount{min-width:75px;border:solid 2px #1d1d1d;border-radius:5px;margin:0 2px;display:flex;align-items:center;text-align:center;justify-content:center;overflow:hidden;cursor:pointer;word-break:normal;color:#1d1d1d;background-color:#fff}.rev-gen-contribution__amount input{position:absolute;opacity:0;width:0;height:0}.rev-gen-contribution__amount--custom{outline:0;text-transform:none;text-decoration:none}.rev-gen-contribution__amount--custom:hover,.rev-gen-contribution__amount--custom:active,.rev-gen-contribution__amount--custom:focus{background:#1d1d1d !important;color:#fff !important;text-decoration:none}.rev-gen-contribution__amount .rev-gen-contribution-control__label{display:block;width:100%;height:100%;border:0;padding:15px;font-size:14px;background:#fff !important;color:#1d1d1d !important;box-shadow:none !important;transition:background-color 0.05s ease-in !important;text-decoration:none !important;text-transform:none !important;letter-spacing:0 !important}.rev-gen-contribution__amount .rev-gen-contribution-control__label:hover{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount input:checked+.rev-gen-contribution-control__label{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount-wrapper{position:relative;display:flex;justify-content:center}.rev-gen-contribution__tip{margin:0 0 5px;line-height:1;font-size:13px;text-align:center}.rev-gen-contribution__tip.rev-gen-hidden{visibility:hidden}.rev-gen-contribution__custom input[type="number"]{min-width:220px;margin-right:5px;padding:13.5px 0 13px 15px;border-radius:5px;background-color:rgba(160,160,160,0.12);margin-bottom:10px;font-size:14px;outline:0;border:0}.rev-gen-contribution__custom.rev-gen-hidden:not[hidden]{display:none}.rev-gen-contribution__tab-status{height:100%;font-size:14px;text-align:center;transition:min-height 0.2s ease-in}.rev-gen-contribution__tab-status iframe{width:100%;height:0;margin:0 !important;padding:0 !important;border:0 !important}.rev-gen-contribution__response{position:relative;z-index:2;width:100%;background-color:#fff}.rev-gen-contribution__loading{position:absolute;z-index:1;top:50%;margin-top:-32px;left:50%;margin-left:-38px}.rev-gen-contribution-custom{max-width:335px;margin:10px auto;display:flex;flex-flow:row nowrap;align-items:center}.rev-gen-contribution-custom__group{flex:1;display:flex;flex-flow:row nowrap}.rev-gen-contribution-custom__inner{display:flex;flex-flow:row nowrap;align-items:flex-end;justify-content:space-between}.rev-gen-contribution-custom__form{display:flex;align-items:flex-end}.rev-gen-contribution-custom h3.rev-gen-contribution-custom__title{margin:0;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;line-height:1.33;font-size:14px;color:#1d1d1d}.rev-gen-contribution-custom__back{position:relative;bottom:5px;float:left;cursor:pointer;width:15px;margin-right:15px}.rev-gen-contribution-custom__back-arrow{display:inline-block;vertical-align:middle;border:solid #000;border-width:0 2px 2px 0;padding:14px;transform:rotate(135deg)}.rev-gen-contribution-custom__symbol{width:15px;text-align:center}.rev-gen-contribution-custom label{display:block;margin-left:15px;margin-bottom:5px;line-height:1;font-weight:normal;font-size:12px}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send{flex:1;width:auto;min-width:70px;max-width:none;max-height:49px;margin:0;padding:14px 10px !important;border:2px solid #1d1d1d !important;border-radius:5px;font-weight:700;font-size:14px;color:#1d1d1d !important;background-color:#fff !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:active,.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:hover{color:#fff !important;background-color:#1d1d1d !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:disabled{opacity:0.8}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send .rev-gen-contribution-custom-send__loading{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading{padding:11px 10px !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__text{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__loading{display:inline-block;width:21px;height:21px;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMiIgYmFzZVByb2ZpbGU9InRpbnkiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTAwIDUwMCIgb3ZlcmZsb3c9InZpc2libGUiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Ik0zMTcsNDc5LjRjLTEyLDAtMjMuMy03LjYtMjcuNC0xOS42Yy01LjItMTUuMSwyLjktMzEuNiwxOC0zNi44YzcxLjUtMjQuNiwxMTkuNS05MS45LDExOS41LTE2Ny41CgkJYzAtOTcuNi03OS40LTE3Ny4xLTE3Ny4xLTE3Ny4xUzcyLjksMTU3LjksNzIuOSwyNTUuNmMwLDc1LjYsNDgsMTQzLDExOS41LDE2Ny41YzE1LjEsNS4yLDIzLjIsMjEuNywxOCwzNi44cy0yMS43LDIzLjItMzYuOCwxOAoJCUM3OC43LDQ0NS4zLDE1LDM1NS45LDE1LDI1NS42YzAtMTI5LjYsMTA1LjQtMjM1LDIzNS0yMzVzMjM1LDEwNS40LDIzNSwyMzVjMCwxMDAuNC02My43LDE4OS43LTE1OC42LDIyMi4zCgkJQzMyMy4zLDQ3OC45LDMyMC4xLDQ3OS40LDMxNyw0NzkuNHoiLz4KPC9nPgo8L3N2Zz4K) no-repeat;background-size:21px 21px;transition:transform 0.2s ease-in-out;-webkit-animation:pulse-loading 1s infinite;animation:pulse-loading 1s infinite}.rev-gen-contribution-footer{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif}.rev-gen-contribution-footer__inner{display:flex;align-items:center;justify-content:center}.rev-gen-contribution-footer a{flex:1;margin-left:5px;max-width:75px;opacity:0.6;transition:opacity 0.2s ease-in}.rev-gen-contribution-footer a:hover{opacity:1}.rev-gen-contribution-footer a img{vertical-align:middle}.rev-gen-contribution-footer span{position:relative;top:2px;line-height:1.1;font-size:11px;color:#808080}.rev-gen-contribution--box{max-width:380px !important}.rev-gen-contribution--bar{width:100%}.rev-gen-contribution--bar .rev-gen-contribution__donate{margin:15px 0 5px}.rev-gen-contribution--bar .rev-gen-contribution__inner{max-width:100%;padding:15px 25px}.rev-gen-contribution--bar.size-large h2.rev-gen-contribution__title{min-width:250px;margin-right:15px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__inner{padding:0 25px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__choose{display:flex;align-items:center}.rev-gen-contribution--bar.size-large .rev-gen-contribution__description{min-width:250px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form{margin:15px 0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form button[type="submit"]{width:300px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__amounts{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__donate{align-self:flex-end;margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-info-modal{left:auto;right:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom{margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom label{display:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom__back{bottom:auto;float:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom input[type="number"]{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom button[type="submit"]{width:auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution__loading{transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response{display:flex;align-items:center;transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response .tab_widget__container{height:85px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer{margin-left:15px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer a{width:75px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__tab-status{position:relative;min-width:250px;height:85px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__loading{left:0;margin-left:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__response{height:100%;overflow:hidden;margin-right:10px;transform:none;background-color:transparent}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution iframe{height:85px !important}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution-footer{display:none}.rev-gen-contribution--bar.size-large.amount-selected .rev-gen-contribution__amounts{display:none}.rev-gen-contribution--bar.size-large.rev-gen-iframe-ready iframe{width:600px}.rev-gen-contribution--button .rev-gen-contribution__inner{padding:0;box-shadow:none;background-color:transparent;text-align:center}.rev-gen-contribution--button .rev-gen-contribution__footer{margin-top:15px}.rev-gen-contribution--button .rev-gen-contribution__button{max-width:320px;padding:15px 30px;border:0;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:16px;color:#fff;background-color:#1d1d1d;text-decoration:none}.rev-gen-contribution--button .rev-gen-contribution__button:hover,.rev-gen-contribution--button .rev-gen-contribution__button:active{border:0;box-shadow:none;text-decoration:none}.rev-gen-contribution--button:not(.is-amp) .rev-gen-contribution-modal{display:none}.rev-gen-contribution.is-amp iframe{position:relative;z-index:15}.rev-gen-contribution .amp-form-submit-success>*{display:none}.rev-gen-contribution .amp-form-submitting{height:100px}.rev-gen-contribution__amp-show-modal,.rev-gen-contribution__amp-show-modal--purchase{position:absolute;bottom:35px;left:165px;z-index:10;width:95px;height:20px;display:block;background:transparent;cursor:pointer}.rev-gen-contribution__amp-show-modal--purchase{top:72px;bottom:auto}.rev-gen-contribution-modal{position:fixed;top:0;left:0;z-index:9999;display:flex;align-items:center;width:100%;height:100%;background-color:rgba(0,0,0,0.5);opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution{opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution__inner{padding:30px 25px 18px;background-color:#fff}.rev-gen-contribution-modal.active{opacity:1}.rev-gen-contribution-modal.active .rev-gen-contribution{opacity:1}.rev-gen-contribution-modal__close{position:absolute;top:15px;right:15px;display:inline-block;width:15px;height:15px;padding:0 !important;border:0 !important;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMyIgaGVpZ2h0PSIxMyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEzIDEzIj4KICAgIDxwYXRoIGZpbGw9IiMxRDFEMUQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTguMDMyIDYuNUwxMyAxLjUzMSAxMS40NjggMCA2LjUgNC45NjggMS41MzIgMCAwIDEuNTMybDQuOTY4IDQuOTY3TDAgMTEuNDY3bDEuNTMyIDEuNTMyTDYuNSA4LjAzbDQuOTY4IDQuOTY4TDEzIDExLjQ2NyA4LjAzMiA2LjQ5OXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgo8L3N2Zz4K) no-repeat !important;background-size:15px 15px !important;opacity:0.35}.is-amp .rev-gen-contribution-modal{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution-amp-wrap{display:flex;width:100%;height:100%;align-items:center}@-webkit-keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}.font,.tab_widget__donated-amount-text,.tab_widget__thank-you-message,.tab_widget__regular-text,.tab_widget__link,.tab__widget__info-button-question-mark,.tab_widget__info_container{font-family:"Helvetica Neue", Arial, Helvetica, sans-serif}.tab_widget{display:flex;justify-content:center;align-items:center;height:100%}.tab_widget__container{position:relative;background-color:#fff;border-radius:6px;display:flex;align-items:center;width:340px;height:104px;transition:transform 0.5s linear}.tab_widget__container-visible{transform:translate(0)}.tab_widget__arc-container{margin-right:6px;width:calc(64px + 6px);height:64px;position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:center}.tab_widget__arc--background{position:absolute;stroke:#cbd5e0}.tab_widget__arc--filled{position:absolute;stroke:#000;stroke-dasharray:175.84;stroke-dashoffset:175.84}.tab_widget__arc-animation{-webkit-animation:animateTabAmount 0.5s linear forwards;animation:animateTabAmount 0.5s linear forwards}.tab_widget__arc-animation--pulse{stroke:#000;animation:pulse 1s ease-in-out alternate-reverse infinite}.tab_widget__arc-animation--pulse circle{stroke:#000;stroke-opacity:inherit}@-webkit-keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@-webkit-keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}@keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}.tab_widget__donated-amount-text{font-weight:700}.tab_widget__thank-you-message{font-weight:500;margin:0;margin-bottom:5px;font-size:19px;color:#1d1d1d;text-align:left}.tab_widget__regular-text{font-weight:400;font-size:15px;margin:0;margin-bottom:5px;color:#333}.tab_widget__links-container{display:flex;align-items:center}.tab_widget__link{font-weight:400;margin:0;font-size:13px;color:#1d1d1d;text-decoration:underline;cursor:pointer}.tab_widget__links-separator{padding-right:5px;padding-left:5px;color:#333}.tab_widget__container-hidden{transform:translate(500px)}.tab__widget__info-button__container{position:absolute;right:6px;top:6px;cursor:pointer}.tab__widget__info-button{position:relative}.tab__widget__info-button-question-mark{position:absolute;font-weight:700;font-size:12px;color:#fff;left:34%;top:0}.tab__widget__close-button-x-mark{left:33%;top:-1px}.tab_widget__container__info-screen{position:absolute;height:100%;width:calc(100% + 50px);margin-top:-35px;margin-left:-25px;z-index:10;visibility:var(--infoScreenVisibility);text-align:left}.tab_widget__info_container{position:relative;padding:20px;background-color:#fff;box-shadow:0 1px 8px 0 rgba(29,29,29,0.16);border-radius:6px}.tab_widget__info-title{font-weight:500;font-size:18px;margin:0}.tab_widget__info-steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.tab_widget__info-step{display:flex;align-items:center;font-weight:500;font-size:14px;margin:0}.tab_widget__info-step-text{margin-left:6px;margin-right:10px}.tab_widget__info-step-number{display:flex;justify-content:center;align-items:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.tab_widget__info-description{font-weight:500;font-size:14px}.tab_widget__info-description p{margin-bottom:1em}.tab_widget__info-description p:last-child{margin-bottom:0}.tab__widget__icon{position:unset;height:18px;width:18px}1 .amount-text,.rev-gen-contribution__amount{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;font-weight:600;line-height:1.21;text-align:center;color:#333}.rev-gen-contribution{position:relative;width:100%;margin:20px auto;height:auto;transition:height 0.2s ease-in}.rev-gen-contribution__inner{position:relative;height:100%;padding:18px 25px;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:250px}.rev-gen-contribution__question-mark,.rev-gen-contribution-info-modal__x-mark{position:absolute;top:10px;right:10px;z-index:20;cursor:pointer;width:18px;height:18px;border-radius:50%;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:700;font-size:12px;background-color:#1d1d1d;color:#fff;text-align:center}.rev-gen-contribution__question-mark span,.rev-gen-contribution-info-modal__x-mark span{position:relative;left:1px}.rev-gen-contribution-modal .rev-gen-contribution__question-mark,.rev-gen-contribution-modal .rev-gen-contribution-info-modal__x-mark{top:13px;right:35px}.rev-gen-contribution-info-modal{position:absolute;top:0;left:0;z-index:50;padding:20px;border-radius:5px;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution-info-modal__x-mark span{position:relative;top:-1px}.rev-gen-contribution-info-modal__title{margin:0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:18px}.rev-gen-contribution-info-modal__steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.rev-gen-contribution-info-modal__step{display:flex;align-items:center;margin:0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__step-text{margin-left:6px;margin-right:10px}.rev-gen-contribution-info-modal__step-number{display:flex;align-items:center;justify-content:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.rev-gen-contribution-info-modal__description p{margin-bottom:1em;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__description p:last-child{margin-bottom:0}.rev-gen-contribution h2.rev-gen-contribution__title{margin:0;max-width:100%;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:bold;line-height:1.33;font-size:21px;text-align:center;color:#1d1d1d}.rev-gen-contribution h2.rev-gen-contribution__title::before,.rev-gen-contribution h2.rev-gen-contribution__title::after{display:none !important}.rev-gen-contribution__description{max-width:100%;font-size:14px;text-align:center}.rev-gen-contribution__amounts{display:flex;flex-flow:row nowrap;justify-content:space-between;margin-bottom:20px}.rev-gen-contribution--bar .rev-gen-contribution__amounts{justify-content:center}.rev-gen-contribution__form{margin:20px 0}.rev-gen-contribution__form.amp-form-submit-success,.rev-gen-contribution__form.amp-form-submit-error{max-height:250px;overflow:hidden;margin:0}.rev-gen-contribution__form div[submit-success]{position:relative;z-index:10}.rev-gen-contribution__form button[type="submit"]{cursor:pointer;max-width:100%;flex:0 1 100%;width:100%;padding:15px 0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:15px;border:1px solid #000;border-radius:4px;font-weight:500;background:#1d1d1d !important;color:#fff !important;text-decoration:none;text-transform:none;text-shadow:none}.rev-gen-contribution__form button[type="submit"].show{display:block}.rev-gen-contribution .rev-gen-hidden{display:none}.rev-gen-contribution__amount{min-width:75px;border:solid 2px #1d1d1d;border-radius:5px;margin:0 2px;display:flex;align-items:center;text-align:center;justify-content:center;overflow:hidden;cursor:pointer;word-break:normal;color:#1d1d1d;background-color:#fff}.rev-gen-contribution__amount input{position:absolute;opacity:0;width:0;height:0}.rev-gen-contribution__amount--custom{outline:0;text-transform:none;text-decoration:none}.rev-gen-contribution__amount--custom:hover,.rev-gen-contribution__amount--custom:active,.rev-gen-contribution__amount--custom:focus{background:#1d1d1d !important;color:#fff !important;text-decoration:none}.rev-gen-contribution__amount .rev-gen-contribution-control__label{display:block;width:100%;height:100%;border:0;padding:15px;font-size:14px;background:#fff !important;color:#1d1d1d !important;box-shadow:none !important;transition:background-color 0.05s ease-in !important;text-decoration:none !important;text-transform:none !important;letter-spacing:0 !important}.rev-gen-contribution__amount .rev-gen-contribution-control__label:hover{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount input:checked+.rev-gen-contribution-control__label{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount-wrapper{position:relative;display:flex;justify-content:center}.rev-gen-contribution__tip{margin:0 0 5px;line-height:1;font-size:13px;text-align:center}.rev-gen-contribution__tip.rev-gen-hidden{visibility:hidden}.rev-gen-contribution__custom input[type="number"]{min-width:220px;margin:0 5px 0 0;padding:13.5px 0 13px 15px;border-radius:5px;background-color:rgba(160,160,160,0.12);font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;outline:0;border:0}.rev-gen-contribution__custom.rev-gen-hidden:not[hidden]{display:none}.rev-gen-contribution__tab-status{height:100%;font-size:14px;text-align:center;transition:min-height 0.2s ease-in}.rev-gen-contribution__tab-status iframe{width:100%;height:0;margin:0 !important;padding:0 !important;border:0 !important}.rev-gen-contribution__response{position:relative;z-index:2;width:100%;background-color:#fff}.rev-gen-contribution__loading{position:absolute;z-index:1;top:50%;margin-top:-32px;left:50%;margin-left:-38px}.rev-gen-contribution-custom{max-width:335px;margin:10px auto;display:flex;flex-flow:row nowrap;align-items:center}.rev-gen-contribution-custom__group{flex:1;display:flex;flex-flow:row nowrap}.rev-gen-contribution-custom__inner{display:flex;flex-flow:row nowrap;align-items:flex-end;justify-content:space-between}.rev-gen-contribution-custom__form{display:flex;align-items:flex-end}.rev-gen-contribution-custom h3.rev-gen-contribution-custom__title{margin:0;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;line-height:1.33;font-size:14px;color:#1d1d1d}.rev-gen-contribution-custom__back{position:relative;bottom:0;float:left;cursor:pointer;width:15px;margin-right:15px}.rev-gen-contribution-custom__back-arrow{display:inline-block;vertical-align:middle;border:solid #000;border-width:0 2px 2px 0;padding:14px;transform:rotate(135deg)}.rev-gen-contribution-custom__symbol{width:15px;text-align:center}.rev-gen-contribution-custom label{display:block;margin-left:15px;margin-bottom:5px;line-height:1;font-weight:normal;font-size:12px}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send{flex:1;width:auto;min-width:70px;max-width:none;max-height:49px;margin:0;padding:14px 10px !important;border:2px solid #1d1d1d !important;border-radius:5px;font-weight:700;font-size:14px;color:#1d1d1d !important;background-color:#fff !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:active,.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:hover{color:#fff !important;background-color:#1d1d1d !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:disabled{opacity:0.8}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send .rev-gen-contribution-custom-send__loading{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading{padding:11px 10px !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__text{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__loading{display:inline-block;width:21px;height:21px;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMiIgYmFzZVByb2ZpbGU9InRpbnkiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTAwIDUwMCIgb3ZlcmZsb3c9InZpc2libGUiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Ik0zMTcsNDc5LjRjLTEyLDAtMjMuMy03LjYtMjcuNC0xOS42Yy01LjItMTUuMSwyLjktMzEuNiwxOC0zNi44YzcxLjUtMjQuNiwxMTkuNS05MS45LDExOS41LTE2Ny41CgkJYzAtOTcuNi03OS40LTE3Ny4xLTE3Ny4xLTE3Ny4xUzcyLjksMTU3LjksNzIuOSwyNTUuNmMwLDc1LjYsNDgsMTQzLDExOS41LDE2Ny41YzE1LjEsNS4yLDIzLjIsMjEuNywxOCwzNi44cy0yMS43LDIzLjItMzYuOCwxOAoJCUM3OC43LDQ0NS4zLDE1LDM1NS45LDE1LDI1NS42YzAtMTI5LjYsMTA1LjQtMjM1LDIzNS0yMzVzMjM1LDEwNS40LDIzNSwyMzVjMCwxMDAuNC02My43LDE4OS43LTE1OC42LDIyMi4zCgkJQzMyMy4zLDQ3OC45LDMyMC4xLDQ3OS40LDMxNyw0NzkuNHoiLz4KPC9nPgo8L3N2Zz4K) no-repeat;background-size:21px 21px;transition:transform 0.2s ease-in-out;-webkit-animation:pulse-loading 1s infinite;animation:pulse-loading 1s infinite}.rev-gen-contribution-footer{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif}.rev-gen-contribution-footer__inner{display:flex;align-items:center;justify-content:center}.rev-gen-contribution-footer a{flex:1;margin-left:5px;max-width:75px;opacity:0.6;transition:opacity 0.2s ease-in}.rev-gen-contribution-footer a:hover{opacity:1}.rev-gen-contribution-footer a img{vertical-align:middle}.rev-gen-contribution-footer span{position:relative;top:2px;line-height:1.1;font-size:11px;color:#808080}.rev-gen-contribution--box{max-width:380px !important}.rev-gen-contribution--bar{width:100%}.rev-gen-contribution--bar .rev-gen-contribution__donate{margin:15px 0 5px}.rev-gen-contribution--bar .rev-gen-contribution__inner{max-width:100%;padding:15px 25px}.rev-gen-contribution--bar.size-large h2.rev-gen-contribution__title{min-width:250px;margin-right:15px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__inner{padding:0 25px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__choose{display:flex;align-items:center}.rev-gen-contribution--bar.size-large .rev-gen-contribution__description{min-width:250px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form{margin:15px 0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form button[type="submit"]{width:300px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__amounts{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__donate{align-self:flex-end;margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-info-modal{left:auto;right:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom{margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom label{display:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom__back{bottom:auto;float:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom input[type="number"]{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom button[type="submit"]{width:auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution__loading{transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response{display:flex;align-items:center;transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response .tab_widget__container{height:85px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer{margin-left:15px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer a{width:75px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__tab-status{position:relative;min-width:250px;height:85px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__loading{left:0;margin-left:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__response{height:100%;overflow:hidden;margin-right:10px;transform:none;background-color:transparent}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution iframe{height:85px !important}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution-footer{display:none}.rev-gen-contribution--bar.size-large.amount-selected .rev-gen-contribution__amounts{display:none}.rev-gen-contribution--bar.size-large.rev-gen-iframe-ready iframe{width:600px}.rev-gen-contribution--button .rev-gen-contribution__inner{padding:0;box-shadow:none;background-color:transparent;text-align:center}.rev-gen-contribution--button .rev-gen-contribution__footer{margin-top:15px}.rev-gen-contribution--button .rev-gen-contribution__button{max-width:320px;padding:15px 30px;border:0;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:16px;color:#fff;background-color:#1d1d1d;text-decoration:none}.rev-gen-contribution--button .rev-gen-contribution__button:hover,.rev-gen-contribution--button .rev-gen-contribution__button:active{border:0;box-shadow:none;text-decoration:none}.rev-gen-contribution--button:not(.is-amp) .rev-gen-contribution-modal{display:none}.rev-gen-contribution.is-amp iframe{position:relative;z-index:15}.rev-gen-contribution .amp-form-submit-success>*{display:none}.rev-gen-contribution .amp-form-submitting{height:100px}.rev-gen-contribution__amp-show-modal,.rev-gen-contribution__amp-show-modal--purchase{position:absolute;bottom:19px;left:137px;z-index:10;width:95px;height:20px;display:block;background:transparent;cursor:pointer}.rev-gen-contribution__amp-show-modal--purchase{top:72px;bottom:auto}.rev-gen-contribution-modal{position:fixed;top:0;left:0;z-index:9999;display:flex;align-items:center;width:100%;height:100%;background-color:rgba(0,0,0,0.5);opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution{opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution__inner{padding:30px 25px 18px;background-color:#fff}.rev-gen-contribution-modal.active{opacity:1}.rev-gen-contribution-modal.active .rev-gen-contribution{opacity:1}.rev-gen-contribution-modal__close{position:absolute;top:15px;right:15px;display:inline-block;width:15px;height:15px;padding:0 !important;border:0 !important;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMyIgaGVpZ2h0PSIxMyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEzIDEzIj4KICAgIDxwYXRoIGZpbGw9IiMxRDFEMUQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTguMDMyIDYuNUwxMyAxLjUzMSAxMS40NjggMCA2LjUgNC45NjggMS41MzIgMCAwIDEuNTMybDQuOTY4IDQuOTY3TDAgMTEuNDY3bDEuNTMyIDEuNTMyTDYuNSA4LjAzbDQuOTY4IDQuOTY4TDEzIDExLjQ2NyA4LjAzMiA2LjQ5OXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgo8L3N2Zz4K) no-repeat !important;background-size:15px 15px !important;opacity:0.35}.is-amp .rev-gen-contribution-modal{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution-amp-wrap{display:flex;width:100%;height:100%;align-items:center}@-webkit-keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}.font,.tab_widget__donated-amount-text,.tab_widget__thank-you-message,.tab_widget__regular-text,a.tab_widget__link,.tab__widget__info-button-question-mark,.tab_widget__info_container{font-family:"Helvetica Neue", Arial, Helvetica, sans-serif}.tab_widget{display:flex;justify-content:center;align-items:center;height:100%}.tab_widget__container{position:relative;background-color:#fff;border-radius:6px;display:flex;align-items:center;width:340px;height:104px;transition:transform 0.5s linear}.tab_widget__container-visible{transform:translate(0)}.tab_widget__arc-container{margin-right:6px;width:calc(64px + 6px);height:64px;position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:center}.tab_widget__arc--background{position:absolute;stroke:#cbd5e0}.tab_widget__arc--filled{position:absolute;stroke:#000;stroke-dasharray:175.84;stroke-dashoffset:175.84}.tab_widget__arc-animation{-webkit-animation:animateTabAmount 0.5s linear forwards;animation:animateTabAmount 0.5s linear forwards}.tab_widget__arc-animation--pulse{stroke:#000;animation:pulse 1s ease-in-out alternate-reverse infinite}.tab_widget__arc-animation--pulse circle{stroke:#000;stroke-opacity:inherit}@-webkit-keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@-webkit-keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}@keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}.tab_widget__donated-amount-text{font-weight:700}.tab_widget__thank-you-message{font-weight:500;margin:0;margin-bottom:5px;font-size:19px;color:#1d1d1d;text-align:left}.tab_widget__regular-text{font-weight:400;font-size:15px;margin:0;margin-bottom:5px;color:#333}.tab_widget__links-container{display:flex;align-items:center}a.tab_widget__link{font-weight:400;margin:0;font-size:13px;color:#1d1d1d;text-decoration:underline;cursor:pointer}a.tab_widget__link:hover,a.tab_widget__link:visited{color:#1d1d1d}.tab_widget__links-separator{padding-right:5px;padding-left:5px;color:#333}.tab_widget__container-hidden{transform:translate(500px)}.tab__widget__info-button__container{position:absolute;right:6px;top:6px;cursor:pointer}.tab__widget__info-button{position:relative}.tab__widget__info-button-question-mark{position:absolute;font-weight:700;font-size:12px;color:#fff;left:34%;top:0}.tab__widget__close-button-x-mark{left:33%;top:-1px}.tab_widget__container__info-screen{position:absolute;height:100%;width:calc(100% + 50px);margin-top:-35px;margin-left:-25px;z-index:10;visibility:var(--infoScreenVisibility);text-align:left}.tab_widget__info_container{position:relative;padding:20px;background-color:#fff;box-shadow:0 1px 8px 0 rgba(29,29,29,0.16);border-radius:6px}.tab_widget__info-title{font-weight:500;font-size:18px;margin:0}.tab_widget__info-steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.tab_widget__info-step{display:flex;align-items:center;font-weight:500;font-size:14px;margin:0}.tab_widget__info-step-text{margin-left:6px;margin-right:10px}.tab_widget__info-step-number{display:flex;justify-content:center;align-items:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.tab_widget__info-description{font-weight:500;font-size:14px}.tab_widget__info-description p{margin-bottom:1em}.tab_widget__info-description p:last-child{margin-bottom:0}.tab__widget__icon{position:unset;height:18px;width:18px} 2 2 -
revenue-generator/tags/2.0.1/v2/assets/build/frontend.js
r2466307 r2468562 1 (()=>{"use strict";(()=>{const t=t=>{const e=t+"=",o=decodeURIComponent(document.cookie).split(";");for(let t=0;t<o.length;t++){let s=o[t];for(;" "===s.charAt(0);)s=s.substring(1);if(0===s.indexOf(e))return s.substring(e.length,s.length)}return""};class e{constructor(t){this.el=t,this.itemId=this.el.dataset.contributionId,this.closeTimeout=null,this.RESET_TIMEOUT=3e3,this.$o={form:t.querySelector(".rev-gen-contribution__form"),submitButton:t.querySelector("button[type=submit][data-mytab-button]"),amounts:t.querySelector(".rev-gen-contribution__amounts"),choose:t.querySelector(".rev-gen-contribution__choose"),customChoice:t.querySelector(".rev-gen-contribution__amount--custom"),response:t.querySelector(".rev-gen-contribution__response"),loading:t.querySelector(".rev-gen-contribution__loading"),custom:{el:t.querySelector(".rev-gen-contribution__custom"),input:t.querySelector(".rev-gen-contribution__custom input"),backButton:t.querySelector(".rev-gen-contribution-custom__back")},modal:{el:t.querySelector(".rev-gen-contribution-info-modal"),openButton:t.querySelector(".rev-gen-contribution__question-mark"),closeButton:t.querySelector(".rev-gen-contribution-info-modal__x-mark")}},this.bindEvents(),this.maybeContinueFlow()}bindEvents(){const t=this;new ResizeObserver((t=>{t.forEach((t=>{const e=t.target.dataset.breakpoints?JSON.parse(t.target.dataset.breakpoints):"";e&&Object.keys(e).forEach((o=>{const s=e[o],n="size-"+o;t.contentRect.width>=s?t.target.classList.add(n):t.target.classList.remove(n)}))}))})).observe(this.el),this.$o.customChoice.addEventListener("click",(t=>{t.preventDefault(),this.showCustomForm()})),this.$o.custom.backButton.addEventListener("click",(t=>{t.preventDefault(),this.hideCustomForm()})),this.$o.form.addEventListener("change",(()=>{this.customModeActive||(new FormData(this.$o.form).get("amount")?(this.el.classList.add("amount-selected"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.submitButton.removeAttribute("hidden")):(this.el.classList.remove("amount-selected"),this.$o.submitButton.classList.add("rev-gen-hidden"),this.$o.submitButton.addAttribute("hidden")))})),this.$o.form.addEventListener("submit",(e=>{e.preventDefault();const o=new FormData(this.$o.form),s=new XMLHttpRequest;s.open("POST",this.$o.form.getAttribute("action"),!0),s.send(o),s.onreadystatechange=function(){if(4===this.readyState){const e=JSON.parse(this.response);switch(this.status){case 200:const o=document.createElement("script");o.src=t.$o.form.dataset.tabWidgetUrl,t.$o.response.appendChild(o),t.$o.response.innerHTML=e.data.html,o.onload=()=>{t.$o.choose.classList.add("rev-gen-hidden");const e=t.el.querySelectorAll(".tab_widget__link")[1];t.setCloseTimeout(),e.addEventListener("click",(()=>{t.openInfoModal()})),t.hideSubmit()};break;case 402:t.$o.modal.openButton.classList.add("rev-gen-hidden"),t.$o.loading.classList.remove("rev-gen-hidden"),t.el.classList.add("rev-gen-contribution--payment"),t.$o.response.innerHTML=e.data.html,t.$o.choose.classList.add("rev-gen-hidden"),t.hideSubmit();break;case 401:window.location.href=e.data.auth_url}}}})),this.$o.modal.openButton.addEventListener("click",(()=>{t.openInfoModal()})),this.$o.modal.closeButton.addEventListener("click",(()=>{t.closeInfoModal()})),window.addEventListener("message",(e=>{e.data&&"OPEN_INFO_MODAL"===e.data&&t.openInfoModal()})),window.addEventListener("message",(e=>{e.data&&"PAYMENT_SUCCESSFUL"===e.data&&t.reset()})),this.el.addEventListener("rev-gen-iframe-load",(e=>{const o=e.detail||"";o&&(t.$o.loading.classList.add("rev-gen-hidden"),t.$o.modal.openButton.classList.remove("rev-gen-hidden"),o.style.height=o.contentWindow.document.body.scrollHeight+"px",t.el.classList.add("rev-gen-iframe-ready"))}))}hideSubmit(){this.$o.submitButton.classList.add("rev-gen-hidden")}showCustomForm(){this.customModeActive=!0,this.$o.amounts.classList.add("rev-gen-hidden"),this.$o.custom.el.classList.remove("rev-gen-hidden"),this.$o.custom.el.removeAttribute("hidden"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.custom.input.focus()}hideCustomForm(){this.customModeActive=!1,this.$o.form.reset(),this.$o.custom.el.classList.add("rev-gen-hidden"),this.$o.custom.el.setAttribute("hidden",""),this.$o.amounts.classList.remove("rev-gen-hidden"),this.$o.submitButton.classList.add("rev-gen-hidden")}openInfoModal(){clearTimeout(this.closeTimeout),this.$o.modal.el.classList.remove("rev-gen-hidden")}closeInfoModal(){this.$o.modal.el.classList.add("rev-gen-hidden")}reset(){this.el.classList.remove("amount-selected"),this.$o.response.innerHTML="",this.el.classList.remove("rev-gen-contribution--payment"),this.$o.form.reset(),this.$o.choose.classList.remove("rev-gen-hidden")}setCloseTimeout(){const t=this;this.closeTimeout=setTimeout((()=>{t.reset()}),t.RESET_TIMEOUT)}maybeContinueFlow(){if(!t("rgv2_data"))return;const e=JSON.parse(t("rgv2_data"));if(parseInt(this.itemId,10)!==parseInt(e.contribution.item_id,10))return;const o=this.$o.form.querySelector('[value="'+e.contribution.amount+'"]');o?o.checked=!0:(this.$o.custom.input.value=o,this.showCustomForm());const s=new MouseEvent("click");this.$o.submitButton.dispatchEvent(s)}}window.laterpayIframeLoaded=t=>{const e=t.dataset.contributionId;if(!e)return;const o=new CustomEvent("rev-gen-iframe-load",{detail:t});let s=document.querySelectorAll('.rev-gen-contribution[data-contribution-id="'+e+'"]');s=s[s.length-1],s.dispatchEvent(o)};class o{constructor(t){this.$button={trigger:t.querySelector("button"),modal:t.querySelector(".rev-gen-contribution-modal")},this.$modal={el:""},this.bindButtonEvents()}bindButtonEvents(){this.$button.trigger.addEventListener("click",this.open.bind(this))}bindModalEvents(){this.$modal.closeButton.addEventListener("click",this.close.bind(this))}open(t){t.preventDefault();const e=this.$button.modal.cloneNode(!0);this.$modal.el=e,this.$modal.contributionEl=e.querySelector(".rev-gen-contribution"),this.$modal.closeButton=e.querySelector(".rev-gen-contribution-modal__close"),document.querySelector("body").appendChild(e),this.bindModalEvents(),this.initContributionRequest(),setTimeout((function(){e.classList.add("active")}),100)}initContributionRequest(){this.contributionInstance=new e(this.$modal.contributionEl)}close(t){t.preventDefault();const e=this.$modal.el;e.classList.remove("active"),setTimeout((function(){document.querySelector("body").removeChild(e)}),200)}}document.addEventListener("DOMContentLoaded",(()=>{const t=document.getElementsByClassName("rev-gen-contribution");for(const s of t)s.dataset.type&&("button"!==s.dataset.type?new e(s):new o(s))}))})()})();1 (()=>{"use strict";(()=>{const t=t=>{const e=t+"=",o=decodeURIComponent(document.cookie).split(";");for(let t=0;t<o.length;t++){let n=o[t];for(;" "===n.charAt(0);)n=n.substring(1);if(0===n.indexOf(e))return n.substring(e.length,n.length)}return""},e=(t,e,o)=>{const n=new Date;n.setTime(n.getTime()+24*o*60*60*1e3);const s="expires="+n.toUTCString();document.cookie=t+"="+e+";"+s+";path=/"};class o{constructor(t){this.el=t,this.itemId=this.el.dataset.contributionId,this.closeTimeout=null,this.RESET_TIMEOUT=3e3,this.$o={form:t.querySelector(".rev-gen-contribution__form"),submitButton:t.querySelector("button[type=submit][data-mytab-button]"),amounts:t.querySelector(".rev-gen-contribution__amounts"),choose:t.querySelector(".rev-gen-contribution__choose"),customChoice:t.querySelector(".rev-gen-contribution__amount--custom"),response:t.querySelector(".rev-gen-contribution__response"),loading:t.querySelector(".rev-gen-contribution__loading"),custom:{el:t.querySelector(".rev-gen-contribution__custom"),input:t.querySelector(".rev-gen-contribution__custom input"),backButton:t.querySelector(".rev-gen-contribution-custom__back")},modal:{el:t.querySelector(".rev-gen-contribution-info-modal"),openButton:t.querySelector(".rev-gen-contribution__question-mark"),closeButton:t.querySelector(".rev-gen-contribution-info-modal__x-mark")}},this.bindEvents(),this.maybeContinueFlow()}bindEvents(){const o=this;new ResizeObserver((t=>{t.forEach((t=>{const e=t.target.dataset.breakpoints?JSON.parse(t.target.dataset.breakpoints):"";e&&Object.keys(e).forEach((o=>{const n=e[o],s="size-"+o;t.contentRect.width>=n?t.target.classList.add(s):t.target.classList.remove(s)}))}))})).observe(this.el),this.$o.customChoice.addEventListener("click",(t=>{t.preventDefault(),this.showCustomForm()})),this.$o.custom.backButton.addEventListener("click",(t=>{t.preventDefault(),this.hideCustomForm()})),this.$o.form.addEventListener("change",(()=>{this.customModeActive||(new FormData(this.$o.form).get("amount")?(this.el.classList.add("amount-selected"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.submitButton.removeAttribute("hidden")):(this.el.classList.remove("amount-selected"),this.$o.submitButton.classList.add("rev-gen-hidden"),this.$o.submitButton.addAttribute("hidden")))})),this.$o.form.addEventListener("submit",(n=>{n.preventDefault();const s=new FormData(this.$o.form);s.append("rg_key",t("rg_key"));const i=new XMLHttpRequest;i.open("POST",this.$o.form.getAttribute("action"),!0),i.send(s),i.onreadystatechange=function(){if(4===this.readyState){const t=JSON.parse(this.response);switch(this.status){case 200:const n=document.createElement("script");n.src=o.$o.form.dataset.tabWidgetUrl,o.$o.response.appendChild(n),o.$o.response.innerHTML=t.data.html,n.onload=()=>{o.$o.choose.classList.add("rev-gen-hidden");const t=o.el.querySelectorAll(".tab_widget__link")[1];o.setCloseTimeout(),t.addEventListener("click",(()=>{o.openInfoModal()})),o.hideSubmit()};break;case 402:o.$o.modal.openButton.classList.add("rev-gen-hidden"),o.$o.loading.classList.remove("rev-gen-hidden"),o.el.classList.add("rev-gen-contribution--payment"),o.$o.response.innerHTML=t.data.html,o.$o.choose.classList.add("rev-gen-hidden"),o.hideSubmit();break;case 401:e("rg_key",t.data.session_key),e("rg_contribution_data",JSON.stringify(t.data.handover)),window.location.href=t.data.auth_url}}}})),this.$o.modal.openButton.addEventListener("click",(()=>{o.openInfoModal()})),this.$o.modal.closeButton.addEventListener("click",(()=>{o.closeInfoModal()})),window.addEventListener("message",(t=>{t.data&&"OPEN_INFO_MODAL"===t.data&&o.openInfoModal()})),window.addEventListener("message",(t=>{t.data&&"PAYMENT_SUCCESSFUL"===t.data&&o.reset()})),this.el.addEventListener("rev-gen-iframe-load",(t=>{const e=t.detail||"";e&&(o.$o.loading.classList.add("rev-gen-hidden"),o.$o.modal.openButton.classList.remove("rev-gen-hidden"),e.style.height=e.contentWindow.document.body.scrollHeight+"px",o.el.classList.add("rev-gen-iframe-ready"))}))}hideSubmit(){this.$o.submitButton.classList.add("rev-gen-hidden")}showCustomForm(){this.customModeActive=!0,this.$o.amounts.classList.add("rev-gen-hidden"),this.$o.custom.el.classList.remove("rev-gen-hidden"),this.$o.custom.el.removeAttribute("hidden"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.custom.input.focus()}hideCustomForm(){this.customModeActive=!1,this.$o.form.reset(),this.$o.custom.el.classList.add("rev-gen-hidden"),this.$o.custom.el.setAttribute("hidden",""),this.$o.amounts.classList.remove("rev-gen-hidden"),this.$o.submitButton.classList.add("rev-gen-hidden")}openInfoModal(){clearTimeout(this.closeTimeout),this.$o.modal.el.classList.remove("rev-gen-hidden")}closeInfoModal(){this.$o.modal.el.classList.add("rev-gen-hidden")}reset(){this.el.classList.remove("amount-selected"),this.$o.response.innerHTML="",this.el.classList.remove("rev-gen-contribution--payment"),this.$o.form.reset(),this.$o.choose.classList.remove("rev-gen-hidden")}setCloseTimeout(){const t=this;this.closeTimeout=setTimeout((()=>{t.reset()}),t.RESET_TIMEOUT)}maybeContinueFlow(){if(!t("rg_contribution_data"))return;const o=JSON.parse(t("rg_contribution_data"));if(parseInt(this.itemId,10)!==parseInt(o.contribution.item_id,10))return;const n=this.$o.form.querySelector('[value="'+o.contribution.amount+'"]');n?n.checked=!0:(this.$o.custom.input.value=n,this.showCustomForm());const s=new MouseEvent("click");this.$o.submitButton.dispatchEvent(s),e("rg_contribution_data","")}}window.laterpayIframeLoaded=t=>{const e=t.dataset.contributionId;if(!e)return;const o=new CustomEvent("rev-gen-iframe-load",{detail:t});let n=document.querySelectorAll('.rev-gen-contribution[data-contribution-id="'+e+'"]');n=n[n.length-1],n.dispatchEvent(o)};class n{constructor(t){this.$button={trigger:t.querySelector("button"),modal:t.querySelector(".rev-gen-contribution-modal")},this.$modal={el:""},this.bindButtonEvents()}bindButtonEvents(){this.$button.trigger.addEventListener("click",this.open.bind(this))}bindModalEvents(){this.$modal.closeButton.addEventListener("click",this.close.bind(this))}open(t){t.preventDefault();const e=this.$button.modal.cloneNode(!0);this.$modal.el=e,this.$modal.contributionEl=e.querySelector(".rev-gen-contribution"),this.$modal.closeButton=e.querySelector(".rev-gen-contribution-modal__close"),document.querySelector("body").appendChild(e),this.bindModalEvents(),this.initContributionRequest(),setTimeout((function(){e.classList.add("active")}),100)}initContributionRequest(){this.contributionInstance=new o(this.$modal.contributionEl)}close(t){t.preventDefault();const e=this.$modal.el;e.classList.remove("active"),setTimeout((function(){document.querySelector("body").removeChild(e)}),200)}}document.addEventListener("DOMContentLoaded",(()=>{const t=document.getElementsByClassName("rev-gen-contribution");for(const e of t)e.dataset.type&&("button"!==e.dataset.type?new o(e):new n(e))}))})()})(); -
revenue-generator/tags/2.0.1/v2/assets/src/js/frontend/contribution.js
r2466307 r2468562 1 1 /* global FormData, XMLHttpRequest, ResizeObserver, MouseEvent, CustomEvent */ 2 2 3 import { getCookie } from '../helpers/index';3 import { setCookie, getCookie } from '../helpers/index'; 4 4 5 5 /** … … 134 134 // Get form data. 135 135 const data = new FormData( this.$o.form ); 136 data.append( 'rg_key', getCookie( 'rg_key' ) ); 136 137 137 138 // Create ajax object. … … 145 146 const res = JSON.parse( this.response ); 146 147 147 /* eslint-disable no-alert */148 148 switch ( this.status ) { 149 149 // Item added to the tab. … … 195 195 // User not authorized. 196 196 case 401: 197 setCookie( 'rg_key', res.data.session_key ); 198 setCookie( 199 'rg_contribution_data', 200 JSON.stringify( res.data.handover ) 201 ); 202 197 203 // Redirect to auth. 198 204 window.location.href = res.data.auth_url; 199 205 break; 200 206 } 201 /* eslint-enable no-alert */202 207 } 203 208 }; … … 326 331 */ 327 332 maybeContinueFlow() { 328 if ( ! getCookie( 'rg v2_data' ) ) {333 if ( ! getCookie( 'rg_contribution_data' ) ) { 329 334 return; 330 335 } 331 336 332 const clientCookie = JSON.parse( getCookie( 'rg v2_data' ) );337 const clientCookie = JSON.parse( getCookie( 'rg_contribution_data' ) ); 333 338 334 339 if ( … … 358 363 const clickEvent = new MouseEvent( 'click' ); 359 364 this.$o.submitButton.dispatchEvent( clickEvent ); 365 366 // Reset session cookie to empty value after making a contribution. 367 setCookie( 'rg_contribution_data', '' ); 360 368 } 361 369 } -
revenue-generator/tags/2.0.1/v2/assets/src/js/helpers/index.js
r2466307 r2468562 25 25 return ''; 26 26 }; 27 28 export const setCookie = ( cname, cvalue, expDays ) => { 29 const d = new Date(); 30 d.setTime( d.getTime() + expDays * 24 * 60 * 60 * 1000 ); 31 const expires = 'expires=' + d.toUTCString(); 32 document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/'; 33 }; -
revenue-generator/tags/2.0.1/v2/assets/src/scss/frontend/_component.scss
r2466307 r2468562 116 116 } 117 117 118 .tab_widget__link {118 a.tab_widget__link { 119 119 @extend .font; 120 120 font-weight: 400; … … 124 124 text-decoration: underline; 125 125 cursor: pointer; 126 &:hover, 127 &:visited { 128 color: $color-dark; 129 } 126 130 } 127 131 -
revenue-generator/tags/2.0.1/v2/assets/src/scss/frontend/contribution-dialog.scss
r2466307 r2468562 45 45 height: 18px; 46 46 border-radius: 50%; 47 font-family: $box-font; 47 48 font-weight: 700; 48 49 font-size: 12px; … … 81 82 &__title { 82 83 margin: 0; 84 font-family: $box-font; 83 85 font-weight: 500; 84 86 font-size: 18px; … … 94 96 align-items: center; 95 97 margin: 0; 98 font-family: $box-font; 96 99 font-weight: 500; 97 100 font-size: 14px; … … 113 116 } 114 117 &__description { 115 font-weight: 500;116 font-size: 14px;117 118 118 p { 119 119 margin-bottom: 1em; 120 font-family: $box-font; 121 font-weight: 500; 122 font-size: 14px; 120 123 &:last-child { 121 124 margin-bottom: 0; … … 164 167 &.amp-form-submit-success, 165 168 &.amp-form-submit-error { 169 max-height: 250px; 170 overflow: hidden; 166 171 margin: 0; 167 172 } 173 div[submit-success] { 174 position: relative; 175 z-index: 10; 176 } 168 177 button[type="submit"] { 178 cursor: pointer; 169 179 max-width: 100%; 170 180 flex: 0 1 100%; 171 181 width: 100%; 172 182 padding: 15px 0; 183 font-family: $box-font; 173 184 font-size: 15px; 174 185 border: 1px solid #000; … … 274 285 input[type="number"] { 275 286 min-width: 220px; 276 margin -right: 5px;287 margin: 0 5px 0 0; 277 288 padding: 13.5px 0 13px 15px; 278 289 border-radius: 5px; 279 290 background-color: rgba(160, 160, 160, 0.12); 280 margin-bottom: 10px;291 font-family: $box-font; 281 292 font-size: 14px; 282 293 outline: 0; … … 351 362 &__back { 352 363 position: relative; 353 bottom: 5px;364 bottom: 0; 354 365 float: left; 355 366 cursor: pointer; … … 640 651 &__amp-show-modal { 641 652 position: absolute; 642 bottom: 35px;643 left: 1 65px;653 bottom: 19px; 654 left: 137px; 644 655 z-index: 10; 645 656 width: 95px; -
revenue-generator/tags/2.0.1/v2/inc/classes/api/class-auth-provider.php
r2466307 r2468562 74 74 75 75 /** 76 * Returns a new random string to use as the state parameter in an 77 * authorization flow. 78 * 79 * Adds support for PHP5 by generating state with `openssl_random_pseudo_bytes` if 80 * `random_bytes` does not exist. 81 * 82 * @param int $length Length of the random string to be generated. 83 * @return string 84 */ 85 protected function getRandomState( $length = 32 ) { 86 if ( function_exists( 'random_bytes' ) ) { 87 return bin2hex( random_bytes( $length / 2 ) ); 88 } 89 90 if ( function_exists( 'openssl_random_pseudo_bytes' ) ) { 91 return bin2hex( openssl_random_pseudo_bytes( $length / 2 ) ); 92 } 93 } 94 95 /** 76 96 * Check response and throw exception if error is present. 77 97 * -
revenue-generator/tags/2.0.1/v2/inc/classes/api/class-auth.php
r2466307 r2468562 38 38 */ 39 39 const SERVER_KEY_OPTION_NAME = 'lp_rgv2_key'; 40 41 /**42 * Name of the cookie to store JWT.43 *44 * @const string45 */46 const TOKEN_COOKIE_NAME = 'rgv2_token';47 40 48 41 /** … … 151 144 152 145 /** 153 * Get tokens from client. 154 * 155 * @return boolean|JSON False on failure, JSON object on success. 156 */ 157 private function get_jwt_from_client() { 158 $jwt = ( isset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) ) ? sanitize_text_field( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) : ''; 159 160 if ( empty( $jwt ) ) { 161 return false; 162 } 163 164 $tokens = $this->decode_tokens( $jwt ); 146 * Get token from database if key is set. 147 * 148 * @return JWT 149 */ 150 public function get_token_from_db() { 151 $api = API::get_instance(); 152 153 // Return false if session key is not set. 154 if ( empty( $api->session_key ) ) { 155 return false; 156 } 157 158 // Get token by session key. 159 $tokens = get_transient( wp_hash( $api->session_key ) ); 160 $tokens = $this->decode_tokens( $tokens, $api->session_key ); 165 161 166 162 if ( is_wp_error( $tokens ) ) { … … 174 170 * Get access token. 175 171 * 176 * This looks for a token on clientfirst, returns false if it's not found so we can then172 * This looks for a token in database first, returns false if it's not found so we can then 177 173 * start the authorization code flow. 178 174 * … … 186 182 } 187 183 188 // Get tokens from the client.189 $tokens = $this->get_ jwt_from_client();184 // Get tokens from the database. 185 $tokens = $this->get_token_from_db(); 190 186 191 187 if ( ! $tokens ) { … … 216 212 } 217 213 214 if ( ! isset( $_GET['state'] ) ) { 215 return; 216 } 217 218 $state = sanitize_text_field( $_GET['state'] ); 219 220 $api = API::get_instance(); 221 $api->set_session( $state ); 222 218 223 $tokens = $this->get_tokens_from_provider( 219 224 'authorization_code', 220 sanitize_text_field( $_GET['code'] ) 221 ); 225 sanitize_text_field( $_GET['code'] ), 226 $state 227 ); 228 229 $client_data = $api->get_client_meta(); 230 231 // If this is AMP, pair token to AMP client ID instead. 232 if ( isset( $client_data['amp_id_key'] ) ) { 233 delete_transient( wp_hash( $state ) ); 234 235 $this->save_tokens( $tokens, $client_data['amp_id_key'] ); 236 } 222 237 223 238 $redirect_uri = site_url(); 224 $client_data = API::get_user_cookie(); 225 226 if ( isset( $client_data->redirect_uri ) && ! empty( $client_data->redirect_uri ) ) { 227 $redirect_uri = $client_data->redirect_uri; 228 } 239 240 if ( isset( $client_data['redirect_uri'] ) && ! empty( $client_data['redirect_uri'] ) ) { 241 $redirect_uri = $client_data['redirect_uri']; 242 } 243 244 $api->delete_client_meta(); 229 245 230 246 wp_safe_redirect( $redirect_uri ); … … 237 253 * @param string $grant_type Grant type to use when obtaining a token. 238 254 * @param string $key A key to use with the flow (auth code or refresh token). 255 * @param string $state OAuth state. 239 256 * 240 257 * @return AccessToken|boolean Token class instance. Boolean on failure. 241 258 */ 242 public function get_tokens_from_provider( $grant_type = 'refresh_token', $key = '' ) {259 public function get_tokens_from_provider( $grant_type = 'refresh_token', $key = '', $state = '' ) { 243 260 if ( empty( $key ) ) { 244 261 return false; … … 267 284 $tokens = $this->provider->getAccessToken( $grant_type, $params ); 268 285 269 $this->save_tokens( $tokens );286 $this->save_tokens( $tokens, $state ); 270 287 271 288 return $tokens; … … 281 298 * 282 299 * @param AccessToken $tokens AccessToken instance. 300 * @param string $state OAuth state. 283 301 * 284 302 * @return string Access token. 285 303 */ 286 public function save_tokens( AccessToken $tokens ) {304 public function save_tokens( AccessToken $tokens, $state ) { 287 305 $this->token = $tokens->getToken(); 288 $encoded_tokens = $this->encode_tokens( $tokens ); 289 290 if ( isset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) ) { 291 unset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ); 292 } 293 294 if ( ! headers_sent() ) { 295 setcookie( 296 self::TOKEN_COOKIE_NAME, 297 $encoded_tokens, 298 [ 299 'path' => '/', 300 'httponly' => true, 301 'secure' => is_ssl(), 302 'samesite' => true, 303 'expires' => time() + 720 * HOUR_IN_SECONDS, 304 ] 305 ); 306 } 306 $encoded_tokens = $this->encode_tokens( $tokens, $state ); 307 308 delete_transient( wp_hash( $state ) ); 309 set_transient( wp_hash( $state ), $encoded_tokens, 1 * MONTH_IN_SECONDS ); 307 310 308 311 return $this->token; … … 313 316 * 314 317 * @param AccessToken $tokens AccessToken instance. 315 * 316 * @return string JWT token. 317 */ 318 private function encode_tokens( AccessToken $tokens ) { 318 * @param string $key Key to encode tokens with. 319 * 320 * @return mixed JWT token on success, FALSE on failure. 321 */ 322 private function encode_tokens( AccessToken $tokens, $key = '' ) { 323 if ( empty( $key ) ) { 324 return false; 325 } 326 319 327 $payload = [ 320 328 'access' => $tokens->getToken(), … … 323 331 ]; 324 332 325 $jwt = JWT::encode( $payload, $ this->key );333 $jwt = JWT::encode( $payload, $key ); 326 334 327 335 return $jwt; … … 332 340 * 333 341 * @param string $jwt String to decode. 342 * @param string $key Key to decode token with. 334 343 * 335 344 * @return JSON|WP_Error JSON object on success. WP_Error object on failure. 336 345 */ 337 private function decode_tokens( $jwt = '' ) {346 private function decode_tokens( $jwt = '', $key = '' ) { 338 347 if ( empty( $jwt ) ) { 339 348 return new \WP_Error( 'empty_jwt', 'JWT parameter cannot be empty to decode it.' ); 340 349 } 341 350 351 if ( empty( $key ) ) { 352 return new \WP_Error( 'empty_key', 'Key needs to be provided to decode JWT token.' ); 353 } 354 342 355 try { 343 $decoded = JWT::decode( $jwt, $ this->key, [ 'HS256' ] );356 $decoded = JWT::decode( $jwt, $key, [ 'HS256' ] ); 344 357 345 358 return $decoded; … … 551 564 */ 552 565 public function get_auth_code_url() { 553 return $this->provider->getAuthorizationUrl(); 566 $url = $this->provider->getAuthorizationUrl(); 567 568 return $url; 569 } 570 571 /** 572 * Get state from the authorization code flow URL. 573 * 574 * @param string $url URL to get the state from. 575 * 576 * @return string 577 */ 578 public function get_state_from_auth_url( $url = '' ) { 579 if ( empty( $url ) ) { 580 return ''; 581 } 582 583 $parsed_url = parse_url( $url ); 584 parse_str( $parsed_url['query'], $query_params ); 585 586 if ( ! isset( $query_params['state'] ) ) { 587 return ''; 588 } 589 590 return sanitize_text_field( $query_params['state'] ); 554 591 } 555 592 -
revenue-generator/tags/2.0.1/v2/inc/classes/class-api.php
r2466307 r2468562 34 34 35 35 /** 36 * Name of the cookie to store temporary data on client.37 *38 * @const string39 */40 const CLIENT_COOKIE_NAME = 'rgv2_data';41 42 /**43 * Name of the cookie with full tab ID info.44 *45 * @const string46 */47 const FULL_TAB_COOKIE_NAME = 'rgv2_full_tab_id';48 49 /**50 36 * Auth instance. 51 37 * … … 53 39 */ 54 40 public static $auth = null; 41 42 /** 43 * Session key to manage meta. 44 * 45 * @var string 46 */ 47 public $session_key = ''; 48 49 /** 50 * Hashed session key. 51 * 52 * @var string 53 */ 54 private $hashed_key = ''; 55 55 56 56 /** … … 239 239 240 240 /** 241 * Get value of user cookie used when user needs to leave the site 242 * to go through the auth process. Used to store redirect URI and amount 243 * to contribute here. 244 * 245 * @return mixed Empty array on failure. JSON object on success. 246 */ 247 public static function get_user_cookie() { 248 $data = []; 249 250 if ( ! isset( $_COOKIE[ static::CLIENT_COOKIE_NAME ] ) ) { 251 return $data; 252 } 253 254 $data = $_COOKIE[ static::CLIENT_COOKIE_NAME ]; // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 255 $data = json_decode( stripslashes( $data ) ); 256 257 return $data; 258 } 259 260 /** 261 * Return user cookie parameters. 262 * 263 * @return array 264 */ 265 private static function get_user_cookie_params() { 266 return [ 267 'path' => '/', 268 'secure' => is_ssl(), 269 ]; 270 } 271 272 /** 273 * Sets data to user cookie. Unsets the cookie first if it was previously set. 274 * 275 * @param array $data Data to be set. 241 * Set session key. 242 * 243 * @param string $session_key Session key to set. 244 */ 245 public function set_session( $session_key = '' ) { 246 $this->session_key = $session_key; 247 $this->hashed_key = wp_hash( $this->session_key ); 248 } 249 250 /** 251 * Set client meta in database. 252 * 253 * @param string $data Data to be stored. 254 * @param string $type Type of meta. Default: `meta`. 255 * @param int $expiration The expiration after which data will be deleted. 276 256 * 277 257 * @return void 278 258 */ 279 public static function set_user_cookie( $data = [] ) { 280 static::unset_user_cookie(); 281 282 setcookie( 283 static::CLIENT_COOKIE_NAME, 284 json_encode( $data ), 285 static::get_user_cookie_params() 286 ); 287 } 288 289 /** 290 * Unsets user cookie. 291 */ 292 public static function unset_user_cookie() { 293 setcookie( 294 static::CLIENT_COOKIE_NAME, 295 '', 296 static::get_user_cookie_params() 297 ); 298 } 299 300 /** 301 * Sets cookie with full tab ID. 302 * 303 * @param string $value Tab ID. 259 public function set_client_meta( $data = '', $type = 'meta', $expiration = 5 * MINUTE_IN_SECONDS ) { 260 $transient_key = "{$this->hashed_key}_{$type}"; 261 262 set_transient( $transient_key, $data, $expiration ); 263 } 264 265 /** 266 * Get client meta from the database. 267 * 268 * @param string $type Type of meta. Default: `meta`. 269 * 270 * @return mixed 271 */ 272 public function get_client_meta( $type = 'meta' ) { 273 $transient_key = "{$this->hashed_key}_{$type}"; 274 275 return get_transient( $transient_key ); 276 } 277 278 /** 279 * Delete client meta from the database. 280 * 281 * @param string $type Type of meta to be deleted. Default: `meta`. 304 282 * 305 283 * @return void 306 284 */ 307 public static function set_full_tab_cookie( $value = '' ) { 308 $params = static::get_user_cookie_params(); 309 $params['httponly'] = true; 310 311 setcookie( 312 static::FULL_TAB_COOKIE_NAME, 313 $value, 314 $params 315 ); 316 } 317 318 /** 319 * Get value of full tab cookie. 320 * 321 * @return string 322 */ 323 public static function get_full_tab_cookie() { 324 $value = ''; 325 326 if ( ! isset( $_COOKIE[ static::FULL_TAB_COOKIE_NAME ] ) ) { 327 return $value; 328 } 329 330 $value = sanitize_text_field( $_COOKIE[ static::FULL_TAB_COOKIE_NAME ] ); 331 332 return $value; 333 } 334 335 /** 336 * Unsets cookie with full tab ID. 337 */ 338 public static function unset_full_tab_cookie() { 339 static::set_full_tab_cookie( '' ); 285 public function delete_client_meta( $type = 'meta' ) { 286 $transient_key = "{$this->hashed_key}_{$type}"; 287 288 delete_transient( $transient_key ); 340 289 } 341 290 -
revenue-generator/tags/2.0.1/v2/inc/classes/class-frontend-post.php
r2466307 r2468562 36 36 * @const string 37 37 */ 38 const TAB_WIDGET_SCRIPT_URL = 'https://assets. sbx.laterpay.net/pcpro-jsx-components-frontend/main.js';38 const TAB_WIDGET_SCRIPT_URL = 'https://assets.laterpay.net/pcpro-jsx-components-frontend/main.js'; 39 39 40 40 /** … … 72 72 */ 73 73 const MYTAB_SBX_URL = 'https://mytab.sbx.laterpay.net'; 74 75 /**76 * Tab data cookie name for AMP context.77 *78 * @const string79 */80 const AMP_TAB_DATA_COOKIE_NAME = 'amp_lp_tab_data';81 74 82 75 /** … … 131 124 add_action( 'parse_request', [ $this, 'handle_payment_iframe_redirect' ] ); 132 125 add_action( 'parse_request', [ $this, 'handle_purchase_iframe_display' ] ); 126 add_action( 'parse_request', [ $this, 'handle_json_amp_url' ] ); 127 add_action( 'wp_print_footer_scripts', [ $this, 'print_amp_script' ] ); 128 add_action( 'wp_head', [ $this, 'add_amp_script_hash' ] ); 133 129 } 134 130 … … 187 183 $is_amp = ( isset( $_REQUEST['is_amp'] ) && 1 === (int) $_REQUEST['is_amp'] ); 188 184 $layout_type = ( isset( $_REQUEST['layout_type'] ) ) ? sanitize_text_field( $_REQUEST['layout_type'] ) : ''; 185 $key = ( isset( $_REQUEST['rg_key'] ) ) ? sanitize_text_field( $_REQUEST['rg_key'] ) : ''; 189 186 $redirect_uri = ( isset( $_REQUEST['redirect_uri'] ) ) ? esc_url( $_REQUEST['redirect_uri'] ) : ''; // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 190 187 … … 210 207 $api = API::get_instance(); 211 208 209 // If session key is present, set it to API instance. 210 if ( ! empty( $key ) ) { 211 $api->set_session( $key ); 212 } 213 212 214 /** 213 215 * If user is not authorized, return auth flow URL for them in the response … … 215 217 */ 216 218 if ( ! $api->is_user_authorized() ) { 217 /** 218 * Set data to store in the cookie so we can redirect user and 219 * continue their flow. 220 */ 219 // Reset session if in AMP context as we want to pair data to AMP client ID instead. 220 if ( $is_amp ) { 221 $api->set_session( '' ); 222 223 $amp_id_key = ''; 224 225 if ( $is_amp ) { 226 $amp_id_key = $key; 227 } 228 } 229 230 $auth_url = $api::$auth->get_auth_code_url(); 231 $state = $api::$auth->get_state_from_auth_url( $auth_url ); 232 233 $api->set_session( $state ); 234 235 $redirect_uri = $redirect_uri; 236 237 // Set specific AMP redirect URI to redirect back to AMP context. 238 if ( $is_amp ) { 239 $redirect_uri = add_query_arg( 240 [ 241 'amp' => 1, 242 'session' => $state, 243 ], 244 $redirect_uri 245 ); 246 } 247 221 248 $client_data = [ 222 249 'redirect_uri' => $redirect_uri, 223 'contribution' => [224 'amount' => number_format( $amount, 2 ),225 'item_id' => $item_id,226 ],227 250 ]; 228 251 229 // Store data to a cookie. 230 API::set_user_cookie( $client_data ); 252 // Add reference to AMP client ID to client meta for future linking. 253 if ( $is_amp ) { 254 $client_data['amp_id_key'] = $amp_id_key; 255 } 256 257 $api->set_client_meta( $client_data ); 258 259 if ( $is_amp ) { 260 header( 'AMP-Redirect-To: ' . $auth_url ); 261 header( 'Access-Control-Expose-Headers: AMP-Redirect-To' ); 262 } 231 263 232 264 // Send JSON response with auth code flow URL and 401 code. … … 234 266 [ 235 267 'data' => [ 236 'auth_url' => $api::$auth->get_auth_code_url(), 268 'auth_url' => $auth_url, 269 'session_key' => $api->session_key, 270 'handover' => [ 271 'contribution' => [ 272 'amount' => number_format( $amount, 2 ), 273 'item_id' => $item_id, 274 ], 275 ], 237 276 ], 238 277 ], … … 277 316 278 317 if ( $is_amp ) { 279 setcookie( 280 static::AMP_TAB_DATA_COOKIE_NAME, 281 json_encode( $tab_data ), 282 [ 283 'path' => '/', 284 'secure' => is_ssl(), 285 ] 286 ); 318 $api->set_client_meta( $tab_data, 'amp_payment' ); 287 319 } 288 320 … … 310 342 ); 311 343 312 API::unset_user_cookie();313 314 344 wp_send_json( 315 345 $response, … … 325 355 */ 326 356 case 402: 327 $credentials = $api::$auth->get_credentials();328 329 // Set cookie with full tab ID to use when redirecting.330 $api::set_full_tab_cookie( $response['data']['tab']['id'] );331 332 357 $iframe_url = static::get_payment_iframe_url(); 333 334 358 $iframe_url = add_query_arg( 335 359 [ 336 'layout_type' => $layout_type, 360 'key' => $key, 361 'v' => time(), 337 362 ], 338 363 $iframe_url 339 364 ); 365 366 $meta = [ 367 'tab_id' => $tab_data['id'], 368 'layout_type' => $layout_type, 369 ]; 370 371 // Store full tab ID and layout type in payment meta. 372 $api->set_client_meta( $meta, 'payment' ); 340 373 341 374 $response['data']['payment_required'] = true; … … 347 380 ); 348 381 349 API::unset_user_cookie();350 351 382 wp_send_json( 352 383 $response, … … 413 444 414 445 /** 415 * Get iframe URL for purchase component display (AMP).416 *417 * @return string418 */419 public static function get_purchase_iframe_url() {420 $url = site_url();421 $url = add_query_arg( 'laterpay', 'purchase', $url );422 423 return $url;424 }425 426 /**427 446 * Intercept request. When `?laterpay` is present and set to `payment`, 428 447 * make a call to payment component and render it before WP theme initializes. … … 439 458 } 440 459 441 $layout_type = ''; 442 443 if ( isset( $_GET['layout_type'] ) ) { 444 $layout_type = sanitize_text_field( $_GET['layout_type'] ); 445 } 446 447 $api = API::get_instance(); 448 $tab_id = $api::get_full_tab_cookie(); 460 if ( ! isset( $_GET['key'] ) ) { 461 return; 462 } 463 464 $key = sanitize_text_field( $_GET['key'] ); 465 466 if ( empty( $key ) ) { 467 return; 468 } 469 470 $api = API::get_instance(); 471 $api->set_session( $key ); 472 473 // Get full tab ID and layout type previously set to client meta. 474 $payment_data = $api->get_client_meta( 'payment' ); 449 475 450 476 $req = wp_remote_get( … … 453 479 'headers' => [ 454 480 'x-lp-access-token' => $api::$auth->get_access_token(), 455 'x-lp-tab-id' => $ tab_id,456 'x-lp-amp' => ( function_exists( 'is_amp' ) && is_amp() ),457 'x-lp-theme' => $ layout_type,481 'x-lp-tab-id' => $payment_data['tab_id'], 482 'x-lp-amp' => ( isset( $_GET['amp'] ) ), 483 'x-lp-theme' => $payment_data['layout_type'], 458 484 ], 459 485 ] … … 462 488 $res = wp_remote_retrieve_body( $req ); 463 489 490 header( 'Access-Control-Allow-Origin: ' . site_url() ); 464 491 header( 'Content-Type: text/html; charset=UTF-8' ); 465 492 466 493 echo $res; // phpcs:ignore -- WordPress.Security.EscapeOutput.OutputNotEscaped 494 495 // Clean up. Delete client meta and payment meta. 496 $api->delete_client_meta(); 497 $api->delete_client_meta( 'payment' ); 467 498 468 499 exit(); … … 482 513 return; 483 514 } 515 516 if ( ! isset( $_GET['key'] ) ) { 517 return; 518 } 519 520 $key = sanitize_text_field( $_GET['key'] ); 521 522 $api = API::get_instance(); 523 $api->set_session( $key ); 524 525 $amp_meta = $api->get_client_meta( 'amp_payment' ); 484 526 485 527 $api = API::get_instance(); … … 491 533 ]; 492 534 493 if ( isset( $_COOKIE[ static::AMP_TAB_DATA_COOKIE_NAME ] ) ) { 494 $tab_data = wp_parse_args( 495 json_decode( 496 stripslashes( $_COOKIE[ static::AMP_TAB_DATA_COOKIE_NAME ] ) // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 497 ), 498 $tab_data 499 ); 500 } 535 $tab_data = wp_parse_args( $amp_meta, $tab_data ); 501 536 502 537 // Data to use in the template. … … 515 550 } 516 551 552 /** 553 * Outputs simple URL where we'll listen to and intercept the request 554 * to render a JSON. 555 * 556 * @param string $type Type of the JSON to echo. 557 * 558 * @return string 559 */ 560 public static function get_json_amp_url( $type = '' ) { 561 if ( empty( $type ) ) { 562 return; 563 } 564 565 $url = add_query_arg( 566 [ 567 'laterpay' => 'json', 568 'type' => $type, 569 ], 570 site_url() 571 ); 572 573 return $url; 574 } 575 576 /** 577 * Intercept the request and output JSON with the URL to either purchase 578 * or payment component for AMP purposes. 579 * 580 * AMP implementation uses `<amp-list>` to grab values of this JSON and 581 * then dynamically renders `<iframe>` with `src` coming from this JSON. 582 * This allows us to render iframe with the URL queries we need and 583 * overcome the limitation of `<amp-iframe>` alone which does not allow 584 * for dynamic attributes by default. 585 * 586 * @return string 587 */ 588 public function handle_json_amp_url() { 589 if ( ! isset( $_GET['laterpay'] ) ) { 590 return; 591 } 592 593 if ( 'json' !== sanitize_text_field( $_GET['laterpay'] ) ) { 594 return; 595 } 596 597 if ( ! isset( $_GET['type'] ) ) { 598 return; 599 } 600 601 if ( ! isset( $_GET['key'] ) ) { 602 return; 603 } 604 605 $type = sanitize_text_field( $_GET['type'] ); 606 $key = sanitize_text_field( $_GET['key'] ); 607 608 header( 'Content-type: application/json' ); 609 610 $url = self::get_payment_iframe_url(); 611 612 $url = add_query_arg( 613 [ 614 'key' => $key, 615 'amp' => 1, 616 ], 617 $url 618 ); 619 620 $json = json_encode( 621 [ 622 'items' => [ 623 [ 624 'url' => $url, 625 ], 626 ], 627 ] 628 ); 629 630 echo $json; // phpcs:ignore -- WordPress.Security.EscapeOutput.OutputNotEscaped -- output is formed in this method so no need to further escape 631 632 exit(); 633 } 634 635 /** 636 * Print AMP purchase component script if in AMP context. 637 * 638 * @hooked action `wp_print_footer_scripts` 639 */ 640 public function print_amp_script() { 641 if ( ! function_exists( 'is_amp_endpoint' ) || ! is_amp_endpoint() ) { 642 return; 643 } 644 645 include REVENUE_GENERATOR_PLUGIN_DIR . '/v2/templates/frontend/contribution/amp-purchase-component.php'; 646 } 647 648 /** 649 * Print AMP purchase component script hash to wp_head if 650 * in AMP context. 651 * 652 * @hooked action `wp_head` 653 */ 654 public function add_amp_script_hash() { 655 if ( ! function_exists( 'is_amp_endpoint' ) || ! is_amp_endpoint() ) { 656 return; 657 } 658 ?> 659 <meta name="amp-script-src" content="sha384-Xcsn0uFdGgT5Rk2GgmeML-rKQU6kfiRtPfrouuTo0sjizpodOzkcwzV8uBn2zyo9"> 660 <?php 661 } 662 517 663 } -
revenue-generator/tags/2.0.1/v2/templates/frontend/contribution/partial-amounts.php
r2466307 r2468562 13 13 global $wp; 14 14 ?> 15 16 <?php 17 /** 18 * The following bit is added so that AMP compiled CSS include 19 * the purchase component styles which is not yet available 20 * in DOM at the time of render. 21 */ 22 ?> 23 <?php if ( $is_amp ) : ?> 24 <div class="tab_widget__container tab_widget__arc-container tab_widget__arc--background tab_widget__arc--filled tab_widget__donated-amount-text tab_widget__thank-you-message tab_widget__links-container tab_widget__link tab_widget__links-separator tab_widget__container-hidden tab_widget__container-visible tab_widget__regular-text tab_widget tab_widget__arc-animation lp__root lp__tab-widget-data tab__widget__info-button__container tab__widget__info-button tab__widget__info-button-question-mark tab__widget__close-button-x-mark tab_widget__container__info-screen infoContainer title steps step stepText stepNumber description tab__widget__icon" style="display: none;"></div> 25 <?php endif; ?> 26 15 27 <div class="rev-gen-contribution__donate" id="<?php echo esc_attr( $html_id ); ?>_donate"> 16 28 <form class="rev-gen-contribution__form" action="<?php echo esc_url( admin_url() ); ?>admin-ajax.php" method="POST" id="<?php echo esc_attr( $html_id ); ?>_donate-form" action-xhr="<?php echo esc_url( admin_url() ); ?>admin-ajax.php" data-tab-widget-url="<?php echo esc_url( Frontend_Post::get_tab_widget_script_url() ); ?>" on="submit:AMP.setState({ submitted: 1, submitting: 1 })"> … … 18 30 <div submit-success> 19 31 <span on="tap:<?php echo esc_attr( $html_id ); ?>_info-modal.show" class="rev-gen-contribution__amp-show-modal"></span> 20 <iframe src="<?php echo esc_url( Frontend_Post::get_purchase_iframe_url() ); ?>" height="105"></iframe> 32 <template type="amp-mustache"> 33 <amp-script layout="fixed" height="105" width="330" script="revenue-generator-amp-purchase-component"> 34 <div class="lp__root"> 35 <div class="lp__tab-widget-data" 36 data-tab-amount="{{ data.tab.total }}" 37 data-tab-currency="USD" 38 data-tab-limit="{{ data.tab.limit }}" 39 data-view-tab-url="https://mytab.laterpay.net"></div> 40 </div> 41 </amp-script> 42 </template> 21 43 </div> 22 44 <div submit-error> 23 45 <span on="tap:<?php echo esc_attr( $html_id ); ?>_info-modal.show" class="rev-gen-contribution__amp-show-modal--purchase"></span> 24 <iframe src="<?php echo esc_url( Frontend_Post::get_payment_iframe_url() ); ?>" height="250"></iframe> 46 <amp-list width="auto" height="250" src="<?php echo esc_url( Frontend_Post::get_json_amp_url( 'payment' ) ); ?>&key=CLIENT_ID(uid)" max-items="1"> 47 <template type="amp-mustache"> 48 <iframe src="{{url}}" sandbox="allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-scripts allow-top-navigation-by-user-activation" width="100%" height="250" allowpaymentrequest></iframe> 49 </template> 50 </amp-list> 25 51 </div> 26 52 <?php endif; ?> … … 31 57 <input type="hidden" name="action" value="<?php echo esc_attr( Frontend_Post::CONTRIBUTION_AJAX_ACTION ); ?>"> 32 58 <?php if ( $is_amp ) : ?> 59 <input type="hidden" name="rg_key" value="CLIENT_ID(uid)" data-amp-replace="CLIENT_ID"> 33 60 <input type="hidden" name="is_amp" value="1"> 34 61 <?php endif; ?> -
revenue-generator/tags/2.0.1/vendor/autoload.php
r2466307 r2468562 5 5 require_once __DIR__ . '/composer/autoload_real.php'; 6 6 7 return ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b::getLoader();7 return ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045::getLoader(); -
revenue-generator/tags/2.0.1/vendor/composer/InstalledVersions.php
r2466307 r2468562 25 25 'root' => 26 26 array ( 27 'pretty_version' => '2.0. 0',28 'version' => '2.0. 0.0',27 'pretty_version' => '2.0.1', 28 'version' => '2.0.1.0', 29 29 'aliases' => 30 30 array ( … … 73 73 'laterpay/revenue-generator' => 74 74 array ( 75 'pretty_version' => '2.0. 0',76 'version' => '2.0. 0.0',75 'pretty_version' => '2.0.1', 76 'version' => '2.0.1.0', 77 77 'aliases' => 78 78 array ( -
revenue-generator/tags/2.0.1/vendor/composer/autoload_real.php
r2466307 r2468562 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b5 class ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 29 spl_autoload_unregister(array('ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045', 'loadClassLoader')); 30 30 31 31 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); … … 33 33 require __DIR__ . '/autoload_static.php'; 34 34 35 call_user_func(\Composer\Autoload\ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::getInitializer($loader));35 call_user_func(\Composer\Autoload\ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::getInitializer($loader)); 36 36 } else { 37 37 $map = require __DIR__ . '/autoload_namespaces.php'; … … 54 54 55 55 if ($useStaticLoader) { 56 $includeFiles = Composer\Autoload\ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$files;56 $includeFiles = Composer\Autoload\ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$files; 57 57 } else { 58 58 $includeFiles = require __DIR__ . '/autoload_files.php'; 59 59 } 60 60 foreach ($includeFiles as $fileIdentifier => $file) { 61 composerRequire 1f8be73ed8b3d6b4c601375036a77c9b($fileIdentifier, $file);61 composerRequire0180107ac78f1fe5f7e96ac594582045($fileIdentifier, $file); 62 62 } 63 63 … … 66 66 } 67 67 68 function composerRequire 1f8be73ed8b3d6b4c601375036a77c9b($fileIdentifier, $file)68 function composerRequire0180107ac78f1fe5f7e96ac594582045($fileIdentifier, $file) 69 69 { 70 70 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { -
revenue-generator/tags/2.0.1/vendor/composer/autoload_static.php
r2466307 r2468562 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b7 class ComposerStaticInit0180107ac78f1fe5f7e96ac594582045 8 8 { 9 9 public static $files = array ( … … 198 198 { 199 199 return \Closure::bind(function () use ($loader) { 200 $loader->prefixLengthsPsr4 = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$prefixLengthsPsr4;201 $loader->prefixDirsPsr4 = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$prefixDirsPsr4;202 $loader->classMap = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$classMap;200 $loader->prefixLengthsPsr4 = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$prefixLengthsPsr4; 201 $loader->prefixDirsPsr4 = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$prefixDirsPsr4; 202 $loader->classMap = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$classMap; 203 203 204 204 }, null, ClassLoader::class); -
revenue-generator/tags/2.0.1/vendor/composer/installed.php
r2466307 r2468562 2 2 'root' => 3 3 array ( 4 'pretty_version' => '2.0. 0',5 'version' => '2.0. 0.0',4 'pretty_version' => '2.0.1', 5 'version' => '2.0.1.0', 6 6 'aliases' => 7 7 array ( … … 50 50 'laterpay/revenue-generator' => 51 51 array ( 52 'pretty_version' => '2.0. 0',53 'version' => '2.0. 0.0',52 'pretty_version' => '2.0.1', 53 'version' => '2.0.1.0', 54 54 'aliases' => 55 55 array ( -
revenue-generator/trunk/languages/revenue-generator.po
r2466307 r2468562 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Revenue Generator 2.0. 0\n"5 "Project-Id-Version: Revenue Generator 2.0.1\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/revenue-generator\n" 7 7 "Last-Translator: Kimberly Moore <[email protected]>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2021-02-0 1T09:02:16+00:00\n"12 "POT-Creation-Date: 2021-02-04T08:24:31+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.4.0\n" … … 403 403 404 404 #: v1/inc/classes/class-frontend-post.php:780 405 #: v2/inc/classes/class-frontend-post.php:19 4405 #: v2/inc/classes/class-frontend-post.php:191 406 406 msgid "Contribution amount cannot be empty." 407 407 msgstr "" … … 1357 1357 1358 1358 #: v1/templates/frontend/contribution/partial-custom.php:35 1359 #: v2/templates/frontend/contribution/partial-amounts.php: 711359 #: v2/templates/frontend/contribution/partial-amounts.php:98 1360 1360 msgid "Enter custom amount" 1361 1361 msgstr "" … … 1366 1366 1367 1367 #: v1/templates/frontend/contribution/partial-donate.php:37 1368 #: v2/templates/frontend/contribution/partial-amounts.php: 621368 #: v2/templates/frontend/contribution/partial-amounts.php:89 1369 1369 msgid "Custom" 1370 1370 msgstr "" 1371 1371 1372 #: v2/inc/classes/class-frontend-post.php: 2011372 #: v2/inc/classes/class-frontend-post.php:198 1373 1373 msgid "Contribution details cannot be empty." 1374 1374 msgstr "" … … 1431 1431 msgstr "" 1432 1432 1433 #: v2/templates/frontend/contribution/partial-amounts.php: 721433 #: v2/templates/frontend/contribution/partial-amounts.php:99 1434 1434 msgid "Send" 1435 1435 msgstr "" 1436 1436 1437 #: v2/templates/frontend/contribution/partial-amounts.php: 761437 #: v2/templates/frontend/contribution/partial-amounts.php:103 1438 1438 msgid "Add to MyTab" 1439 1439 msgstr "" -
revenue-generator/trunk/readme.txt
r2466307 r2468562 7 7 Tested up to: 5.6 8 8 Requires PHP: 5.6 9 Stable tag: 2.0. 09 Stable tag: 2.0.1 10 10 Author URI: https://laterpay.net 11 11 Plugin URI: https://github.com/laterpay/revenue-generator/ … … 82 82 == Changelog == 83 83 84 = 2.0.1 ( 4 February 2021 ) = 85 * Fixed issue with contributions on page cache enabled hosts. 86 84 87 = 2.0.0 ( 1 February 2021 ) = 85 88 * New for contributions-only merchants: on-page purchase and payment experience powered by all new Laterpay platform. … … 126 129 == Upgrade notice == 127 130 131 = 2.0.1 = 132 Fixed issue with contributions on page cache enabled hosts. 133 128 134 = 2.0.0 = 129 135 New on-page purchase and payment experience for contributions-only merchants. Added support for custom post types to paywalls. -
revenue-generator/trunk/revenue-generator.php
r2466307 r2468562 4 4 * Description: Monetize your blog and content with Laterpay's Revenue Generator. 5 5 * Plugin URI: https://github.com/laterpay/revenue-generator 6 * Version: 2.0. 06 * Version: 2.0.1 7 7 * Author: Laterpay 8 8 * Text Domain: revenue-generator … … 15 15 defined( 'ABSPATH' ) || exit; 16 16 17 define( 'REVENUE_GENERATOR_VERSION', '2.0. 0' );17 define( 'REVENUE_GENERATOR_VERSION', '2.0.1' ); 18 18 19 19 if ( ! defined( 'REVENUE_GENERATOR_PLUGIN_FILE' ) ) { -
revenue-generator/trunk/v2/assets/build/css/frontend.css
r2466307 r2468562 1 .amount-text,.rev-gen-contribution__amount{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;font-weight:600;line-height:1.21;text-align:center;color:#333}.rev-gen-contribution{position:relative;width:100%;margin:20px auto;height:auto;transition:height 0.2s ease-in}.rev-gen-contribution__inner{position:relative;height:100%;padding:18px 25px;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:250px}.rev-gen-contribution__question-mark,.rev-gen-contribution-info-modal__x-mark{position:absolute;top:10px;right:10px;z-index:20;cursor:pointer;width:18px;height:18px;border-radius:50%;font- weight:700;font-size:12px;background-color:#1d1d1d;color:#fff;text-align:center}.rev-gen-contribution__question-mark span,.rev-gen-contribution-info-modal__x-mark span{position:relative;left:1px}.rev-gen-contribution-modal .rev-gen-contribution__question-mark,.rev-gen-contribution-modal .rev-gen-contribution-info-modal__x-mark{top:13px;right:35px}.rev-gen-contribution-info-modal{position:absolute;top:0;left:0;z-index:50;padding:20px;border-radius:5px;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution-info-modal__x-mark span{position:relative;top:-1px}.rev-gen-contribution-info-modal__title{margin:0;font-weight:500;font-size:18px}.rev-gen-contribution-info-modal__steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.rev-gen-contribution-info-modal__step{display:flex;align-items:center;margin:0;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__step-text{margin-left:6px;margin-right:10px}.rev-gen-contribution-info-modal__step-number{display:flex;align-items:center;justify-content:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.rev-gen-contribution-info-modal__description{font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__description p{margin-bottom:1em}.rev-gen-contribution-info-modal__description p:last-child{margin-bottom:0}.rev-gen-contribution h2.rev-gen-contribution__title{margin:0;max-width:100%;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:bold;line-height:1.33;font-size:21px;text-align:center;color:#1d1d1d}.rev-gen-contribution h2.rev-gen-contribution__title::before,.rev-gen-contribution h2.rev-gen-contribution__title::after{display:none !important}.rev-gen-contribution__description{max-width:100%;font-size:14px;text-align:center}.rev-gen-contribution__amounts{display:flex;flex-flow:row nowrap;justify-content:space-between;margin-bottom:20px}.rev-gen-contribution--bar .rev-gen-contribution__amounts{justify-content:center}.rev-gen-contribution__form{margin:20px 0}.rev-gen-contribution__form.amp-form-submit-success,.rev-gen-contribution__form.amp-form-submit-error{margin:0}.rev-gen-contribution__form button[type="submit"]{max-width:100%;flex:0 1 100%;width:100%;padding:15px 0;font-size:15px;border:1px solid #000;border-radius:4px;font-weight:500;background:#1d1d1d !important;color:#fff !important;text-decoration:none;text-transform:none;text-shadow:none}.rev-gen-contribution__form button[type="submit"].show{display:block}.rev-gen-contribution .rev-gen-hidden{display:none}.rev-gen-contribution__amount{min-width:75px;border:solid 2px #1d1d1d;border-radius:5px;margin:0 2px;display:flex;align-items:center;text-align:center;justify-content:center;overflow:hidden;cursor:pointer;word-break:normal;color:#1d1d1d;background-color:#fff}.rev-gen-contribution__amount input{position:absolute;opacity:0;width:0;height:0}.rev-gen-contribution__amount--custom{outline:0;text-transform:none;text-decoration:none}.rev-gen-contribution__amount--custom:hover,.rev-gen-contribution__amount--custom:active,.rev-gen-contribution__amount--custom:focus{background:#1d1d1d !important;color:#fff !important;text-decoration:none}.rev-gen-contribution__amount .rev-gen-contribution-control__label{display:block;width:100%;height:100%;border:0;padding:15px;font-size:14px;background:#fff !important;color:#1d1d1d !important;box-shadow:none !important;transition:background-color 0.05s ease-in !important;text-decoration:none !important;text-transform:none !important;letter-spacing:0 !important}.rev-gen-contribution__amount .rev-gen-contribution-control__label:hover{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount input:checked+.rev-gen-contribution-control__label{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount-wrapper{position:relative;display:flex;justify-content:center}.rev-gen-contribution__tip{margin:0 0 5px;line-height:1;font-size:13px;text-align:center}.rev-gen-contribution__tip.rev-gen-hidden{visibility:hidden}.rev-gen-contribution__custom input[type="number"]{min-width:220px;margin-right:5px;padding:13.5px 0 13px 15px;border-radius:5px;background-color:rgba(160,160,160,0.12);margin-bottom:10px;font-size:14px;outline:0;border:0}.rev-gen-contribution__custom.rev-gen-hidden:not[hidden]{display:none}.rev-gen-contribution__tab-status{height:100%;font-size:14px;text-align:center;transition:min-height 0.2s ease-in}.rev-gen-contribution__tab-status iframe{width:100%;height:0;margin:0 !important;padding:0 !important;border:0 !important}.rev-gen-contribution__response{position:relative;z-index:2;width:100%;background-color:#fff}.rev-gen-contribution__loading{position:absolute;z-index:1;top:50%;margin-top:-32px;left:50%;margin-left:-38px}.rev-gen-contribution-custom{max-width:335px;margin:10px auto;display:flex;flex-flow:row nowrap;align-items:center}.rev-gen-contribution-custom__group{flex:1;display:flex;flex-flow:row nowrap}.rev-gen-contribution-custom__inner{display:flex;flex-flow:row nowrap;align-items:flex-end;justify-content:space-between}.rev-gen-contribution-custom__form{display:flex;align-items:flex-end}.rev-gen-contribution-custom h3.rev-gen-contribution-custom__title{margin:0;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;line-height:1.33;font-size:14px;color:#1d1d1d}.rev-gen-contribution-custom__back{position:relative;bottom:5px;float:left;cursor:pointer;width:15px;margin-right:15px}.rev-gen-contribution-custom__back-arrow{display:inline-block;vertical-align:middle;border:solid #000;border-width:0 2px 2px 0;padding:14px;transform:rotate(135deg)}.rev-gen-contribution-custom__symbol{width:15px;text-align:center}.rev-gen-contribution-custom label{display:block;margin-left:15px;margin-bottom:5px;line-height:1;font-weight:normal;font-size:12px}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send{flex:1;width:auto;min-width:70px;max-width:none;max-height:49px;margin:0;padding:14px 10px !important;border:2px solid #1d1d1d !important;border-radius:5px;font-weight:700;font-size:14px;color:#1d1d1d !important;background-color:#fff !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:active,.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:hover{color:#fff !important;background-color:#1d1d1d !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:disabled{opacity:0.8}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send .rev-gen-contribution-custom-send__loading{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading{padding:11px 10px !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__text{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__loading{display:inline-block;width:21px;height:21px;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMiIgYmFzZVByb2ZpbGU9InRpbnkiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTAwIDUwMCIgb3ZlcmZsb3c9InZpc2libGUiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Ik0zMTcsNDc5LjRjLTEyLDAtMjMuMy03LjYtMjcuNC0xOS42Yy01LjItMTUuMSwyLjktMzEuNiwxOC0zNi44YzcxLjUtMjQuNiwxMTkuNS05MS45LDExOS41LTE2Ny41CgkJYzAtOTcuNi03OS40LTE3Ny4xLTE3Ny4xLTE3Ny4xUzcyLjksMTU3LjksNzIuOSwyNTUuNmMwLDc1LjYsNDgsMTQzLDExOS41LDE2Ny41YzE1LjEsNS4yLDIzLjIsMjEuNywxOCwzNi44cy0yMS43LDIzLjItMzYuOCwxOAoJCUM3OC43LDQ0NS4zLDE1LDM1NS45LDE1LDI1NS42YzAtMTI5LjYsMTA1LjQtMjM1LDIzNS0yMzVzMjM1LDEwNS40LDIzNSwyMzVjMCwxMDAuNC02My43LDE4OS43LTE1OC42LDIyMi4zCgkJQzMyMy4zLDQ3OC45LDMyMC4xLDQ3OS40LDMxNyw0NzkuNHoiLz4KPC9nPgo8L3N2Zz4K) no-repeat;background-size:21px 21px;transition:transform 0.2s ease-in-out;-webkit-animation:pulse-loading 1s infinite;animation:pulse-loading 1s infinite}.rev-gen-contribution-footer{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif}.rev-gen-contribution-footer__inner{display:flex;align-items:center;justify-content:center}.rev-gen-contribution-footer a{flex:1;margin-left:5px;max-width:75px;opacity:0.6;transition:opacity 0.2s ease-in}.rev-gen-contribution-footer a:hover{opacity:1}.rev-gen-contribution-footer a img{vertical-align:middle}.rev-gen-contribution-footer span{position:relative;top:2px;line-height:1.1;font-size:11px;color:#808080}.rev-gen-contribution--box{max-width:380px !important}.rev-gen-contribution--bar{width:100%}.rev-gen-contribution--bar .rev-gen-contribution__donate{margin:15px 0 5px}.rev-gen-contribution--bar .rev-gen-contribution__inner{max-width:100%;padding:15px 25px}.rev-gen-contribution--bar.size-large h2.rev-gen-contribution__title{min-width:250px;margin-right:15px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__inner{padding:0 25px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__choose{display:flex;align-items:center}.rev-gen-contribution--bar.size-large .rev-gen-contribution__description{min-width:250px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form{margin:15px 0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form button[type="submit"]{width:300px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__amounts{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__donate{align-self:flex-end;margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-info-modal{left:auto;right:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom{margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom label{display:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom__back{bottom:auto;float:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom input[type="number"]{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom button[type="submit"]{width:auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution__loading{transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response{display:flex;align-items:center;transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response .tab_widget__container{height:85px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer{margin-left:15px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer a{width:75px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__tab-status{position:relative;min-width:250px;height:85px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__loading{left:0;margin-left:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__response{height:100%;overflow:hidden;margin-right:10px;transform:none;background-color:transparent}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution iframe{height:85px !important}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution-footer{display:none}.rev-gen-contribution--bar.size-large.amount-selected .rev-gen-contribution__amounts{display:none}.rev-gen-contribution--bar.size-large.rev-gen-iframe-ready iframe{width:600px}.rev-gen-contribution--button .rev-gen-contribution__inner{padding:0;box-shadow:none;background-color:transparent;text-align:center}.rev-gen-contribution--button .rev-gen-contribution__footer{margin-top:15px}.rev-gen-contribution--button .rev-gen-contribution__button{max-width:320px;padding:15px 30px;border:0;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:16px;color:#fff;background-color:#1d1d1d;text-decoration:none}.rev-gen-contribution--button .rev-gen-contribution__button:hover,.rev-gen-contribution--button .rev-gen-contribution__button:active{border:0;box-shadow:none;text-decoration:none}.rev-gen-contribution--button:not(.is-amp) .rev-gen-contribution-modal{display:none}.rev-gen-contribution.is-amp iframe{position:relative;z-index:15}.rev-gen-contribution .amp-form-submit-success>*{display:none}.rev-gen-contribution .amp-form-submitting{height:100px}.rev-gen-contribution__amp-show-modal,.rev-gen-contribution__amp-show-modal--purchase{position:absolute;bottom:35px;left:165px;z-index:10;width:95px;height:20px;display:block;background:transparent;cursor:pointer}.rev-gen-contribution__amp-show-modal--purchase{top:72px;bottom:auto}.rev-gen-contribution-modal{position:fixed;top:0;left:0;z-index:9999;display:flex;align-items:center;width:100%;height:100%;background-color:rgba(0,0,0,0.5);opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution{opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution__inner{padding:30px 25px 18px;background-color:#fff}.rev-gen-contribution-modal.active{opacity:1}.rev-gen-contribution-modal.active .rev-gen-contribution{opacity:1}.rev-gen-contribution-modal__close{position:absolute;top:15px;right:15px;display:inline-block;width:15px;height:15px;padding:0 !important;border:0 !important;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMyIgaGVpZ2h0PSIxMyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEzIDEzIj4KICAgIDxwYXRoIGZpbGw9IiMxRDFEMUQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTguMDMyIDYuNUwxMyAxLjUzMSAxMS40NjggMCA2LjUgNC45NjggMS41MzIgMCAwIDEuNTMybDQuOTY4IDQuOTY3TDAgMTEuNDY3bDEuNTMyIDEuNTMyTDYuNSA4LjAzbDQuOTY4IDQuOTY4TDEzIDExLjQ2NyA4LjAzMiA2LjQ5OXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgo8L3N2Zz4K) no-repeat !important;background-size:15px 15px !important;opacity:0.35}.is-amp .rev-gen-contribution-modal{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution-amp-wrap{display:flex;width:100%;height:100%;align-items:center}@-webkit-keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}.font,.tab_widget__donated-amount-text,.tab_widget__thank-you-message,.tab_widget__regular-text,.tab_widget__link,.tab__widget__info-button-question-mark,.tab_widget__info_container{font-family:"Helvetica Neue", Arial, Helvetica, sans-serif}.tab_widget{display:flex;justify-content:center;align-items:center;height:100%}.tab_widget__container{position:relative;background-color:#fff;border-radius:6px;display:flex;align-items:center;width:340px;height:104px;transition:transform 0.5s linear}.tab_widget__container-visible{transform:translate(0)}.tab_widget__arc-container{margin-right:6px;width:calc(64px + 6px);height:64px;position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:center}.tab_widget__arc--background{position:absolute;stroke:#cbd5e0}.tab_widget__arc--filled{position:absolute;stroke:#000;stroke-dasharray:175.84;stroke-dashoffset:175.84}.tab_widget__arc-animation{-webkit-animation:animateTabAmount 0.5s linear forwards;animation:animateTabAmount 0.5s linear forwards}.tab_widget__arc-animation--pulse{stroke:#000;animation:pulse 1s ease-in-out alternate-reverse infinite}.tab_widget__arc-animation--pulse circle{stroke:#000;stroke-opacity:inherit}@-webkit-keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@-webkit-keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}@keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}.tab_widget__donated-amount-text{font-weight:700}.tab_widget__thank-you-message{font-weight:500;margin:0;margin-bottom:5px;font-size:19px;color:#1d1d1d;text-align:left}.tab_widget__regular-text{font-weight:400;font-size:15px;margin:0;margin-bottom:5px;color:#333}.tab_widget__links-container{display:flex;align-items:center}.tab_widget__link{font-weight:400;margin:0;font-size:13px;color:#1d1d1d;text-decoration:underline;cursor:pointer}.tab_widget__links-separator{padding-right:5px;padding-left:5px;color:#333}.tab_widget__container-hidden{transform:translate(500px)}.tab__widget__info-button__container{position:absolute;right:6px;top:6px;cursor:pointer}.tab__widget__info-button{position:relative}.tab__widget__info-button-question-mark{position:absolute;font-weight:700;font-size:12px;color:#fff;left:34%;top:0}.tab__widget__close-button-x-mark{left:33%;top:-1px}.tab_widget__container__info-screen{position:absolute;height:100%;width:calc(100% + 50px);margin-top:-35px;margin-left:-25px;z-index:10;visibility:var(--infoScreenVisibility);text-align:left}.tab_widget__info_container{position:relative;padding:20px;background-color:#fff;box-shadow:0 1px 8px 0 rgba(29,29,29,0.16);border-radius:6px}.tab_widget__info-title{font-weight:500;font-size:18px;margin:0}.tab_widget__info-steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.tab_widget__info-step{display:flex;align-items:center;font-weight:500;font-size:14px;margin:0}.tab_widget__info-step-text{margin-left:6px;margin-right:10px}.tab_widget__info-step-number{display:flex;justify-content:center;align-items:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.tab_widget__info-description{font-weight:500;font-size:14px}.tab_widget__info-description p{margin-bottom:1em}.tab_widget__info-description p:last-child{margin-bottom:0}.tab__widget__icon{position:unset;height:18px;width:18px}1 .amount-text,.rev-gen-contribution__amount{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;font-weight:600;line-height:1.21;text-align:center;color:#333}.rev-gen-contribution{position:relative;width:100%;margin:20px auto;height:auto;transition:height 0.2s ease-in}.rev-gen-contribution__inner{position:relative;height:100%;padding:18px 25px;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:250px}.rev-gen-contribution__question-mark,.rev-gen-contribution-info-modal__x-mark{position:absolute;top:10px;right:10px;z-index:20;cursor:pointer;width:18px;height:18px;border-radius:50%;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:700;font-size:12px;background-color:#1d1d1d;color:#fff;text-align:center}.rev-gen-contribution__question-mark span,.rev-gen-contribution-info-modal__x-mark span{position:relative;left:1px}.rev-gen-contribution-modal .rev-gen-contribution__question-mark,.rev-gen-contribution-modal .rev-gen-contribution-info-modal__x-mark{top:13px;right:35px}.rev-gen-contribution-info-modal{position:absolute;top:0;left:0;z-index:50;padding:20px;border-radius:5px;box-shadow:0 0 15px 0 rgba(0,0,0,0.1);background-color:#fff}.rev-gen-contribution-info-modal__x-mark span{position:relative;top:-1px}.rev-gen-contribution-info-modal__title{margin:0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:18px}.rev-gen-contribution-info-modal__steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.rev-gen-contribution-info-modal__step{display:flex;align-items:center;margin:0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__step-text{margin-left:6px;margin-right:10px}.rev-gen-contribution-info-modal__step-number{display:flex;align-items:center;justify-content:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.rev-gen-contribution-info-modal__description p{margin-bottom:1em;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:14px}.rev-gen-contribution-info-modal__description p:last-child{margin-bottom:0}.rev-gen-contribution h2.rev-gen-contribution__title{margin:0;max-width:100%;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:bold;line-height:1.33;font-size:21px;text-align:center;color:#1d1d1d}.rev-gen-contribution h2.rev-gen-contribution__title::before,.rev-gen-contribution h2.rev-gen-contribution__title::after{display:none !important}.rev-gen-contribution__description{max-width:100%;font-size:14px;text-align:center}.rev-gen-contribution__amounts{display:flex;flex-flow:row nowrap;justify-content:space-between;margin-bottom:20px}.rev-gen-contribution--bar .rev-gen-contribution__amounts{justify-content:center}.rev-gen-contribution__form{margin:20px 0}.rev-gen-contribution__form.amp-form-submit-success,.rev-gen-contribution__form.amp-form-submit-error{max-height:250px;overflow:hidden;margin:0}.rev-gen-contribution__form div[submit-success]{position:relative;z-index:10}.rev-gen-contribution__form button[type="submit"]{cursor:pointer;max-width:100%;flex:0 1 100%;width:100%;padding:15px 0;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:15px;border:1px solid #000;border-radius:4px;font-weight:500;background:#1d1d1d !important;color:#fff !important;text-decoration:none;text-transform:none;text-shadow:none}.rev-gen-contribution__form button[type="submit"].show{display:block}.rev-gen-contribution .rev-gen-hidden{display:none}.rev-gen-contribution__amount{min-width:75px;border:solid 2px #1d1d1d;border-radius:5px;margin:0 2px;display:flex;align-items:center;text-align:center;justify-content:center;overflow:hidden;cursor:pointer;word-break:normal;color:#1d1d1d;background-color:#fff}.rev-gen-contribution__amount input{position:absolute;opacity:0;width:0;height:0}.rev-gen-contribution__amount--custom{outline:0;text-transform:none;text-decoration:none}.rev-gen-contribution__amount--custom:hover,.rev-gen-contribution__amount--custom:active,.rev-gen-contribution__amount--custom:focus{background:#1d1d1d !important;color:#fff !important;text-decoration:none}.rev-gen-contribution__amount .rev-gen-contribution-control__label{display:block;width:100%;height:100%;border:0;padding:15px;font-size:14px;background:#fff !important;color:#1d1d1d !important;box-shadow:none !important;transition:background-color 0.05s ease-in !important;text-decoration:none !important;text-transform:none !important;letter-spacing:0 !important}.rev-gen-contribution__amount .rev-gen-contribution-control__label:hover{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount input:checked+.rev-gen-contribution-control__label{background:#1d1d1d !important;color:#fff !important}.rev-gen-contribution__amount-wrapper{position:relative;display:flex;justify-content:center}.rev-gen-contribution__tip{margin:0 0 5px;line-height:1;font-size:13px;text-align:center}.rev-gen-contribution__tip.rev-gen-hidden{visibility:hidden}.rev-gen-contribution__custom input[type="number"]{min-width:220px;margin:0 5px 0 0;padding:13.5px 0 13px 15px;border-radius:5px;background-color:rgba(160,160,160,0.12);font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;outline:0;border:0}.rev-gen-contribution__custom.rev-gen-hidden:not[hidden]{display:none}.rev-gen-contribution__tab-status{height:100%;font-size:14px;text-align:center;transition:min-height 0.2s ease-in}.rev-gen-contribution__tab-status iframe{width:100%;height:0;margin:0 !important;padding:0 !important;border:0 !important}.rev-gen-contribution__response{position:relative;z-index:2;width:100%;background-color:#fff}.rev-gen-contribution__loading{position:absolute;z-index:1;top:50%;margin-top:-32px;left:50%;margin-left:-38px}.rev-gen-contribution-custom{max-width:335px;margin:10px auto;display:flex;flex-flow:row nowrap;align-items:center}.rev-gen-contribution-custom__group{flex:1;display:flex;flex-flow:row nowrap}.rev-gen-contribution-custom__inner{display:flex;flex-flow:row nowrap;align-items:flex-end;justify-content:space-between}.rev-gen-contribution-custom__form{display:flex;align-items:flex-end}.rev-gen-contribution-custom h3.rev-gen-contribution-custom__title{margin:0;border:1px solid transparent;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;line-height:1.33;font-size:14px;color:#1d1d1d}.rev-gen-contribution-custom__back{position:relative;bottom:0;float:left;cursor:pointer;width:15px;margin-right:15px}.rev-gen-contribution-custom__back-arrow{display:inline-block;vertical-align:middle;border:solid #000;border-width:0 2px 2px 0;padding:14px;transform:rotate(135deg)}.rev-gen-contribution-custom__symbol{width:15px;text-align:center}.rev-gen-contribution-custom label{display:block;margin-left:15px;margin-bottom:5px;line-height:1;font-weight:normal;font-size:12px}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send{flex:1;width:auto;min-width:70px;max-width:none;max-height:49px;margin:0;padding:14px 10px !important;border:2px solid #1d1d1d !important;border-radius:5px;font-weight:700;font-size:14px;color:#1d1d1d !important;background-color:#fff !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:active,.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:hover{color:#fff !important;background-color:#1d1d1d !important;text-decoration:none !important;box-shadow:none !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send:disabled{opacity:0.8}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send .rev-gen-contribution-custom-send__loading{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading{padding:11px 10px !important}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__text{display:none}.rev-gen-contribution-custom button.rev-gen-contribution-custom-send.loading .rev-gen-contribution-send__loading{display:inline-block;width:21px;height:21px;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMiIgYmFzZVByb2ZpbGU9InRpbnkiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTAwIDUwMCIgb3ZlcmZsb3c9InZpc2libGUiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Ik0zMTcsNDc5LjRjLTEyLDAtMjMuMy03LjYtMjcuNC0xOS42Yy01LjItMTUuMSwyLjktMzEuNiwxOC0zNi44YzcxLjUtMjQuNiwxMTkuNS05MS45LDExOS41LTE2Ny41CgkJYzAtOTcuNi03OS40LTE3Ny4xLTE3Ny4xLTE3Ny4xUzcyLjksMTU3LjksNzIuOSwyNTUuNmMwLDc1LjYsNDgsMTQzLDExOS41LDE2Ny41YzE1LjEsNS4yLDIzLjIsMjEuNywxOCwzNi44cy0yMS43LDIzLjItMzYuOCwxOAoJCUM3OC43LDQ0NS4zLDE1LDM1NS45LDE1LDI1NS42YzAtMTI5LjYsMTA1LjQtMjM1LDIzNS0yMzVzMjM1LDEwNS40LDIzNSwyMzVjMCwxMDAuNC02My43LDE4OS43LTE1OC42LDIyMi4zCgkJQzMyMy4zLDQ3OC45LDMyMC4xLDQ3OS40LDMxNyw0NzkuNHoiLz4KPC9nPgo8L3N2Zz4K) no-repeat;background-size:21px 21px;transition:transform 0.2s ease-in-out;-webkit-animation:pulse-loading 1s infinite;animation:pulse-loading 1s infinite}.rev-gen-contribution-footer{font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif}.rev-gen-contribution-footer__inner{display:flex;align-items:center;justify-content:center}.rev-gen-contribution-footer a{flex:1;margin-left:5px;max-width:75px;opacity:0.6;transition:opacity 0.2s ease-in}.rev-gen-contribution-footer a:hover{opacity:1}.rev-gen-contribution-footer a img{vertical-align:middle}.rev-gen-contribution-footer span{position:relative;top:2px;line-height:1.1;font-size:11px;color:#808080}.rev-gen-contribution--box{max-width:380px !important}.rev-gen-contribution--bar{width:100%}.rev-gen-contribution--bar .rev-gen-contribution__donate{margin:15px 0 5px}.rev-gen-contribution--bar .rev-gen-contribution__inner{max-width:100%;padding:15px 25px}.rev-gen-contribution--bar.size-large h2.rev-gen-contribution__title{min-width:250px;margin-right:15px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__inner{padding:0 25px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__choose{display:flex;align-items:center}.rev-gen-contribution--bar.size-large .rev-gen-contribution__description{min-width:250px;text-align:left}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form{margin:15px 0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__form button[type="submit"]{width:300px}.rev-gen-contribution--bar.size-large .rev-gen-contribution__amounts{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution__donate{align-self:flex-end;margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-info-modal{left:auto;right:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom{margin:0 0 0 auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom label{display:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom__back{bottom:auto;float:none}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom input[type="number"]{margin-bottom:0}.rev-gen-contribution--bar.size-large .rev-gen-contribution-custom button[type="submit"]{width:auto}.rev-gen-contribution--bar.size-large .rev-gen-contribution__loading{transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response{display:flex;align-items:center;transform:scale(0.85)}.rev-gen-contribution--bar.size-large .rev-gen-contribution__response .tab_widget__container{height:85px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer{margin-left:15px}.rev-gen-contribution--bar.size-large .rev-gen-contribution-footer a{width:75px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__inner{min-height:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__tab-status{position:relative;min-width:250px;height:85px}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__loading{left:0;margin-left:0}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution__response{height:100%;overflow:hidden;margin-right:10px;transform:none;background-color:transparent}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution iframe{height:85px !important}.rev-gen-contribution--bar.size-large.rev-gen-contribution--payment .rev-gen-contribution-footer{display:none}.rev-gen-contribution--bar.size-large.amount-selected .rev-gen-contribution__amounts{display:none}.rev-gen-contribution--bar.size-large.rev-gen-iframe-ready iframe{width:600px}.rev-gen-contribution--button .rev-gen-contribution__inner{padding:0;box-shadow:none;background-color:transparent;text-align:center}.rev-gen-contribution--button .rev-gen-contribution__footer{margin-top:15px}.rev-gen-contribution--button .rev-gen-contribution__button{max-width:320px;padding:15px 30px;border:0;border-radius:5px;font-family:"Helvetica Neue","Open Sans","Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:500;font-size:16px;color:#fff;background-color:#1d1d1d;text-decoration:none}.rev-gen-contribution--button .rev-gen-contribution__button:hover,.rev-gen-contribution--button .rev-gen-contribution__button:active{border:0;box-shadow:none;text-decoration:none}.rev-gen-contribution--button:not(.is-amp) .rev-gen-contribution-modal{display:none}.rev-gen-contribution.is-amp iframe{position:relative;z-index:15}.rev-gen-contribution .amp-form-submit-success>*{display:none}.rev-gen-contribution .amp-form-submitting{height:100px}.rev-gen-contribution__amp-show-modal,.rev-gen-contribution__amp-show-modal--purchase{position:absolute;bottom:19px;left:137px;z-index:10;width:95px;height:20px;display:block;background:transparent;cursor:pointer}.rev-gen-contribution__amp-show-modal--purchase{top:72px;bottom:auto}.rev-gen-contribution-modal{position:fixed;top:0;left:0;z-index:9999;display:flex;align-items:center;width:100%;height:100%;background-color:rgba(0,0,0,0.5);opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution{opacity:0;transition:opacity 0.13s ease-in}.rev-gen-contribution-modal .rev-gen-contribution__inner{padding:30px 25px 18px;background-color:#fff}.rev-gen-contribution-modal.active{opacity:1}.rev-gen-contribution-modal.active .rev-gen-contribution{opacity:1}.rev-gen-contribution-modal__close{position:absolute;top:15px;right:15px;display:inline-block;width:15px;height:15px;padding:0 !important;border:0 !important;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMyIgaGVpZ2h0PSIxMyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEzIDEzIj4KICAgIDxwYXRoIGZpbGw9IiMxRDFEMUQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTguMDMyIDYuNUwxMyAxLjUzMSAxMS40NjggMCA2LjUgNC45NjggMS41MzIgMCAwIDEuNTMybDQuOTY4IDQuOTY3TDAgMTEuNDY3bDEuNTMyIDEuNTMyTDYuNSA4LjAzbDQuOTY4IDQuOTY4TDEzIDExLjQ2NyA4LjAzMiA2LjQ5OXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgo8L3N2Zz4K) no-repeat !important;background-size:15px 15px !important;opacity:0.35}.is-amp .rev-gen-contribution-modal{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution{opacity:1}.is-amp .rev-gen-contribution-modal .rev-gen-contribution-amp-wrap{display:flex;width:100%;height:100%;align-items:center}@-webkit-keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes pulse-loading{0%{transform:scale(1.1)}50%{transform:scale(1.15)}75%{transform:scale(1.1)}100%{transform:scale(1)}}.font,.tab_widget__donated-amount-text,.tab_widget__thank-you-message,.tab_widget__regular-text,a.tab_widget__link,.tab__widget__info-button-question-mark,.tab_widget__info_container{font-family:"Helvetica Neue", Arial, Helvetica, sans-serif}.tab_widget{display:flex;justify-content:center;align-items:center;height:100%}.tab_widget__container{position:relative;background-color:#fff;border-radius:6px;display:flex;align-items:center;width:340px;height:104px;transition:transform 0.5s linear}.tab_widget__container-visible{transform:translate(0)}.tab_widget__arc-container{margin-right:6px;width:calc(64px + 6px);height:64px;position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:center}.tab_widget__arc--background{position:absolute;stroke:#cbd5e0}.tab_widget__arc--filled{position:absolute;stroke:#000;stroke-dasharray:175.84;stroke-dashoffset:175.84}.tab_widget__arc-animation{-webkit-animation:animateTabAmount 0.5s linear forwards;animation:animateTabAmount 0.5s linear forwards}.tab_widget__arc-animation--pulse{stroke:#000;animation:pulse 1s ease-in-out alternate-reverse infinite}.tab_widget__arc-animation--pulse circle{stroke:#000;stroke-opacity:inherit}@-webkit-keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@keyframes animateTabAmount{to{stroke-dashoffset:var(--strokeDashOffset)}}@-webkit-keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}@keyframes pulse{0%{stroke-opacity:0.2}100%{transform:scale(1.1)}}.tab_widget__donated-amount-text{font-weight:700}.tab_widget__thank-you-message{font-weight:500;margin:0;margin-bottom:5px;font-size:19px;color:#1d1d1d;text-align:left}.tab_widget__regular-text{font-weight:400;font-size:15px;margin:0;margin-bottom:5px;color:#333}.tab_widget__links-container{display:flex;align-items:center}a.tab_widget__link{font-weight:400;margin:0;font-size:13px;color:#1d1d1d;text-decoration:underline;cursor:pointer}a.tab_widget__link:hover,a.tab_widget__link:visited{color:#1d1d1d}.tab_widget__links-separator{padding-right:5px;padding-left:5px;color:#333}.tab_widget__container-hidden{transform:translate(500px)}.tab__widget__info-button__container{position:absolute;right:6px;top:6px;cursor:pointer}.tab__widget__info-button{position:relative}.tab__widget__info-button-question-mark{position:absolute;font-weight:700;font-size:12px;color:#fff;left:34%;top:0}.tab__widget__close-button-x-mark{left:33%;top:-1px}.tab_widget__container__info-screen{position:absolute;height:100%;width:calc(100% + 50px);margin-top:-35px;margin-left:-25px;z-index:10;visibility:var(--infoScreenVisibility);text-align:left}.tab_widget__info_container{position:relative;padding:20px;background-color:#fff;box-shadow:0 1px 8px 0 rgba(29,29,29,0.16);border-radius:6px}.tab_widget__info-title{font-weight:500;font-size:18px;margin:0}.tab_widget__info-steps{margin-top:18px;margin-bottom:20px;display:flex;align-items:center}.tab_widget__info-step{display:flex;align-items:center;font-weight:500;font-size:14px;margin:0}.tab_widget__info-step-text{margin-left:6px;margin-right:10px}.tab_widget__info-step-number{display:flex;justify-content:center;align-items:center;font-size:10px;width:18px;height:18px;border-radius:50%;background-color:#1d1d1d;color:#fff}.tab_widget__info-description{font-weight:500;font-size:14px}.tab_widget__info-description p{margin-bottom:1em}.tab_widget__info-description p:last-child{margin-bottom:0}.tab__widget__icon{position:unset;height:18px;width:18px} 2 2 -
revenue-generator/trunk/v2/assets/build/frontend.js
r2466307 r2468562 1 (()=>{"use strict";(()=>{const t=t=>{const e=t+"=",o=decodeURIComponent(document.cookie).split(";");for(let t=0;t<o.length;t++){let s=o[t];for(;" "===s.charAt(0);)s=s.substring(1);if(0===s.indexOf(e))return s.substring(e.length,s.length)}return""};class e{constructor(t){this.el=t,this.itemId=this.el.dataset.contributionId,this.closeTimeout=null,this.RESET_TIMEOUT=3e3,this.$o={form:t.querySelector(".rev-gen-contribution__form"),submitButton:t.querySelector("button[type=submit][data-mytab-button]"),amounts:t.querySelector(".rev-gen-contribution__amounts"),choose:t.querySelector(".rev-gen-contribution__choose"),customChoice:t.querySelector(".rev-gen-contribution__amount--custom"),response:t.querySelector(".rev-gen-contribution__response"),loading:t.querySelector(".rev-gen-contribution__loading"),custom:{el:t.querySelector(".rev-gen-contribution__custom"),input:t.querySelector(".rev-gen-contribution__custom input"),backButton:t.querySelector(".rev-gen-contribution-custom__back")},modal:{el:t.querySelector(".rev-gen-contribution-info-modal"),openButton:t.querySelector(".rev-gen-contribution__question-mark"),closeButton:t.querySelector(".rev-gen-contribution-info-modal__x-mark")}},this.bindEvents(),this.maybeContinueFlow()}bindEvents(){const t=this;new ResizeObserver((t=>{t.forEach((t=>{const e=t.target.dataset.breakpoints?JSON.parse(t.target.dataset.breakpoints):"";e&&Object.keys(e).forEach((o=>{const s=e[o],n="size-"+o;t.contentRect.width>=s?t.target.classList.add(n):t.target.classList.remove(n)}))}))})).observe(this.el),this.$o.customChoice.addEventListener("click",(t=>{t.preventDefault(),this.showCustomForm()})),this.$o.custom.backButton.addEventListener("click",(t=>{t.preventDefault(),this.hideCustomForm()})),this.$o.form.addEventListener("change",(()=>{this.customModeActive||(new FormData(this.$o.form).get("amount")?(this.el.classList.add("amount-selected"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.submitButton.removeAttribute("hidden")):(this.el.classList.remove("amount-selected"),this.$o.submitButton.classList.add("rev-gen-hidden"),this.$o.submitButton.addAttribute("hidden")))})),this.$o.form.addEventListener("submit",(e=>{e.preventDefault();const o=new FormData(this.$o.form),s=new XMLHttpRequest;s.open("POST",this.$o.form.getAttribute("action"),!0),s.send(o),s.onreadystatechange=function(){if(4===this.readyState){const e=JSON.parse(this.response);switch(this.status){case 200:const o=document.createElement("script");o.src=t.$o.form.dataset.tabWidgetUrl,t.$o.response.appendChild(o),t.$o.response.innerHTML=e.data.html,o.onload=()=>{t.$o.choose.classList.add("rev-gen-hidden");const e=t.el.querySelectorAll(".tab_widget__link")[1];t.setCloseTimeout(),e.addEventListener("click",(()=>{t.openInfoModal()})),t.hideSubmit()};break;case 402:t.$o.modal.openButton.classList.add("rev-gen-hidden"),t.$o.loading.classList.remove("rev-gen-hidden"),t.el.classList.add("rev-gen-contribution--payment"),t.$o.response.innerHTML=e.data.html,t.$o.choose.classList.add("rev-gen-hidden"),t.hideSubmit();break;case 401:window.location.href=e.data.auth_url}}}})),this.$o.modal.openButton.addEventListener("click",(()=>{t.openInfoModal()})),this.$o.modal.closeButton.addEventListener("click",(()=>{t.closeInfoModal()})),window.addEventListener("message",(e=>{e.data&&"OPEN_INFO_MODAL"===e.data&&t.openInfoModal()})),window.addEventListener("message",(e=>{e.data&&"PAYMENT_SUCCESSFUL"===e.data&&t.reset()})),this.el.addEventListener("rev-gen-iframe-load",(e=>{const o=e.detail||"";o&&(t.$o.loading.classList.add("rev-gen-hidden"),t.$o.modal.openButton.classList.remove("rev-gen-hidden"),o.style.height=o.contentWindow.document.body.scrollHeight+"px",t.el.classList.add("rev-gen-iframe-ready"))}))}hideSubmit(){this.$o.submitButton.classList.add("rev-gen-hidden")}showCustomForm(){this.customModeActive=!0,this.$o.amounts.classList.add("rev-gen-hidden"),this.$o.custom.el.classList.remove("rev-gen-hidden"),this.$o.custom.el.removeAttribute("hidden"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.custom.input.focus()}hideCustomForm(){this.customModeActive=!1,this.$o.form.reset(),this.$o.custom.el.classList.add("rev-gen-hidden"),this.$o.custom.el.setAttribute("hidden",""),this.$o.amounts.classList.remove("rev-gen-hidden"),this.$o.submitButton.classList.add("rev-gen-hidden")}openInfoModal(){clearTimeout(this.closeTimeout),this.$o.modal.el.classList.remove("rev-gen-hidden")}closeInfoModal(){this.$o.modal.el.classList.add("rev-gen-hidden")}reset(){this.el.classList.remove("amount-selected"),this.$o.response.innerHTML="",this.el.classList.remove("rev-gen-contribution--payment"),this.$o.form.reset(),this.$o.choose.classList.remove("rev-gen-hidden")}setCloseTimeout(){const t=this;this.closeTimeout=setTimeout((()=>{t.reset()}),t.RESET_TIMEOUT)}maybeContinueFlow(){if(!t("rgv2_data"))return;const e=JSON.parse(t("rgv2_data"));if(parseInt(this.itemId,10)!==parseInt(e.contribution.item_id,10))return;const o=this.$o.form.querySelector('[value="'+e.contribution.amount+'"]');o?o.checked=!0:(this.$o.custom.input.value=o,this.showCustomForm());const s=new MouseEvent("click");this.$o.submitButton.dispatchEvent(s)}}window.laterpayIframeLoaded=t=>{const e=t.dataset.contributionId;if(!e)return;const o=new CustomEvent("rev-gen-iframe-load",{detail:t});let s=document.querySelectorAll('.rev-gen-contribution[data-contribution-id="'+e+'"]');s=s[s.length-1],s.dispatchEvent(o)};class o{constructor(t){this.$button={trigger:t.querySelector("button"),modal:t.querySelector(".rev-gen-contribution-modal")},this.$modal={el:""},this.bindButtonEvents()}bindButtonEvents(){this.$button.trigger.addEventListener("click",this.open.bind(this))}bindModalEvents(){this.$modal.closeButton.addEventListener("click",this.close.bind(this))}open(t){t.preventDefault();const e=this.$button.modal.cloneNode(!0);this.$modal.el=e,this.$modal.contributionEl=e.querySelector(".rev-gen-contribution"),this.$modal.closeButton=e.querySelector(".rev-gen-contribution-modal__close"),document.querySelector("body").appendChild(e),this.bindModalEvents(),this.initContributionRequest(),setTimeout((function(){e.classList.add("active")}),100)}initContributionRequest(){this.contributionInstance=new e(this.$modal.contributionEl)}close(t){t.preventDefault();const e=this.$modal.el;e.classList.remove("active"),setTimeout((function(){document.querySelector("body").removeChild(e)}),200)}}document.addEventListener("DOMContentLoaded",(()=>{const t=document.getElementsByClassName("rev-gen-contribution");for(const s of t)s.dataset.type&&("button"!==s.dataset.type?new e(s):new o(s))}))})()})();1 (()=>{"use strict";(()=>{const t=t=>{const e=t+"=",o=decodeURIComponent(document.cookie).split(";");for(let t=0;t<o.length;t++){let n=o[t];for(;" "===n.charAt(0);)n=n.substring(1);if(0===n.indexOf(e))return n.substring(e.length,n.length)}return""},e=(t,e,o)=>{const n=new Date;n.setTime(n.getTime()+24*o*60*60*1e3);const s="expires="+n.toUTCString();document.cookie=t+"="+e+";"+s+";path=/"};class o{constructor(t){this.el=t,this.itemId=this.el.dataset.contributionId,this.closeTimeout=null,this.RESET_TIMEOUT=3e3,this.$o={form:t.querySelector(".rev-gen-contribution__form"),submitButton:t.querySelector("button[type=submit][data-mytab-button]"),amounts:t.querySelector(".rev-gen-contribution__amounts"),choose:t.querySelector(".rev-gen-contribution__choose"),customChoice:t.querySelector(".rev-gen-contribution__amount--custom"),response:t.querySelector(".rev-gen-contribution__response"),loading:t.querySelector(".rev-gen-contribution__loading"),custom:{el:t.querySelector(".rev-gen-contribution__custom"),input:t.querySelector(".rev-gen-contribution__custom input"),backButton:t.querySelector(".rev-gen-contribution-custom__back")},modal:{el:t.querySelector(".rev-gen-contribution-info-modal"),openButton:t.querySelector(".rev-gen-contribution__question-mark"),closeButton:t.querySelector(".rev-gen-contribution-info-modal__x-mark")}},this.bindEvents(),this.maybeContinueFlow()}bindEvents(){const o=this;new ResizeObserver((t=>{t.forEach((t=>{const e=t.target.dataset.breakpoints?JSON.parse(t.target.dataset.breakpoints):"";e&&Object.keys(e).forEach((o=>{const n=e[o],s="size-"+o;t.contentRect.width>=n?t.target.classList.add(s):t.target.classList.remove(s)}))}))})).observe(this.el),this.$o.customChoice.addEventListener("click",(t=>{t.preventDefault(),this.showCustomForm()})),this.$o.custom.backButton.addEventListener("click",(t=>{t.preventDefault(),this.hideCustomForm()})),this.$o.form.addEventListener("change",(()=>{this.customModeActive||(new FormData(this.$o.form).get("amount")?(this.el.classList.add("amount-selected"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.submitButton.removeAttribute("hidden")):(this.el.classList.remove("amount-selected"),this.$o.submitButton.classList.add("rev-gen-hidden"),this.$o.submitButton.addAttribute("hidden")))})),this.$o.form.addEventListener("submit",(n=>{n.preventDefault();const s=new FormData(this.$o.form);s.append("rg_key",t("rg_key"));const i=new XMLHttpRequest;i.open("POST",this.$o.form.getAttribute("action"),!0),i.send(s),i.onreadystatechange=function(){if(4===this.readyState){const t=JSON.parse(this.response);switch(this.status){case 200:const n=document.createElement("script");n.src=o.$o.form.dataset.tabWidgetUrl,o.$o.response.appendChild(n),o.$o.response.innerHTML=t.data.html,n.onload=()=>{o.$o.choose.classList.add("rev-gen-hidden");const t=o.el.querySelectorAll(".tab_widget__link")[1];o.setCloseTimeout(),t.addEventListener("click",(()=>{o.openInfoModal()})),o.hideSubmit()};break;case 402:o.$o.modal.openButton.classList.add("rev-gen-hidden"),o.$o.loading.classList.remove("rev-gen-hidden"),o.el.classList.add("rev-gen-contribution--payment"),o.$o.response.innerHTML=t.data.html,o.$o.choose.classList.add("rev-gen-hidden"),o.hideSubmit();break;case 401:e("rg_key",t.data.session_key),e("rg_contribution_data",JSON.stringify(t.data.handover)),window.location.href=t.data.auth_url}}}})),this.$o.modal.openButton.addEventListener("click",(()=>{o.openInfoModal()})),this.$o.modal.closeButton.addEventListener("click",(()=>{o.closeInfoModal()})),window.addEventListener("message",(t=>{t.data&&"OPEN_INFO_MODAL"===t.data&&o.openInfoModal()})),window.addEventListener("message",(t=>{t.data&&"PAYMENT_SUCCESSFUL"===t.data&&o.reset()})),this.el.addEventListener("rev-gen-iframe-load",(t=>{const e=t.detail||"";e&&(o.$o.loading.classList.add("rev-gen-hidden"),o.$o.modal.openButton.classList.remove("rev-gen-hidden"),e.style.height=e.contentWindow.document.body.scrollHeight+"px",o.el.classList.add("rev-gen-iframe-ready"))}))}hideSubmit(){this.$o.submitButton.classList.add("rev-gen-hidden")}showCustomForm(){this.customModeActive=!0,this.$o.amounts.classList.add("rev-gen-hidden"),this.$o.custom.el.classList.remove("rev-gen-hidden"),this.$o.custom.el.removeAttribute("hidden"),this.$o.submitButton.classList.remove("rev-gen-hidden"),this.$o.custom.input.focus()}hideCustomForm(){this.customModeActive=!1,this.$o.form.reset(),this.$o.custom.el.classList.add("rev-gen-hidden"),this.$o.custom.el.setAttribute("hidden",""),this.$o.amounts.classList.remove("rev-gen-hidden"),this.$o.submitButton.classList.add("rev-gen-hidden")}openInfoModal(){clearTimeout(this.closeTimeout),this.$o.modal.el.classList.remove("rev-gen-hidden")}closeInfoModal(){this.$o.modal.el.classList.add("rev-gen-hidden")}reset(){this.el.classList.remove("amount-selected"),this.$o.response.innerHTML="",this.el.classList.remove("rev-gen-contribution--payment"),this.$o.form.reset(),this.$o.choose.classList.remove("rev-gen-hidden")}setCloseTimeout(){const t=this;this.closeTimeout=setTimeout((()=>{t.reset()}),t.RESET_TIMEOUT)}maybeContinueFlow(){if(!t("rg_contribution_data"))return;const o=JSON.parse(t("rg_contribution_data"));if(parseInt(this.itemId,10)!==parseInt(o.contribution.item_id,10))return;const n=this.$o.form.querySelector('[value="'+o.contribution.amount+'"]');n?n.checked=!0:(this.$o.custom.input.value=n,this.showCustomForm());const s=new MouseEvent("click");this.$o.submitButton.dispatchEvent(s),e("rg_contribution_data","")}}window.laterpayIframeLoaded=t=>{const e=t.dataset.contributionId;if(!e)return;const o=new CustomEvent("rev-gen-iframe-load",{detail:t});let n=document.querySelectorAll('.rev-gen-contribution[data-contribution-id="'+e+'"]');n=n[n.length-1],n.dispatchEvent(o)};class n{constructor(t){this.$button={trigger:t.querySelector("button"),modal:t.querySelector(".rev-gen-contribution-modal")},this.$modal={el:""},this.bindButtonEvents()}bindButtonEvents(){this.$button.trigger.addEventListener("click",this.open.bind(this))}bindModalEvents(){this.$modal.closeButton.addEventListener("click",this.close.bind(this))}open(t){t.preventDefault();const e=this.$button.modal.cloneNode(!0);this.$modal.el=e,this.$modal.contributionEl=e.querySelector(".rev-gen-contribution"),this.$modal.closeButton=e.querySelector(".rev-gen-contribution-modal__close"),document.querySelector("body").appendChild(e),this.bindModalEvents(),this.initContributionRequest(),setTimeout((function(){e.classList.add("active")}),100)}initContributionRequest(){this.contributionInstance=new o(this.$modal.contributionEl)}close(t){t.preventDefault();const e=this.$modal.el;e.classList.remove("active"),setTimeout((function(){document.querySelector("body").removeChild(e)}),200)}}document.addEventListener("DOMContentLoaded",(()=>{const t=document.getElementsByClassName("rev-gen-contribution");for(const e of t)e.dataset.type&&("button"!==e.dataset.type?new o(e):new n(e))}))})()})(); -
revenue-generator/trunk/v2/assets/src/js/frontend/contribution.js
r2466307 r2468562 1 1 /* global FormData, XMLHttpRequest, ResizeObserver, MouseEvent, CustomEvent */ 2 2 3 import { getCookie } from '../helpers/index';3 import { setCookie, getCookie } from '../helpers/index'; 4 4 5 5 /** … … 134 134 // Get form data. 135 135 const data = new FormData( this.$o.form ); 136 data.append( 'rg_key', getCookie( 'rg_key' ) ); 136 137 137 138 // Create ajax object. … … 145 146 const res = JSON.parse( this.response ); 146 147 147 /* eslint-disable no-alert */148 148 switch ( this.status ) { 149 149 // Item added to the tab. … … 195 195 // User not authorized. 196 196 case 401: 197 setCookie( 'rg_key', res.data.session_key ); 198 setCookie( 199 'rg_contribution_data', 200 JSON.stringify( res.data.handover ) 201 ); 202 197 203 // Redirect to auth. 198 204 window.location.href = res.data.auth_url; 199 205 break; 200 206 } 201 /* eslint-enable no-alert */202 207 } 203 208 }; … … 326 331 */ 327 332 maybeContinueFlow() { 328 if ( ! getCookie( 'rg v2_data' ) ) {333 if ( ! getCookie( 'rg_contribution_data' ) ) { 329 334 return; 330 335 } 331 336 332 const clientCookie = JSON.parse( getCookie( 'rg v2_data' ) );337 const clientCookie = JSON.parse( getCookie( 'rg_contribution_data' ) ); 333 338 334 339 if ( … … 358 363 const clickEvent = new MouseEvent( 'click' ); 359 364 this.$o.submitButton.dispatchEvent( clickEvent ); 365 366 // Reset session cookie to empty value after making a contribution. 367 setCookie( 'rg_contribution_data', '' ); 360 368 } 361 369 } -
revenue-generator/trunk/v2/assets/src/js/helpers/index.js
r2466307 r2468562 25 25 return ''; 26 26 }; 27 28 export const setCookie = ( cname, cvalue, expDays ) => { 29 const d = new Date(); 30 d.setTime( d.getTime() + expDays * 24 * 60 * 60 * 1000 ); 31 const expires = 'expires=' + d.toUTCString(); 32 document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/'; 33 }; -
revenue-generator/trunk/v2/assets/src/scss/frontend/_component.scss
r2466307 r2468562 116 116 } 117 117 118 .tab_widget__link {118 a.tab_widget__link { 119 119 @extend .font; 120 120 font-weight: 400; … … 124 124 text-decoration: underline; 125 125 cursor: pointer; 126 &:hover, 127 &:visited { 128 color: $color-dark; 129 } 126 130 } 127 131 -
revenue-generator/trunk/v2/assets/src/scss/frontend/contribution-dialog.scss
r2466307 r2468562 45 45 height: 18px; 46 46 border-radius: 50%; 47 font-family: $box-font; 47 48 font-weight: 700; 48 49 font-size: 12px; … … 81 82 &__title { 82 83 margin: 0; 84 font-family: $box-font; 83 85 font-weight: 500; 84 86 font-size: 18px; … … 94 96 align-items: center; 95 97 margin: 0; 98 font-family: $box-font; 96 99 font-weight: 500; 97 100 font-size: 14px; … … 113 116 } 114 117 &__description { 115 font-weight: 500;116 font-size: 14px;117 118 118 p { 119 119 margin-bottom: 1em; 120 font-family: $box-font; 121 font-weight: 500; 122 font-size: 14px; 120 123 &:last-child { 121 124 margin-bottom: 0; … … 164 167 &.amp-form-submit-success, 165 168 &.amp-form-submit-error { 169 max-height: 250px; 170 overflow: hidden; 166 171 margin: 0; 167 172 } 173 div[submit-success] { 174 position: relative; 175 z-index: 10; 176 } 168 177 button[type="submit"] { 178 cursor: pointer; 169 179 max-width: 100%; 170 180 flex: 0 1 100%; 171 181 width: 100%; 172 182 padding: 15px 0; 183 font-family: $box-font; 173 184 font-size: 15px; 174 185 border: 1px solid #000; … … 274 285 input[type="number"] { 275 286 min-width: 220px; 276 margin -right: 5px;287 margin: 0 5px 0 0; 277 288 padding: 13.5px 0 13px 15px; 278 289 border-radius: 5px; 279 290 background-color: rgba(160, 160, 160, 0.12); 280 margin-bottom: 10px;291 font-family: $box-font; 281 292 font-size: 14px; 282 293 outline: 0; … … 351 362 &__back { 352 363 position: relative; 353 bottom: 5px;364 bottom: 0; 354 365 float: left; 355 366 cursor: pointer; … … 640 651 &__amp-show-modal { 641 652 position: absolute; 642 bottom: 35px;643 left: 1 65px;653 bottom: 19px; 654 left: 137px; 644 655 z-index: 10; 645 656 width: 95px; -
revenue-generator/trunk/v2/inc/classes/api/class-auth-provider.php
r2466307 r2468562 74 74 75 75 /** 76 * Returns a new random string to use as the state parameter in an 77 * authorization flow. 78 * 79 * Adds support for PHP5 by generating state with `openssl_random_pseudo_bytes` if 80 * `random_bytes` does not exist. 81 * 82 * @param int $length Length of the random string to be generated. 83 * @return string 84 */ 85 protected function getRandomState( $length = 32 ) { 86 if ( function_exists( 'random_bytes' ) ) { 87 return bin2hex( random_bytes( $length / 2 ) ); 88 } 89 90 if ( function_exists( 'openssl_random_pseudo_bytes' ) ) { 91 return bin2hex( openssl_random_pseudo_bytes( $length / 2 ) ); 92 } 93 } 94 95 /** 76 96 * Check response and throw exception if error is present. 77 97 * -
revenue-generator/trunk/v2/inc/classes/api/class-auth.php
r2466307 r2468562 38 38 */ 39 39 const SERVER_KEY_OPTION_NAME = 'lp_rgv2_key'; 40 41 /**42 * Name of the cookie to store JWT.43 *44 * @const string45 */46 const TOKEN_COOKIE_NAME = 'rgv2_token';47 40 48 41 /** … … 151 144 152 145 /** 153 * Get tokens from client. 154 * 155 * @return boolean|JSON False on failure, JSON object on success. 156 */ 157 private function get_jwt_from_client() { 158 $jwt = ( isset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) ) ? sanitize_text_field( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) : ''; 159 160 if ( empty( $jwt ) ) { 161 return false; 162 } 163 164 $tokens = $this->decode_tokens( $jwt ); 146 * Get token from database if key is set. 147 * 148 * @return JWT 149 */ 150 public function get_token_from_db() { 151 $api = API::get_instance(); 152 153 // Return false if session key is not set. 154 if ( empty( $api->session_key ) ) { 155 return false; 156 } 157 158 // Get token by session key. 159 $tokens = get_transient( wp_hash( $api->session_key ) ); 160 $tokens = $this->decode_tokens( $tokens, $api->session_key ); 165 161 166 162 if ( is_wp_error( $tokens ) ) { … … 174 170 * Get access token. 175 171 * 176 * This looks for a token on clientfirst, returns false if it's not found so we can then172 * This looks for a token in database first, returns false if it's not found so we can then 177 173 * start the authorization code flow. 178 174 * … … 186 182 } 187 183 188 // Get tokens from the client.189 $tokens = $this->get_ jwt_from_client();184 // Get tokens from the database. 185 $tokens = $this->get_token_from_db(); 190 186 191 187 if ( ! $tokens ) { … … 216 212 } 217 213 214 if ( ! isset( $_GET['state'] ) ) { 215 return; 216 } 217 218 $state = sanitize_text_field( $_GET['state'] ); 219 220 $api = API::get_instance(); 221 $api->set_session( $state ); 222 218 223 $tokens = $this->get_tokens_from_provider( 219 224 'authorization_code', 220 sanitize_text_field( $_GET['code'] ) 221 ); 225 sanitize_text_field( $_GET['code'] ), 226 $state 227 ); 228 229 $client_data = $api->get_client_meta(); 230 231 // If this is AMP, pair token to AMP client ID instead. 232 if ( isset( $client_data['amp_id_key'] ) ) { 233 delete_transient( wp_hash( $state ) ); 234 235 $this->save_tokens( $tokens, $client_data['amp_id_key'] ); 236 } 222 237 223 238 $redirect_uri = site_url(); 224 $client_data = API::get_user_cookie(); 225 226 if ( isset( $client_data->redirect_uri ) && ! empty( $client_data->redirect_uri ) ) { 227 $redirect_uri = $client_data->redirect_uri; 228 } 239 240 if ( isset( $client_data['redirect_uri'] ) && ! empty( $client_data['redirect_uri'] ) ) { 241 $redirect_uri = $client_data['redirect_uri']; 242 } 243 244 $api->delete_client_meta(); 229 245 230 246 wp_safe_redirect( $redirect_uri ); … … 237 253 * @param string $grant_type Grant type to use when obtaining a token. 238 254 * @param string $key A key to use with the flow (auth code or refresh token). 255 * @param string $state OAuth state. 239 256 * 240 257 * @return AccessToken|boolean Token class instance. Boolean on failure. 241 258 */ 242 public function get_tokens_from_provider( $grant_type = 'refresh_token', $key = '' ) {259 public function get_tokens_from_provider( $grant_type = 'refresh_token', $key = '', $state = '' ) { 243 260 if ( empty( $key ) ) { 244 261 return false; … … 267 284 $tokens = $this->provider->getAccessToken( $grant_type, $params ); 268 285 269 $this->save_tokens( $tokens );286 $this->save_tokens( $tokens, $state ); 270 287 271 288 return $tokens; … … 281 298 * 282 299 * @param AccessToken $tokens AccessToken instance. 300 * @param string $state OAuth state. 283 301 * 284 302 * @return string Access token. 285 303 */ 286 public function save_tokens( AccessToken $tokens ) {304 public function save_tokens( AccessToken $tokens, $state ) { 287 305 $this->token = $tokens->getToken(); 288 $encoded_tokens = $this->encode_tokens( $tokens ); 289 290 if ( isset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ) ) { 291 unset( $_COOKIE[ self::TOKEN_COOKIE_NAME ] ); 292 } 293 294 if ( ! headers_sent() ) { 295 setcookie( 296 self::TOKEN_COOKIE_NAME, 297 $encoded_tokens, 298 [ 299 'path' => '/', 300 'httponly' => true, 301 'secure' => is_ssl(), 302 'samesite' => true, 303 'expires' => time() + 720 * HOUR_IN_SECONDS, 304 ] 305 ); 306 } 306 $encoded_tokens = $this->encode_tokens( $tokens, $state ); 307 308 delete_transient( wp_hash( $state ) ); 309 set_transient( wp_hash( $state ), $encoded_tokens, 1 * MONTH_IN_SECONDS ); 307 310 308 311 return $this->token; … … 313 316 * 314 317 * @param AccessToken $tokens AccessToken instance. 315 * 316 * @return string JWT token. 317 */ 318 private function encode_tokens( AccessToken $tokens ) { 318 * @param string $key Key to encode tokens with. 319 * 320 * @return mixed JWT token on success, FALSE on failure. 321 */ 322 private function encode_tokens( AccessToken $tokens, $key = '' ) { 323 if ( empty( $key ) ) { 324 return false; 325 } 326 319 327 $payload = [ 320 328 'access' => $tokens->getToken(), … … 323 331 ]; 324 332 325 $jwt = JWT::encode( $payload, $ this->key );333 $jwt = JWT::encode( $payload, $key ); 326 334 327 335 return $jwt; … … 332 340 * 333 341 * @param string $jwt String to decode. 342 * @param string $key Key to decode token with. 334 343 * 335 344 * @return JSON|WP_Error JSON object on success. WP_Error object on failure. 336 345 */ 337 private function decode_tokens( $jwt = '' ) {346 private function decode_tokens( $jwt = '', $key = '' ) { 338 347 if ( empty( $jwt ) ) { 339 348 return new \WP_Error( 'empty_jwt', 'JWT parameter cannot be empty to decode it.' ); 340 349 } 341 350 351 if ( empty( $key ) ) { 352 return new \WP_Error( 'empty_key', 'Key needs to be provided to decode JWT token.' ); 353 } 354 342 355 try { 343 $decoded = JWT::decode( $jwt, $ this->key, [ 'HS256' ] );356 $decoded = JWT::decode( $jwt, $key, [ 'HS256' ] ); 344 357 345 358 return $decoded; … … 551 564 */ 552 565 public function get_auth_code_url() { 553 return $this->provider->getAuthorizationUrl(); 566 $url = $this->provider->getAuthorizationUrl(); 567 568 return $url; 569 } 570 571 /** 572 * Get state from the authorization code flow URL. 573 * 574 * @param string $url URL to get the state from. 575 * 576 * @return string 577 */ 578 public function get_state_from_auth_url( $url = '' ) { 579 if ( empty( $url ) ) { 580 return ''; 581 } 582 583 $parsed_url = parse_url( $url ); 584 parse_str( $parsed_url['query'], $query_params ); 585 586 if ( ! isset( $query_params['state'] ) ) { 587 return ''; 588 } 589 590 return sanitize_text_field( $query_params['state'] ); 554 591 } 555 592 -
revenue-generator/trunk/v2/inc/classes/class-api.php
r2466307 r2468562 34 34 35 35 /** 36 * Name of the cookie to store temporary data on client.37 *38 * @const string39 */40 const CLIENT_COOKIE_NAME = 'rgv2_data';41 42 /**43 * Name of the cookie with full tab ID info.44 *45 * @const string46 */47 const FULL_TAB_COOKIE_NAME = 'rgv2_full_tab_id';48 49 /**50 36 * Auth instance. 51 37 * … … 53 39 */ 54 40 public static $auth = null; 41 42 /** 43 * Session key to manage meta. 44 * 45 * @var string 46 */ 47 public $session_key = ''; 48 49 /** 50 * Hashed session key. 51 * 52 * @var string 53 */ 54 private $hashed_key = ''; 55 55 56 56 /** … … 239 239 240 240 /** 241 * Get value of user cookie used when user needs to leave the site 242 * to go through the auth process. Used to store redirect URI and amount 243 * to contribute here. 244 * 245 * @return mixed Empty array on failure. JSON object on success. 246 */ 247 public static function get_user_cookie() { 248 $data = []; 249 250 if ( ! isset( $_COOKIE[ static::CLIENT_COOKIE_NAME ] ) ) { 251 return $data; 252 } 253 254 $data = $_COOKIE[ static::CLIENT_COOKIE_NAME ]; // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 255 $data = json_decode( stripslashes( $data ) ); 256 257 return $data; 258 } 259 260 /** 261 * Return user cookie parameters. 262 * 263 * @return array 264 */ 265 private static function get_user_cookie_params() { 266 return [ 267 'path' => '/', 268 'secure' => is_ssl(), 269 ]; 270 } 271 272 /** 273 * Sets data to user cookie. Unsets the cookie first if it was previously set. 274 * 275 * @param array $data Data to be set. 241 * Set session key. 242 * 243 * @param string $session_key Session key to set. 244 */ 245 public function set_session( $session_key = '' ) { 246 $this->session_key = $session_key; 247 $this->hashed_key = wp_hash( $this->session_key ); 248 } 249 250 /** 251 * Set client meta in database. 252 * 253 * @param string $data Data to be stored. 254 * @param string $type Type of meta. Default: `meta`. 255 * @param int $expiration The expiration after which data will be deleted. 276 256 * 277 257 * @return void 278 258 */ 279 public static function set_user_cookie( $data = [] ) { 280 static::unset_user_cookie(); 281 282 setcookie( 283 static::CLIENT_COOKIE_NAME, 284 json_encode( $data ), 285 static::get_user_cookie_params() 286 ); 287 } 288 289 /** 290 * Unsets user cookie. 291 */ 292 public static function unset_user_cookie() { 293 setcookie( 294 static::CLIENT_COOKIE_NAME, 295 '', 296 static::get_user_cookie_params() 297 ); 298 } 299 300 /** 301 * Sets cookie with full tab ID. 302 * 303 * @param string $value Tab ID. 259 public function set_client_meta( $data = '', $type = 'meta', $expiration = 5 * MINUTE_IN_SECONDS ) { 260 $transient_key = "{$this->hashed_key}_{$type}"; 261 262 set_transient( $transient_key, $data, $expiration ); 263 } 264 265 /** 266 * Get client meta from the database. 267 * 268 * @param string $type Type of meta. Default: `meta`. 269 * 270 * @return mixed 271 */ 272 public function get_client_meta( $type = 'meta' ) { 273 $transient_key = "{$this->hashed_key}_{$type}"; 274 275 return get_transient( $transient_key ); 276 } 277 278 /** 279 * Delete client meta from the database. 280 * 281 * @param string $type Type of meta to be deleted. Default: `meta`. 304 282 * 305 283 * @return void 306 284 */ 307 public static function set_full_tab_cookie( $value = '' ) { 308 $params = static::get_user_cookie_params(); 309 $params['httponly'] = true; 310 311 setcookie( 312 static::FULL_TAB_COOKIE_NAME, 313 $value, 314 $params 315 ); 316 } 317 318 /** 319 * Get value of full tab cookie. 320 * 321 * @return string 322 */ 323 public static function get_full_tab_cookie() { 324 $value = ''; 325 326 if ( ! isset( $_COOKIE[ static::FULL_TAB_COOKIE_NAME ] ) ) { 327 return $value; 328 } 329 330 $value = sanitize_text_field( $_COOKIE[ static::FULL_TAB_COOKIE_NAME ] ); 331 332 return $value; 333 } 334 335 /** 336 * Unsets cookie with full tab ID. 337 */ 338 public static function unset_full_tab_cookie() { 339 static::set_full_tab_cookie( '' ); 285 public function delete_client_meta( $type = 'meta' ) { 286 $transient_key = "{$this->hashed_key}_{$type}"; 287 288 delete_transient( $transient_key ); 340 289 } 341 290 -
revenue-generator/trunk/v2/inc/classes/class-frontend-post.php
r2466307 r2468562 36 36 * @const string 37 37 */ 38 const TAB_WIDGET_SCRIPT_URL = 'https://assets. sbx.laterpay.net/pcpro-jsx-components-frontend/main.js';38 const TAB_WIDGET_SCRIPT_URL = 'https://assets.laterpay.net/pcpro-jsx-components-frontend/main.js'; 39 39 40 40 /** … … 72 72 */ 73 73 const MYTAB_SBX_URL = 'https://mytab.sbx.laterpay.net'; 74 75 /**76 * Tab data cookie name for AMP context.77 *78 * @const string79 */80 const AMP_TAB_DATA_COOKIE_NAME = 'amp_lp_tab_data';81 74 82 75 /** … … 131 124 add_action( 'parse_request', [ $this, 'handle_payment_iframe_redirect' ] ); 132 125 add_action( 'parse_request', [ $this, 'handle_purchase_iframe_display' ] ); 126 add_action( 'parse_request', [ $this, 'handle_json_amp_url' ] ); 127 add_action( 'wp_print_footer_scripts', [ $this, 'print_amp_script' ] ); 128 add_action( 'wp_head', [ $this, 'add_amp_script_hash' ] ); 133 129 } 134 130 … … 187 183 $is_amp = ( isset( $_REQUEST['is_amp'] ) && 1 === (int) $_REQUEST['is_amp'] ); 188 184 $layout_type = ( isset( $_REQUEST['layout_type'] ) ) ? sanitize_text_field( $_REQUEST['layout_type'] ) : ''; 185 $key = ( isset( $_REQUEST['rg_key'] ) ) ? sanitize_text_field( $_REQUEST['rg_key'] ) : ''; 189 186 $redirect_uri = ( isset( $_REQUEST['redirect_uri'] ) ) ? esc_url( $_REQUEST['redirect_uri'] ) : ''; // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 190 187 … … 210 207 $api = API::get_instance(); 211 208 209 // If session key is present, set it to API instance. 210 if ( ! empty( $key ) ) { 211 $api->set_session( $key ); 212 } 213 212 214 /** 213 215 * If user is not authorized, return auth flow URL for them in the response … … 215 217 */ 216 218 if ( ! $api->is_user_authorized() ) { 217 /** 218 * Set data to store in the cookie so we can redirect user and 219 * continue their flow. 220 */ 219 // Reset session if in AMP context as we want to pair data to AMP client ID instead. 220 if ( $is_amp ) { 221 $api->set_session( '' ); 222 223 $amp_id_key = ''; 224 225 if ( $is_amp ) { 226 $amp_id_key = $key; 227 } 228 } 229 230 $auth_url = $api::$auth->get_auth_code_url(); 231 $state = $api::$auth->get_state_from_auth_url( $auth_url ); 232 233 $api->set_session( $state ); 234 235 $redirect_uri = $redirect_uri; 236 237 // Set specific AMP redirect URI to redirect back to AMP context. 238 if ( $is_amp ) { 239 $redirect_uri = add_query_arg( 240 [ 241 'amp' => 1, 242 'session' => $state, 243 ], 244 $redirect_uri 245 ); 246 } 247 221 248 $client_data = [ 222 249 'redirect_uri' => $redirect_uri, 223 'contribution' => [224 'amount' => number_format( $amount, 2 ),225 'item_id' => $item_id,226 ],227 250 ]; 228 251 229 // Store data to a cookie. 230 API::set_user_cookie( $client_data ); 252 // Add reference to AMP client ID to client meta for future linking. 253 if ( $is_amp ) { 254 $client_data['amp_id_key'] = $amp_id_key; 255 } 256 257 $api->set_client_meta( $client_data ); 258 259 if ( $is_amp ) { 260 header( 'AMP-Redirect-To: ' . $auth_url ); 261 header( 'Access-Control-Expose-Headers: AMP-Redirect-To' ); 262 } 231 263 232 264 // Send JSON response with auth code flow URL and 401 code. … … 234 266 [ 235 267 'data' => [ 236 'auth_url' => $api::$auth->get_auth_code_url(), 268 'auth_url' => $auth_url, 269 'session_key' => $api->session_key, 270 'handover' => [ 271 'contribution' => [ 272 'amount' => number_format( $amount, 2 ), 273 'item_id' => $item_id, 274 ], 275 ], 237 276 ], 238 277 ], … … 277 316 278 317 if ( $is_amp ) { 279 setcookie( 280 static::AMP_TAB_DATA_COOKIE_NAME, 281 json_encode( $tab_data ), 282 [ 283 'path' => '/', 284 'secure' => is_ssl(), 285 ] 286 ); 318 $api->set_client_meta( $tab_data, 'amp_payment' ); 287 319 } 288 320 … … 310 342 ); 311 343 312 API::unset_user_cookie();313 314 344 wp_send_json( 315 345 $response, … … 325 355 */ 326 356 case 402: 327 $credentials = $api::$auth->get_credentials();328 329 // Set cookie with full tab ID to use when redirecting.330 $api::set_full_tab_cookie( $response['data']['tab']['id'] );331 332 357 $iframe_url = static::get_payment_iframe_url(); 333 334 358 $iframe_url = add_query_arg( 335 359 [ 336 'layout_type' => $layout_type, 360 'key' => $key, 361 'v' => time(), 337 362 ], 338 363 $iframe_url 339 364 ); 365 366 $meta = [ 367 'tab_id' => $tab_data['id'], 368 'layout_type' => $layout_type, 369 ]; 370 371 // Store full tab ID and layout type in payment meta. 372 $api->set_client_meta( $meta, 'payment' ); 340 373 341 374 $response['data']['payment_required'] = true; … … 347 380 ); 348 381 349 API::unset_user_cookie();350 351 382 wp_send_json( 352 383 $response, … … 413 444 414 445 /** 415 * Get iframe URL for purchase component display (AMP).416 *417 * @return string418 */419 public static function get_purchase_iframe_url() {420 $url = site_url();421 $url = add_query_arg( 'laterpay', 'purchase', $url );422 423 return $url;424 }425 426 /**427 446 * Intercept request. When `?laterpay` is present and set to `payment`, 428 447 * make a call to payment component and render it before WP theme initializes. … … 439 458 } 440 459 441 $layout_type = ''; 442 443 if ( isset( $_GET['layout_type'] ) ) { 444 $layout_type = sanitize_text_field( $_GET['layout_type'] ); 445 } 446 447 $api = API::get_instance(); 448 $tab_id = $api::get_full_tab_cookie(); 460 if ( ! isset( $_GET['key'] ) ) { 461 return; 462 } 463 464 $key = sanitize_text_field( $_GET['key'] ); 465 466 if ( empty( $key ) ) { 467 return; 468 } 469 470 $api = API::get_instance(); 471 $api->set_session( $key ); 472 473 // Get full tab ID and layout type previously set to client meta. 474 $payment_data = $api->get_client_meta( 'payment' ); 449 475 450 476 $req = wp_remote_get( … … 453 479 'headers' => [ 454 480 'x-lp-access-token' => $api::$auth->get_access_token(), 455 'x-lp-tab-id' => $ tab_id,456 'x-lp-amp' => ( function_exists( 'is_amp' ) && is_amp() ),457 'x-lp-theme' => $ layout_type,481 'x-lp-tab-id' => $payment_data['tab_id'], 482 'x-lp-amp' => ( isset( $_GET['amp'] ) ), 483 'x-lp-theme' => $payment_data['layout_type'], 458 484 ], 459 485 ] … … 462 488 $res = wp_remote_retrieve_body( $req ); 463 489 490 header( 'Access-Control-Allow-Origin: ' . site_url() ); 464 491 header( 'Content-Type: text/html; charset=UTF-8' ); 465 492 466 493 echo $res; // phpcs:ignore -- WordPress.Security.EscapeOutput.OutputNotEscaped 494 495 // Clean up. Delete client meta and payment meta. 496 $api->delete_client_meta(); 497 $api->delete_client_meta( 'payment' ); 467 498 468 499 exit(); … … 482 513 return; 483 514 } 515 516 if ( ! isset( $_GET['key'] ) ) { 517 return; 518 } 519 520 $key = sanitize_text_field( $_GET['key'] ); 521 522 $api = API::get_instance(); 523 $api->set_session( $key ); 524 525 $amp_meta = $api->get_client_meta( 'amp_payment' ); 484 526 485 527 $api = API::get_instance(); … … 491 533 ]; 492 534 493 if ( isset( $_COOKIE[ static::AMP_TAB_DATA_COOKIE_NAME ] ) ) { 494 $tab_data = wp_parse_args( 495 json_decode( 496 stripslashes( $_COOKIE[ static::AMP_TAB_DATA_COOKIE_NAME ] ) // phpcs:ignore -- WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 497 ), 498 $tab_data 499 ); 500 } 535 $tab_data = wp_parse_args( $amp_meta, $tab_data ); 501 536 502 537 // Data to use in the template. … … 515 550 } 516 551 552 /** 553 * Outputs simple URL where we'll listen to and intercept the request 554 * to render a JSON. 555 * 556 * @param string $type Type of the JSON to echo. 557 * 558 * @return string 559 */ 560 public static function get_json_amp_url( $type = '' ) { 561 if ( empty( $type ) ) { 562 return; 563 } 564 565 $url = add_query_arg( 566 [ 567 'laterpay' => 'json', 568 'type' => $type, 569 ], 570 site_url() 571 ); 572 573 return $url; 574 } 575 576 /** 577 * Intercept the request and output JSON with the URL to either purchase 578 * or payment component for AMP purposes. 579 * 580 * AMP implementation uses `<amp-list>` to grab values of this JSON and 581 * then dynamically renders `<iframe>` with `src` coming from this JSON. 582 * This allows us to render iframe with the URL queries we need and 583 * overcome the limitation of `<amp-iframe>` alone which does not allow 584 * for dynamic attributes by default. 585 * 586 * @return string 587 */ 588 public function handle_json_amp_url() { 589 if ( ! isset( $_GET['laterpay'] ) ) { 590 return; 591 } 592 593 if ( 'json' !== sanitize_text_field( $_GET['laterpay'] ) ) { 594 return; 595 } 596 597 if ( ! isset( $_GET['type'] ) ) { 598 return; 599 } 600 601 if ( ! isset( $_GET['key'] ) ) { 602 return; 603 } 604 605 $type = sanitize_text_field( $_GET['type'] ); 606 $key = sanitize_text_field( $_GET['key'] ); 607 608 header( 'Content-type: application/json' ); 609 610 $url = self::get_payment_iframe_url(); 611 612 $url = add_query_arg( 613 [ 614 'key' => $key, 615 'amp' => 1, 616 ], 617 $url 618 ); 619 620 $json = json_encode( 621 [ 622 'items' => [ 623 [ 624 'url' => $url, 625 ], 626 ], 627 ] 628 ); 629 630 echo $json; // phpcs:ignore -- WordPress.Security.EscapeOutput.OutputNotEscaped -- output is formed in this method so no need to further escape 631 632 exit(); 633 } 634 635 /** 636 * Print AMP purchase component script if in AMP context. 637 * 638 * @hooked action `wp_print_footer_scripts` 639 */ 640 public function print_amp_script() { 641 if ( ! function_exists( 'is_amp_endpoint' ) || ! is_amp_endpoint() ) { 642 return; 643 } 644 645 include REVENUE_GENERATOR_PLUGIN_DIR . '/v2/templates/frontend/contribution/amp-purchase-component.php'; 646 } 647 648 /** 649 * Print AMP purchase component script hash to wp_head if 650 * in AMP context. 651 * 652 * @hooked action `wp_head` 653 */ 654 public function add_amp_script_hash() { 655 if ( ! function_exists( 'is_amp_endpoint' ) || ! is_amp_endpoint() ) { 656 return; 657 } 658 ?> 659 <meta name="amp-script-src" content="sha384-Xcsn0uFdGgT5Rk2GgmeML-rKQU6kfiRtPfrouuTo0sjizpodOzkcwzV8uBn2zyo9"> 660 <?php 661 } 662 517 663 } -
revenue-generator/trunk/v2/templates/frontend/contribution/partial-amounts.php
r2466307 r2468562 13 13 global $wp; 14 14 ?> 15 16 <?php 17 /** 18 * The following bit is added so that AMP compiled CSS include 19 * the purchase component styles which is not yet available 20 * in DOM at the time of render. 21 */ 22 ?> 23 <?php if ( $is_amp ) : ?> 24 <div class="tab_widget__container tab_widget__arc-container tab_widget__arc--background tab_widget__arc--filled tab_widget__donated-amount-text tab_widget__thank-you-message tab_widget__links-container tab_widget__link tab_widget__links-separator tab_widget__container-hidden tab_widget__container-visible tab_widget__regular-text tab_widget tab_widget__arc-animation lp__root lp__tab-widget-data tab__widget__info-button__container tab__widget__info-button tab__widget__info-button-question-mark tab__widget__close-button-x-mark tab_widget__container__info-screen infoContainer title steps step stepText stepNumber description tab__widget__icon" style="display: none;"></div> 25 <?php endif; ?> 26 15 27 <div class="rev-gen-contribution__donate" id="<?php echo esc_attr( $html_id ); ?>_donate"> 16 28 <form class="rev-gen-contribution__form" action="<?php echo esc_url( admin_url() ); ?>admin-ajax.php" method="POST" id="<?php echo esc_attr( $html_id ); ?>_donate-form" action-xhr="<?php echo esc_url( admin_url() ); ?>admin-ajax.php" data-tab-widget-url="<?php echo esc_url( Frontend_Post::get_tab_widget_script_url() ); ?>" on="submit:AMP.setState({ submitted: 1, submitting: 1 })"> … … 18 30 <div submit-success> 19 31 <span on="tap:<?php echo esc_attr( $html_id ); ?>_info-modal.show" class="rev-gen-contribution__amp-show-modal"></span> 20 <iframe src="<?php echo esc_url( Frontend_Post::get_purchase_iframe_url() ); ?>" height="105"></iframe> 32 <template type="amp-mustache"> 33 <amp-script layout="fixed" height="105" width="330" script="revenue-generator-amp-purchase-component"> 34 <div class="lp__root"> 35 <div class="lp__tab-widget-data" 36 data-tab-amount="{{ data.tab.total }}" 37 data-tab-currency="USD" 38 data-tab-limit="{{ data.tab.limit }}" 39 data-view-tab-url="https://mytab.laterpay.net"></div> 40 </div> 41 </amp-script> 42 </template> 21 43 </div> 22 44 <div submit-error> 23 45 <span on="tap:<?php echo esc_attr( $html_id ); ?>_info-modal.show" class="rev-gen-contribution__amp-show-modal--purchase"></span> 24 <iframe src="<?php echo esc_url( Frontend_Post::get_payment_iframe_url() ); ?>" height="250"></iframe> 46 <amp-list width="auto" height="250" src="<?php echo esc_url( Frontend_Post::get_json_amp_url( 'payment' ) ); ?>&key=CLIENT_ID(uid)" max-items="1"> 47 <template type="amp-mustache"> 48 <iframe src="{{url}}" sandbox="allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-scripts allow-top-navigation-by-user-activation" width="100%" height="250" allowpaymentrequest></iframe> 49 </template> 50 </amp-list> 25 51 </div> 26 52 <?php endif; ?> … … 31 57 <input type="hidden" name="action" value="<?php echo esc_attr( Frontend_Post::CONTRIBUTION_AJAX_ACTION ); ?>"> 32 58 <?php if ( $is_amp ) : ?> 59 <input type="hidden" name="rg_key" value="CLIENT_ID(uid)" data-amp-replace="CLIENT_ID"> 33 60 <input type="hidden" name="is_amp" value="1"> 34 61 <?php endif; ?> -
revenue-generator/trunk/vendor/autoload.php
r2466307 r2468562 5 5 require_once __DIR__ . '/composer/autoload_real.php'; 6 6 7 return ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b::getLoader();7 return ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045::getLoader(); -
revenue-generator/trunk/vendor/composer/InstalledVersions.php
r2466307 r2468562 25 25 'root' => 26 26 array ( 27 'pretty_version' => '2.0. 0',28 'version' => '2.0. 0.0',27 'pretty_version' => '2.0.1', 28 'version' => '2.0.1.0', 29 29 'aliases' => 30 30 array ( … … 73 73 'laterpay/revenue-generator' => 74 74 array ( 75 'pretty_version' => '2.0. 0',76 'version' => '2.0. 0.0',75 'pretty_version' => '2.0.1', 76 'version' => '2.0.1.0', 77 77 'aliases' => 78 78 array ( -
revenue-generator/trunk/vendor/composer/autoload_real.php
r2466307 r2468562 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b5 class ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 29 spl_autoload_unregister(array('ComposerAutoloaderInit 1f8be73ed8b3d6b4c601375036a77c9b', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInit0180107ac78f1fe5f7e96ac594582045', 'loadClassLoader')); 30 30 31 31 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); … … 33 33 require __DIR__ . '/autoload_static.php'; 34 34 35 call_user_func(\Composer\Autoload\ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::getInitializer($loader));35 call_user_func(\Composer\Autoload\ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::getInitializer($loader)); 36 36 } else { 37 37 $map = require __DIR__ . '/autoload_namespaces.php'; … … 54 54 55 55 if ($useStaticLoader) { 56 $includeFiles = Composer\Autoload\ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$files;56 $includeFiles = Composer\Autoload\ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$files; 57 57 } else { 58 58 $includeFiles = require __DIR__ . '/autoload_files.php'; 59 59 } 60 60 foreach ($includeFiles as $fileIdentifier => $file) { 61 composerRequire 1f8be73ed8b3d6b4c601375036a77c9b($fileIdentifier, $file);61 composerRequire0180107ac78f1fe5f7e96ac594582045($fileIdentifier, $file); 62 62 } 63 63 … … 66 66 } 67 67 68 function composerRequire 1f8be73ed8b3d6b4c601375036a77c9b($fileIdentifier, $file)68 function composerRequire0180107ac78f1fe5f7e96ac594582045($fileIdentifier, $file) 69 69 { 70 70 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { -
revenue-generator/trunk/vendor/composer/autoload_static.php
r2466307 r2468562 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b7 class ComposerStaticInit0180107ac78f1fe5f7e96ac594582045 8 8 { 9 9 public static $files = array ( … … 198 198 { 199 199 return \Closure::bind(function () use ($loader) { 200 $loader->prefixLengthsPsr4 = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$prefixLengthsPsr4;201 $loader->prefixDirsPsr4 = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$prefixDirsPsr4;202 $loader->classMap = ComposerStaticInit 1f8be73ed8b3d6b4c601375036a77c9b::$classMap;200 $loader->prefixLengthsPsr4 = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$prefixLengthsPsr4; 201 $loader->prefixDirsPsr4 = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$prefixDirsPsr4; 202 $loader->classMap = ComposerStaticInit0180107ac78f1fe5f7e96ac594582045::$classMap; 203 203 204 204 }, null, ClassLoader::class); -
revenue-generator/trunk/vendor/composer/installed.php
r2466307 r2468562 2 2 'root' => 3 3 array ( 4 'pretty_version' => '2.0. 0',5 'version' => '2.0. 0.0',4 'pretty_version' => '2.0.1', 5 'version' => '2.0.1.0', 6 6 'aliases' => 7 7 array ( … … 50 50 'laterpay/revenue-generator' => 51 51 array ( 52 'pretty_version' => '2.0. 0',53 'version' => '2.0. 0.0',52 'pretty_version' => '2.0.1', 53 'version' => '2.0.1.0', 54 54 'aliases' => 55 55 array (
Note: See TracChangeset
for help on using the changeset viewer.