Social Media Feather | social media sharing - Version 2.1.0

Version Description

  • New settings interface.
  • Sanitize everything!
Download this release

Release Info

Developer socialmediafeather
Plugin Icon 128x128 Social Media Feather | social media sharing
Version 2.1.0
Comparing to
See all releases

Code changes from version 2.0.6 to 2.1.0

Files changed (38) hide show
  1. build/index.asset.php +1 -0
  2. build/index.css +2 -0
  3. build/index.js +2 -0
  4. build/index.js.LICENSE.txt +20 -0
  5. build/loader.js +1 -0
  6. instance.php +28 -0
  7. php/class-plugin-base.php +290 -0
  8. php/class-plugin.php +48 -0
  9. php/class-socialmediafeather.php +926 -0
  10. readme.txt +10 -3
  11. social-media-feather.php +47 -35
  12. synved-connect/synved-connect-key.php +17 -8
  13. synved-connect/synved-connect-sponsor.php +177 -161
  14. synved-connect/synved-connect-support.php +32 -23
  15. synved-connect/synved-connect.php +74 -52
  16. synved-option/addons/option-type-addon/option-type-addon.php +6 -206
  17. synved-option/addons/option-type-addon/script/custom.js +0 -235
  18. synved-option/inc/SynvedOptionCallback.php +0 -76
  19. synved-option/inc/class-synvedoptioncallback.php +133 -0
  20. synved-option/script/custom.js +21 -16
  21. synved-option/synved-option-item.php +456 -468
  22. synved-option/synved-option-page.php +39 -83
  23. synved-option/synved-option-render.php +179 -209
  24. synved-option/synved-option-section.php +30 -10
  25. synved-option/synved-option-setting.php +43 -23
  26. synved-option/synved-option.php +647 -730
  27. synved-plugout/synved-plugout-core.php +254 -193
  28. synved-plugout/synved-plugout.php +23 -21
  29. synved-social/addons/extra-icons/extra-icons.php +42 -38
  30. synved-social/inc/SynvedSocialFollowWidget.php +0 -34
  31. synved-social/inc/SynvedSocialShareWidget.php +0 -34
  32. synved-social/inc/SynvedSocialWidget.php +0 -144
  33. synved-social/inc/class-synvedsocialfollowwidget.php +46 -0
  34. synved-social/inc/class-synvedsocialsharewidget.php +44 -0
  35. synved-social/inc/class-synvedsocialwidget.php +209 -0
  36. synved-social/synved-social-setup.php +645 -400
  37. synved-social/synved-social.php +510 -471
  38. uninstall.php +9 -7
build/index.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '264f4e87735938f654a0ad056ae3c2b0');
build/index.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ @charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,:after,:before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent;background-color:var(--bs-body-bg);color:var(--bs-body-color);font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);margin:0;text-align:var(--bs-body-text-align)}hr{background-color:currentColor;border:0;color:inherit;margin:1rem 0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:500;line-height:1.2;margin-bottom:.5rem;margin-top:0}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-bottom:1rem;margin-top:0}abbr[data-bs-original-title],abbr[title]{cursor:help;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit;margin-bottom:1rem}ol,ul{padding-left:2rem}dl,ol,ul{margin-bottom:1rem;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{background-color:#fcf8e3;padding:.2em}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{direction:ltr;font-family:var(--bs-font-monospace);font-size:1em;unicode-bidi:bidi-override}pre{display:block;font-size:.875em;margin-bottom:1rem;margin-top:0;overflow:auto}pre code{color:inherit;font-size:inherit;word-break:normal}code{word-wrap:break-word;color:#d63384;font-size:.875em}a>code{color:inherit}kbd{background-color:#212529;border-radius:.2rem;color:#fff;font-size:.875em;padding:.2rem .4rem}kbd kbd{font-size:1em;font-weight:700;padding:0}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{border-collapse:collapse;caption-side:bottom}caption{color:#6c757d;padding-bottom:.5rem;padding-top:.5rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{border-style:none;padding:0}textarea{resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{float:left;font-size:calc(1.275rem + .3vw);line-height:inherit;margin-bottom:.5rem;padding:0;width:100%}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}output{display:inline-block}iframe{border:0}summary{cursor:pointer;display:list-item}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{color:#6c757d;font-size:.875em;margin-bottom:1rem;margin-top:-1rem}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:#6c757d;font-size:.875em}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{margin-left:auto;margin-right:auto;padding-left:var(--bs-gutter-x,.75rem);padding-right:var(--bs-gutter-x,.75rem);width:100%}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-left:calc(var(--bs-gutter-x)*-.5);margin-right:calc(var(--bs-gutter-x)*-.5);margin-top:calc(var(--bs-gutter-y)*-1)}.row>*{flex-shrink:0;margin-top:var(--bs-gutter-y);max-width:100%;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0,0,0,.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0,0,0,.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0,0,0,.075);border-color:#dee2e6;color:#212529;margin-bottom:1rem;vertical-align:top;width:100%}.table>:not(caption)>*>*{background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg);padding:.5rem}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;border-color:#bacbe6;color:#000}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;border-color:#cbccce;color:#000}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;border-color:#bcd0c7;color:#000}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;border-color:#badce3;color:#000}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;border-color:#e6dbb9;color:#000}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;border-color:#dfc2c4;color:#000}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;border-color:#dfe0e1;color:#000}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;border-color:#373b3e;color:#fff}.table-responsive{-webkit-overflow-scrolling:touch;overflow-x:auto}@media (max-width:575.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:767.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:991.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:1199.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:1399.98px){.table-responsive-xxl{-webkit-overflow-scrolling:touch;overflow-x:auto}}.form-label{margin-bottom:.5rem}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.col-form-label-lg{font-size:1.25rem;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.col-form-label-sm{font-size:.875rem;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.form-text{color:#6c757d;font-size:.875em;margin-top:.25rem}.form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-clip:padding-box;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;color:#212529;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{background-color:#fff;border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);color:#212529;outline:0}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{-webkit-margin-end:.75rem;background-color:#e9ecef;border:0 solid;border-color:inherit;border-inline-end-width:1px;border-radius:0;color:#212529;margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{-webkit-margin-end:.75rem;background-color:#e9ecef;border:0 solid;border-color:inherit;border-inline-end-width:1px;border-radius:0;color:#212529;margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:1px 0;color:#212529;display:block;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:.2rem;font-size:.875rem;min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem}.form-control-sm::file-selector-button{-webkit-margin-end:.5rem;margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-control-sm::-webkit-file-upload-button{-webkit-margin-end:.5rem;margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-control-lg{border-radius:.3rem;font-size:1.25rem;min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem}.form-control-lg::file-selector-button{-webkit-margin-end:1rem;margin:-.5rem -1rem;margin-inline-end:1rem;padding:.5rem 1rem}.form-control-lg::-webkit-file-upload-button{-webkit-margin-end:1rem;margin:-.5rem -1rem;margin-inline-end:1rem;padding:.5rem 1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{height:auto;padding:.375rem;width:3rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border-radius:.25rem;height:1.5em}.form-control-color::-webkit-color-swatch{border-radius:.25rem;height:1.5em}.form-select{-moz-padding-start:calc(.75rem - 3px);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath fill=%27none%27 stroke=%27%23343a40%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%272%27 d=%27m2 5 6 6 6-6%27/%3E%3C/svg%3E");background-position:right .75rem center;background-repeat:no-repeat;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;color:#212529;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem 2.25rem .375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-select[multiple],.form-select[size]:not([size="1"]){background-image:none;padding-right:.75rem}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{border-radius:.2rem;font-size:.875rem;padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.form-select-lg{border-radius:.3rem;font-size:1.25rem;padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.form-check{display:block;margin-bottom:.125rem;min-height:1.5rem;padding-left:1.5em}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{-webkit-print-color-adjust:exact;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-position:50%;background-repeat:no-repeat;background-size:contain;border:1px solid rgba(0,0,0,.25);color-adjust:exact;height:1em;margin-top:.25em;vertical-align:top;width:1em}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3E%3Cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27m6 10 3 3 6-6%27/%3E%3C/svg%3E")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3E%3Ccircle r=%272%27 fill=%27%23fff%27/%3E%3C/svg%3E")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3E%3Cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3E%3C/svg%3E");border-color:#0d6efd}.form-check-input:disabled{filter:none;opacity:.5;pointer-events:none}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3E%3Ccircle r=%273%27 fill=%27rgba%280, 0, 0, 0.25%29%27/%3E%3C/svg%3E");background-position:0;border-radius:2em;margin-left:-2.5em;transition:background-position .15s ease-in-out;width:2em}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3E%3Ccircle r=%273%27 fill=%27%2386b7fe%27/%3E%3C/svg%3E")}.form-switch .form-check-input:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3E%3Ccircle r=%273%27 fill=%27%23fff%27/%3E%3C/svg%3E");background-position:100%}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{filter:none;opacity:.65;pointer-events:none}.form-range{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;height:1.5rem;padding:0;width:100%}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{background-color:#dee2e6;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range::-moz-range-thumb{-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{background-color:#dee2e6;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{border:1px solid transparent;height:100%;left:0;padding:1rem .75rem;pointer-events:none;position:absolute;top:0;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control:-ms-input-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control:not(:-ms-input-placeholder){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control:-webkit-autofill{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-select{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:not(:-ms-input-placeholder)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.form-control,.input-group>.form-select{flex:1 1 auto;min-width:0;position:relative;width:1%}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{align-items:center;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem;color:#212529;display:flex;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{border-radius:.3rem;font-size:1.25rem;padding:.5rem 1rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{border-radius:.2rem;font-size:.875rem;padding:.25rem .5rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-bottom-right-radius:0;border-top-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.valid-feedback{color:#198754;display:none;font-size:.875em;margin-top:.25rem;width:100%}.valid-tooltip{background-color:rgba(25,135,84,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3E%3Cpath fill=%27%23198754%27 d=%27M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#198754;padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath fill=%27none%27 stroke=%27%23343a40%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%272%27 d=%27m2 5 6 6 6-6%27/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3E%3Cpath fill=%27%23198754%27 d=%27M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{color:#dc3545;display:none;font-size:.875em;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:rgba(220,53,69,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23dc3545%27%3E%3Ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3E%3Cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3E%3Ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23dc3545%27 stroke=%27none%27/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath fill=%27none%27 stroke=%27%23343a40%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%272%27 d=%27m2 5 6 6 6-6%27/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23dc3545%27%3E%3Ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3E%3Cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3E%3Ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23dc3545%27 stroke=%27none%27/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;color:#212529;cursor:pointer;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.btn.disabled,.btn:disabled,fieldset:disabled .btn{opacity:.65;pointer-events:none}.btn-primary{background-color:#0d6efd;border-color:#0d6efd;color:#fff}.btn-check:focus+.btn-primary,.btn-primary:focus,.btn-primary:hover{background-color:#0b5ed7;border-color:#0a58ca;color:#fff}.btn-check:focus+.btn-primary,.btn-primary:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{background-color:#0a58ca;border-color:#0a53be;color:#fff}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{background-color:#0d6efd;border-color:#0d6efd;color:#fff}.btn-secondary{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-check:focus+.btn-secondary,.btn-secondary:focus,.btn-secondary:hover{background-color:#5c636a;border-color:#565e64;color:#fff}.btn-check:focus+.btn-secondary,.btn-secondary:focus{box-shadow:0 0 0 .25rem hsla(208,6%,54%,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{background-color:#565e64;border-color:#51585e;color:#fff}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem hsla(208,6%,54%,.5)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-success{background-color:#198754;border-color:#198754;color:#fff}.btn-check:focus+.btn-success,.btn-success:focus,.btn-success:hover{background-color:#157347;border-color:#146c43;color:#fff}.btn-check:focus+.btn-success,.btn-success:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{background-color:#146c43;border-color:#13653f;color:#fff}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{background-color:#198754;border-color:#198754;color:#fff}.btn-info{background-color:#0dcaf0;border-color:#0dcaf0;color:#000}.btn-check:focus+.btn-info,.btn-info:focus,.btn-info:hover{background-color:#31d2f2;border-color:#25cff2;color:#000}.btn-check:focus+.btn-info,.btn-info:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{background-color:#3dd5f3;border-color:#25cff2;color:#000}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{background-color:#0dcaf0;border-color:#0dcaf0;color:#000}.btn-warning{background-color:#ffc107;border-color:#ffc107;color:#000}.btn-check:focus+.btn-warning,.btn-warning:focus,.btn-warning:hover{background-color:#ffca2c;border-color:#ffc720;color:#000}.btn-check:focus+.btn-warning,.btn-warning:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{background-color:#ffcd39;border-color:#ffc720;color:#000}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{background-color:#ffc107;border-color:#ffc107;color:#000}.btn-danger{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-check:focus+.btn-danger,.btn-danger:focus,.btn-danger:hover{background-color:#bb2d3b;border-color:#b02a37;color:#fff}.btn-check:focus+.btn-danger,.btn-danger:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{background-color:#b02a37;border-color:#a52834;color:#fff}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-light{background-color:#f8f9fa;border-color:#f8f9fa;color:#000}.btn-check:focus+.btn-light,.btn-light:focus,.btn-light:hover{background-color:#f9fafb;border-color:#f9fafb;color:#000}.btn-check:focus+.btn-light,.btn-light:focus{box-shadow:0 0 0 .25rem hsla(210,2%,83%,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{background-color:#f9fafb;border-color:#f9fafb;color:#000}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem hsla(210,2%,83%,.5)}.btn-light.disabled,.btn-light:disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#000}.btn-dark{background-color:#212529;border-color:#212529;color:#fff}.btn-check:focus+.btn-dark,.btn-dark:focus,.btn-dark:hover{background-color:#1c1f23;border-color:#1a1e21;color:#fff}.btn-check:focus+.btn-dark,.btn-dark:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{background-color:#1a1e21;border-color:#191c1f;color:#fff}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{background-color:#212529;border-color:#212529;color:#fff}.btn-outline-primary{border-color:#0d6efd;color:#0d6efd}.btn-outline-primary:hover{background-color:#0d6efd;border-color:#0d6efd;color:#fff}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{background-color:#0d6efd;border-color:#0d6efd;color:#fff}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{background-color:transparent;color:#0d6efd}.btn-outline-secondary{border-color:#6c757d;color:#6c757d}.btn-outline-secondary:hover{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem hsla(208,7%,46%,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem hsla(208,7%,46%,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{background-color:transparent;color:#6c757d}.btn-outline-success{border-color:#198754;color:#198754}.btn-outline-success:hover{background-color:#198754;border-color:#198754;color:#fff}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{background-color:#198754;border-color:#198754;color:#fff}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{background-color:transparent;color:#198754}.btn-outline-info{border-color:#0dcaf0;color:#0dcaf0}.btn-outline-info:hover{background-color:#0dcaf0;border-color:#0dcaf0;color:#000}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{background-color:#0dcaf0;border-color:#0dcaf0;color:#000}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{background-color:transparent;color:#0dcaf0}.btn-outline-warning{border-color:#ffc107;color:#ffc107}.btn-outline-warning:hover{background-color:#ffc107;border-color:#ffc107;color:#000}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{background-color:#ffc107;border-color:#ffc107;color:#000}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{background-color:transparent;color:#ffc107}.btn-outline-danger{border-color:#dc3545;color:#dc3545}.btn-outline-danger:hover{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{background-color:transparent;color:#dc3545}.btn-outline-light{border-color:#f8f9fa;color:#f8f9fa}.btn-outline-light:hover{background-color:#f8f9fa;border-color:#f8f9fa;color:#000}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{background-color:#f8f9fa;border-color:#f8f9fa;color:#000}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{background-color:transparent;color:#f8f9fa}.btn-outline-dark{border-color:#212529;color:#212529}.btn-outline-dark:hover{background-color:#212529;border-color:#212529;color:#fff}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{background-color:#212529;border-color:#212529;color:#fff}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{background-color:transparent;color:#212529}.btn-link{color:#0d6efd;font-weight:400;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{border-radius:.3rem;font-size:1.25rem;padding:.5rem 1rem}.btn-group-sm>.btn,.btn-sm{border-radius:.2rem;font-size:.875rem;padding:.25rem .5rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{height:auto;transition:width .35s ease;width:0}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;color:#212529;display:none;font-size:1rem;list-style:none;margin:0;min-width:10rem;padding:.5rem 0;position:absolute;text-align:left;z-index:1000}.dropdown-menu[data-bs-popper]{left:0;margin-top:.125rem;top:100%}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{left:auto;right:0}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{left:auto;right:0}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{left:auto;right:0}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{left:auto;right:0}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{left:auto;right:0}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{left:auto;right:0}}.dropup .dropdown-menu[data-bs-popper]{bottom:100%;margin-bottom:.125rem;margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{left:100%;margin-left:.125rem;margin-top:0;right:auto;top:0}.dropend .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropend .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-toggle:after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{left:auto;margin-right:.125rem;margin-top:0;right:100%;top:0}.dropstart .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:empty:after{margin-left:0}.dropstart .dropdown-toggle:before{vertical-align:0}.dropdown-divider{border-top:1px solid rgba(0,0,0,.15);height:0;margin:.5rem 0;overflow:hidden}.dropdown-item{background-color:transparent;border:0;clear:both;color:#212529;display:block;font-weight:400;padding:.25rem 1rem;text-align:inherit;text-decoration:none;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:#e9ecef;color:#1e2125}.dropdown-item.active,.dropdown-item:active{background-color:#0d6efd;color:#fff;text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:#adb5bd;pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:#6c757d;display:block;font-size:.875rem;margin-bottom:0;padding:.5rem 1rem;white-space:nowrap}.dropdown-item-text{color:#212529;display:block;padding:.25rem 1rem}.dropdown-menu-dark{background-color:#343a40;border-color:rgba(0,0,0,.15);color:#dee2e6}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{background-color:hsla(0,0%,100%,.15);color:#fff}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{background-color:#0d6efd;color:#fff}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropend .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropstart .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{color:#0d6efd;display:block;padding:.5rem 1rem;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:#0a58ca}.nav-link.disabled{color:#6c757d;cursor:default;pointer-events:none}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem;margin-bottom:-1px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{background-color:transparent;border-color:transparent;color:#6c757d}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:#fff;border-color:#dee2e6 #dee2e6 #fff;color:#495057}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:#0d6efd;color:#fff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;padding-bottom:.5rem;padding-top:.5rem;position:relative}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{align-items:center;display:flex;flex-wrap:inherit;justify-content:space-between}.navbar-brand{font-size:1.25rem;margin-right:1rem;padding-bottom:.3125rem;padding-top:.3125rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link{padding-left:0;padding-right:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-bottom:.5rem;padding-top:.5rem}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:1px solid transparent;border-radius:.25rem;font-size:1.25rem;line-height:1;padding:.25rem .75rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{box-shadow:0 0 0 .25rem;outline:0;text-decoration:none}.navbar-toggler-icon{background-position:50%;background-repeat:no-repeat;background-size:100%;display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler,.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand-sm .offcanvas-bottom,.navbar-expand-sm .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler,.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand-md .offcanvas-bottom,.navbar-expand-md .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler,.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand-lg .offcanvas-bottom,.navbar-expand-lg .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler,.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand-xl .offcanvas-bottom,.navbar-expand-xl .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler,.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand-xxl .offcanvas-bottom,.navbar-expand-xxl .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler,.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{background-color:transparent;border-left:0;border-right:0;bottom:0;flex-grow:1;position:inherit;transform:none;transition:none;visibility:visible!important;z-index:1000}.navbar-expand .offcanvas-bottom,.navbar-expand .offcanvas-top{border-bottom:0;border-top:0;height:auto}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{border-color:rgba(0,0,0,.1);color:rgba(0,0,0,.55)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3E%3Cpath stroke=%27rgba%280, 0, 0, 0.55%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{border-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.55)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3E%3Cpath stroke=%27rgba%28255, 255, 255, 0.55%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{word-wrap:break-word;background-clip:border-box;background-color:#fff;border:1px solid rgba(0,0,0,.125);border-radius:.25rem;display:flex;flex-direction:column;min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px);border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125);margin-bottom:0;padding:.5rem 1rem}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125);padding:.5rem 1rem}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{border-bottom:0;margin-bottom:-.5rem}.card-header-pills,.card-header-tabs{margin-left:-.5rem;margin-right:-.5rem}.card-img-overlay{border-radius:calc(.25rem - 1px);bottom:0;left:0;padding:1rem;position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{align-items:center;background-color:#fff;border:0;border-radius:0;color:#212529;display:flex;font-size:1rem;overflow-anchor:none;padding:1rem 1.25rem;position:relative;text-align:left;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease;width:100%}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){background-color:#e7f1ff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125);color:#0c63e4}.accordion-button:not(.collapsed):after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%230c63e4%27%3E%3Cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3E%3C/svg%3E");transform:rotate(-180deg)}.accordion-button:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23212529%27%3E%3Cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:1.25rem;content:"";flex-shrink:0;height:1.25rem;margin-left:auto;transition:transform .2s ease-in-out;width:1.25rem}@media (prefers-reduced-motion:reduce){.accordion-button:after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0;z-index:3}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-left:0;border-radius:0;border-right:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:1rem;padding:0}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{color:#6c757d;content:var(--bs-breadcrumb-divider,"/");float:left;padding-right:.5rem}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;list-style:none;padding-left:0}.page-link{background-color:#fff;border:1px solid #dee2e6;color:#0d6efd;display:block;position:relative;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{border-color:#dee2e6;z-index:2}.page-link:focus,.page-link:hover{background-color:#e9ecef;color:#0a58ca}.page-link:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0;z-index:3}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{background-color:#0d6efd;border-color:#0d6efd;color:#fff;z-index:3}.page-item.disabled .page-link{background-color:#fff;border-color:#dee2e6;color:#6c757d;pointer-events:none}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.pagination-lg .page-link{font-size:1.25rem;padding:.75rem 1.5rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.pagination-sm .page-link{font-size:.875rem;padding:.25rem .5rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.badge{border-radius:.25rem;color:#fff;display:inline-block;font-size:.75em;font-weight:700;line-height:1;padding:.35em .65em;text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{border:1px solid transparent;border-radius:.25rem;margin-bottom:1rem;padding:1rem;position:relative}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{padding:1.25rem 1rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{background-color:#cfe2ff;border-color:#b6d4fe;color:#084298}.alert-primary .alert-link{color:#06357a}.alert-secondary{background-color:#e2e3e5;border-color:#d3d6d8;color:#41464b}.alert-secondary .alert-link{color:#34383c}.alert-success{background-color:#d1e7dd;border-color:#badbcc;color:#0f5132}.alert-success .alert-link{color:#0c4128}.alert-info{background-color:#cff4fc;border-color:#b6effb;color:#055160}.alert-info .alert-link{color:#04414d}.alert-warning{background-color:#fff3cd;border-color:#ffecb5;color:#664d03}.alert-warning .alert-link{color:#523e02}.alert-danger{background-color:#f8d7da;border-color:#f5c2c7;color:#842029}.alert-danger .alert-link{color:#6a1a21}.alert-light{background-color:#fefefe;border-color:#fdfdfe;color:#636464}.alert-light .alert-link{color:#4f5050}.alert-dark{background-color:#d3d3d4;border-color:#bcbebf;color:#141619}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{background-color:#e9ecef;border-radius:.25rem;font-size:.75rem;height:1rem}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{background-color:#0d6efd;color:#fff;flex-direction:column;justify-content:center;text-align:center;transition:width .6s ease;white-space:nowrap}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{border-radius:.25rem;display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-numbered{counter-reset:section;list-style-type:none}.list-group-numbered>li:before{content:counters(section,".") ". ";counter-increment:section}.list-group-item-action{color:#495057;text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:#f8f9fa;color:#495057;text-decoration:none;z-index:1}.list-group-item-action:active{background-color:#e9ecef;color:#212529}.list-group-item{background-color:#fff;border:1px solid rgba(0,0,0,.125);color:#212529;display:block;padding:.5rem 1rem;position:relative;text-decoration:none}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:#fff;color:#6c757d;pointer-events:none}.list-group-item.active{background-color:#0d6efd;border-color:#0d6efd;color:#fff;z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:1px;margin-top:-1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{background-color:#cfe2ff;color:#084298}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{background-color:#bacbe6;color:#084298}.list-group-item-primary.list-group-item-action.active{background-color:#084298;border-color:#084298;color:#fff}.list-group-item-secondary{background-color:#e2e3e5;color:#41464b}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{background-color:#cbccce;color:#41464b}.list-group-item-secondary.list-group-item-action.active{background-color:#41464b;border-color:#41464b;color:#fff}.list-group-item-success{background-color:#d1e7dd;color:#0f5132}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{background-color:#bcd0c7;color:#0f5132}.list-group-item-success.list-group-item-action.active{background-color:#0f5132;border-color:#0f5132;color:#fff}.list-group-item-info{background-color:#cff4fc;color:#055160}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{background-color:#badce3;color:#055160}.list-group-item-info.list-group-item-action.active{background-color:#055160;border-color:#055160;color:#fff}.list-group-item-warning{background-color:#fff3cd;color:#664d03}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{background-color:#e6dbb9;color:#664d03}.list-group-item-warning.list-group-item-action.active{background-color:#664d03;border-color:#664d03;color:#fff}.list-group-item-danger{background-color:#f8d7da;color:#842029}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{background-color:#dfc2c4;color:#842029}.list-group-item-danger.list-group-item-action.active{background-color:#842029;border-color:#842029;color:#fff}.list-group-item-light{background-color:#fefefe;color:#636464}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{background-color:#e5e5e5;color:#636464}.list-group-item-light.list-group-item-action.active{background-color:#636464;border-color:#636464;color:#fff}.list-group-item-dark{background-color:#d3d3d4;color:#141619}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{background-color:#bebebf;color:#141619}.list-group-item-dark.list-group-item-action.active{background-color:#141619;border-color:#141619;color:#fff}.btn-close{background:transparent url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z%27/%3E%3C/svg%3E") 50%/1em auto no-repeat;border:0;border-radius:.25rem;box-sizing:content-box;color:#000;height:1em;opacity:.5;padding:.25em;width:1em}.btn-close:hover{color:#000;opacity:.75;text-decoration:none}.btn-close:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1;outline:0}.btn-close.disabled,.btn-close:disabled{opacity:.25;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border:1px solid rgba(0,0,0,.1);border-radius:.25rem;box-shadow:0 .5rem 1rem rgba(0,0,0,.15);font-size:.875rem;max-width:100%;pointer-events:auto;width:350px}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{max-width:100%;pointer-events:none;width:-webkit-max-content;width:-moz-max-content;width:max-content}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{align-items:center;background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);color:#6c757d;display:flex;padding:.5rem .75rem}.toast-header .btn-close{margin-left:.75rem;margin-right:-.375rem}.toast-body{word-wrap:break-word;padding:.75rem}.modal{display:none;height:100%;left:0;outline:0;overflow-x:hidden;overflow-y:auto;position:fixed;top:0;width:100%;z-index:1055}.modal-dialog{margin:.5rem;pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - 1rem)}.modal-content{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1050}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{align-items:center;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);display:flex;flex-shrink:0;justify-content:space-between;padding:1rem}.modal-header .btn-close{margin:-.5rem -.5rem -.5rem auto;padding:.5rem}.modal-title{line-height:1.5;margin-bottom:0}.modal-body{flex:1 1 auto;padding:1rem;position:relative}.modal-footer{align-items:center;border-bottom-left-radius:calc(.3rem - 1px);border-bottom-right-radius:calc(.3rem - 1px);border-top:1px solid #dee2e6;display:flex;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;padding:.75rem}.modal-footer>*{margin:.25rem}@media (min-width:576px){.modal-dialog{margin:1.75rem auto;max-width:500px}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-sm-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-md-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-lg-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xxl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{word-wrap:break-word;display:block;font-family:var(--bs-font-sans-serif);font-size:.875rem;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:0;opacity:0;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:1080}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{display:block;height:.4rem;position:absolute;width:.8rem}.tooltip .tooltip-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow:before,.bs-tooltip-top .tooltip-arrow:before{border-top-color:#000;border-width:.4rem .4rem 0;top:-1px}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{height:.8rem;left:0;width:.4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow:before,.bs-tooltip-end .tooltip-arrow:before{border-right-color:#000;border-width:.4rem .4rem .4rem 0;right:-1px}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow:before,.bs-tooltip-bottom .tooltip-arrow:before{border-bottom-color:#000;border-width:0 .4rem .4rem;bottom:-1px}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{height:.8rem;right:0;width:.4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow:before,.bs-tooltip-start .tooltip-arrow:before{border-left-color:#000;border-width:.4rem 0 .4rem .4rem;left:-1px}.tooltip-inner{background-color:#000;border-radius:.25rem;color:#fff;max-width:200px;padding:.25rem .5rem;text-align:center}.popover{word-wrap:break-word;background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;display:block;font-family:var(--bs-font-sans-serif);font-size:.875rem;font-style:normal;font-weight:400;left:0;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:276px;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;top:0;white-space:normal;word-break:normal;word-spacing:normal;z-index:1070}.popover .popover-arrow{display:block;height:.5rem;position:absolute;width:1rem}.popover .popover-arrow:after,.popover .popover-arrow:before{border-color:transparent;border-style:solid;content:"";display:block;position:absolute}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:before{border-top-color:rgba(0,0,0,.25);border-width:.5rem .5rem 0;bottom:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-top>.popover-arrow:after{border-top-color:#fff;border-width:.5rem .5rem 0;bottom:1px}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{height:1rem;left:calc(-.5rem - 1px);width:.5rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:before{border-right-color:rgba(0,0,0,.25);border-width:.5rem .5rem .5rem 0;left:0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-end>.popover-arrow:after{border-right-color:#fff;border-width:.5rem .5rem .5rem 0;left:1px}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:before{border-bottom-color:rgba(0,0,0,.25);border-width:0 .5rem .5rem;top:0}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:after{border-bottom-color:#fff;border-width:0 .5rem .5rem;top:1px}.bs-popover-auto[data-popper-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:1px solid #f0f0f0;content:"";display:block;left:50%;margin-left:-.5rem;position:absolute;top:0;width:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{height:1rem;right:calc(-.5rem - 1px);width:.5rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:before{border-left-color:rgba(0,0,0,.25);border-width:.5rem 0 .5rem .5rem;right:0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-start>.popover-arrow:after{border-left-color:#fff;border-width:.5rem 0 .5rem .5rem;right:1px}.popover-header{background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);font-size:1rem;margin-bottom:0;padding:.5rem 1rem}.popover-header:empty{display:none}.popover-body{color:#212529;padding:1rem}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{opacity:0;transition:opacity 0s .6s;z-index:0}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;background:0 0;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;display:inline-block;height:2rem;width:2rem}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3E%3Cpath d=%27M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z%27/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3E%3Cpath d=%27M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z%27/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-bottom:1rem;margin-left:15%;margin-right:15%;padding:0;position:absolute;right:0;z-index:2}.carousel-indicators [data-bs-target]{background-clip:padding-box;background-color:#fff;border:0;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;padding:0;text-indent:-999px;transition:opacity .6s ease;width:30px}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:1.25rem;color:#fff;left:15%;padding-bottom:1.25rem;padding-top:1.25rem;position:absolute;right:15%;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(1turn)}}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite;border:.25em solid;border-radius:50%;border-right:.25em solid transparent;display:inline-block;height:2rem;vertical-align:-.125em;width:2rem}.spinner-border-sm{border-width:.2em;height:1rem;width:1rem}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite;background-color:currentColor;border-radius:50%;display:inline-block;height:2rem;opacity:0;vertical-align:-.125em;width:2rem}.spinner-grow-sm{height:1rem;width:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.offcanvas{background-clip:padding-box;background-color:#fff;bottom:0;display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:1045}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{align-items:center;display:flex;justify-content:space-between;padding:1rem}.offcanvas-header .btn-close{margin-bottom:-.5rem;margin-right:-.5rem;margin-top:-.5rem;padding:.5rem}.offcanvas-title{line-height:1.5;margin-bottom:0}.offcanvas-body{flex-grow:1;overflow-y:auto;padding:1rem}.offcanvas-start{border-right:1px solid rgba(0,0,0,.2);left:0;top:0;transform:translateX(-100%);width:400px}.offcanvas-end{border-left:1px solid rgba(0,0,0,.2);right:0;top:0;transform:translateX(100%);width:400px}.offcanvas-top{border-bottom:1px solid rgba(0,0,0,.2);top:0;transform:translateY(-100%)}.offcanvas-bottom,.offcanvas-top{height:30vh;left:0;max-height:100%;right:0}.offcanvas-bottom{border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{background-color:currentColor;cursor:wait;display:inline-block;min-height:1em;opacity:.5;vertical-align:middle}.placeholder.btn:before{content:"";display:inline-block}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite;-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%}@-webkit-keyframes placeholder-wave{to{-webkit-mask-position:-200% 0;mask-position:-200% 0}}@keyframes placeholder-wave{to{-webkit-mask-position:-200% 0;mask-position:-200% 0}}.clearfix:after{clear:both;content:"";display:block}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio:before{content:"";display:block;padding-top:var(--bs-aspect-ratio)}.ratio>*{height:100%;left:0;position:absolute;top:0;width:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.hstack{align-items:center;flex-direction:row}.hstack,.vstack{-ms-grid-row-align:stretch;align-self:stretch;display:flex}.vstack{flex:1 1 auto;flex-direction:column}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.stretched-link:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{-ms-grid-row-align:stretch;align-self:stretch;background-color:currentColor;display:inline-block;min-height:1em;opacity:.25;width:1px}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:-ms-grid!important;display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-left:0!important;margin-right:0!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-3{margin-left:1rem!important;margin-right:1rem!important}.mx-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-5{margin-left:3rem!important;margin-right:3rem!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-0{margin-bottom:0!important;margin-top:0!important}.my-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-left:0!important;padding-right:0!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}.px-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-5{padding-left:3rem!important;padding-right:3rem!important}.py-0{padding-bottom:0!important;padding-top:0!important}.py-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:hsla(0,0%,100%,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-end,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-end{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-start{border-bottom-left-radius:.25rem!important}.rounded-start{border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:-ms-grid!important;display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-left:0!important;margin-right:0!important}.mx-sm-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-sm-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-sm-3{margin-left:1rem!important;margin-right:1rem!important}.mx-sm-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-sm-5{margin-left:3rem!important;margin-right:3rem!important}.mx-sm-auto{margin-left:auto!important;margin-right:auto!important}.my-sm-0{margin-bottom:0!important;margin-top:0!important}.my-sm-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-sm-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-sm-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-sm-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-sm-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-sm-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-left:0!important;padding-right:0!important}.px-sm-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-sm-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-sm-3{padding-left:1rem!important;padding-right:1rem!important}.px-sm-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-sm-5{padding-left:3rem!important;padding-right:3rem!important}.py-sm-0{padding-bottom:0!important;padding-top:0!important}.py-sm-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-sm-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-sm-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-sm-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-sm-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:-ms-grid!important;display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-left:0!important;margin-right:0!important}.mx-md-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-md-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-md-3{margin-left:1rem!important;margin-right:1rem!important}.mx-md-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-md-5{margin-left:3rem!important;margin-right:3rem!important}.mx-md-auto{margin-left:auto!important;margin-right:auto!important}.my-md-0{margin-bottom:0!important;margin-top:0!important}.my-md-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-md-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-md-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-md-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-md-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-md-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-left:0!important;padding-right:0!important}.px-md-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-md-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-md-3{padding-left:1rem!important;padding-right:1rem!important}.px-md-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-md-5{padding-left:3rem!important;padding-right:3rem!important}.py-md-0{padding-bottom:0!important;padding-top:0!important}.py-md-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-md-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-md-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-md-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-md-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:-ms-grid!important;display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-left:0!important;margin-right:0!important}.mx-lg-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-lg-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-lg-3{margin-left:1rem!important;margin-right:1rem!important}.mx-lg-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-lg-5{margin-left:3rem!important;margin-right:3rem!important}.mx-lg-auto{margin-left:auto!important;margin-right:auto!important}.my-lg-0{margin-bottom:0!important;margin-top:0!important}.my-lg-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-lg-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-lg-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-lg-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-lg-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-lg-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-left:0!important;padding-right:0!important}.px-lg-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-lg-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-lg-3{padding-left:1rem!important;padding-right:1rem!important}.px-lg-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-lg-5{padding-left:3rem!important;padding-right:3rem!important}.py-lg-0{padding-bottom:0!important;padding-top:0!important}.py-lg-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-lg-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-lg-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-lg-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-lg-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:-ms-grid!important;display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-left:0!important;margin-right:0!important}.mx-xl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xl-auto{margin-left:auto!important;margin-right:auto!important}.my-xl-0{margin-bottom:0!important;margin-top:0!important}.my-xl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-left:0!important;padding-right:0!important}.px-xl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xl-0{padding-bottom:0!important;padding-top:0!important}.py-xl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:-ms-grid!important;display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{-ms-grid-row-align:center!important;align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{-ms-grid-row-align:stretch!important;align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-left:0!important;margin-right:0!important}.mx-xxl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xxl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xxl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xxl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xxl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xxl-auto{margin-left:auto!important;margin-right:auto!important}.my-xxl-0{margin-bottom:0!important;margin-top:0!important}.my-xxl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xxl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xxl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xxl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xxl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xxl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-left:0!important;padding-right:0!important}.px-xxl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xxl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xxl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xxl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xxl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xxl-0{padding-bottom:0!important;padding-top:0!important}.py-xxl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xxl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xxl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xxl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xxl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:-ms-grid!important;display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}
2
+ .form-check .form-check-input{background-repeat:no-repeat;margin-top:.25em}.form-check .form-check-input:checked:before{content:none}.smf__form-check label{text-align:center}.smf__form-check label img{border:1px solid #ccc;display:block}.smf__form-check label input{float:none!important;margin:0 1em!important;text-align:center}.smf-review-us{background:#fff;border:1px solid #00b300;border-radius:10px;bottom:40px;padding:15px;position:fixed;right:10px;text-align:center;width:295px}.smf-review-us #close-review-us{cursor:pointer}.social-media-feather .nav-tabs li{margin-bottom:0!important}
build/index.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /*! For license information please see index.js.LICENSE.txt */
2
+ (self.webpackChunksocial_media_feather=self.webpackChunksocial_media_feather||[]).push([[826],{595:function(e,t,a){"use strict";var l=window.wp.element,n=window.ReactDOM,o=a.n(n),r=window.wp.domReady,i=a.n(r),s=a(196),c=a.n(s),u=window.wp.apiFetch,d=a.n(u),m=window.wp.i18n,p=window.lodash,f=a.n(p),h=a(184),b=a.n(h),_=a(893);const g=s.createContext({prefixes:{}}),{Consumer:y,Provider:v}=g;function w(e,t){const{prefixes:a}=(0,s.useContext)(g);return e||a[t]||t}const x=s.forwardRef((({bsPrefix:e,fluid:t,as:a="div",className:l,...n},o)=>{const r=w(e,"container"),i="string"==typeof t?`-${t}`:"-fluid";return(0,_.jsx)(a,{ref:o,...n,className:b()(l,t?`${r}${i}`:r)})}));x.displayName="Container",x.defaultProps={fluid:!1};var E=x,k=a(697),S=a.n(k);const N={type:S().string,tooltip:S().bool,as:S().elementType},C=s.forwardRef((({as:e="div",className:t,type:a="valid",tooltip:l=!1,...n},o)=>(0,_.jsx)(e,{...n,ref:o,className:b()(t,`${a}-${l?"tooltip":"feedback"}`)})));C.displayName="Feedback",C.propTypes=N;var F=C,T=s.createContext({});const P=s.forwardRef((({id:e,bsPrefix:t,className:a,type:l="checkbox",isValid:n=!1,isInvalid:o=!1,as:r="input",...i},c)=>{const{controlId:u}=(0,s.useContext)(T);return t=w(t,"form-check-input"),(0,_.jsx)(r,{...i,ref:c,type:l,id:e||u,className:b()(a,t,n&&"is-valid",o&&"is-invalid")})}));P.displayName="FormCheckInput";var M=P;const O=s.forwardRef((({bsPrefix:e,className:t,htmlFor:a,...l},n)=>{const{controlId:o}=(0,s.useContext)(T);return e=w(e,"form-check-label"),(0,_.jsx)("label",{...l,ref:n,htmlFor:a||o,className:b()(t,e)})}));O.displayName="FormCheckLabel";var j=O;function L(e,t){let a=0;return s.Children.map(e,(e=>s.isValidElement(e)?t(e,a++):e))}const I=s.forwardRef((({id:e,bsPrefix:t,bsSwitchPrefix:a,inline:l=!1,disabled:n=!1,isValid:o=!1,isInvalid:r=!1,feedbackTooltip:i=!1,feedback:c,feedbackType:u,className:d,style:m,title:p="",type:f="checkbox",label:h,children:g,as:y="input",...v},x)=>{t=w(t,"form-check"),a=w(a,"form-switch");const{controlId:E}=(0,s.useContext)(T),k=(0,s.useMemo)((()=>({controlId:e||E})),[E,e]),S=!g&&null!=h&&!1!==h||function(e,t){return s.Children.toArray(e).some((e=>s.isValidElement(e)&&e.type===t))}(g,j),N=(0,_.jsx)(M,{...v,type:"switch"===f?"checkbox":f,ref:x,isValid:o,isInvalid:r,disabled:n,as:y});return(0,_.jsx)(T.Provider,{value:k,children:(0,_.jsx)("div",{style:m,className:b()(d,S&&t,l&&`${t}-inline`,"switch"===f&&a),children:g||(0,_.jsxs)(_.Fragment,{children:[N,S&&(0,_.jsx)(j,{title:p,children:h}),c&&(0,_.jsx)(F,{type:u,tooltip:i,children:c})]})})})}));I.displayName="FormCheck";var R=Object.assign(I,{Input:M,Label:j});a(473);const $=s.forwardRef((({bsPrefix:e,type:t,size:a,htmlSize:l,id:n,className:o,isValid:r=!1,isInvalid:i=!1,plaintext:c,readOnly:u,as:d="input",...m},p)=>{const{controlId:f}=(0,s.useContext)(T);let h;return e=w(e,"form-control"),h=c?{[`${e}-plaintext`]:!0}:{[e]:!0,[`${e}-${a}`]:a},(0,_.jsx)(d,{...m,type:t,size:l,ref:p,readOnly:u,id:n||f,className:b()(o,h,r&&"is-valid",i&&"is-invalid","color"===t&&`${e}-color`)})}));$.displayName="FormControl";var A=Object.assign($,{Feedback:F}),D=/-(.)/g;const G=e=>{return e[0].toUpperCase()+(t=e,t.replace(D,(function(e,t){return t.toUpperCase()}))).slice(1);var t};function K(e,{displayName:t=G(e),Component:a,defaultProps:l}={}){const n=s.forwardRef((({className:t,bsPrefix:l,as:n=a||"div",...o},r)=>{const i=w(l,e);return(0,_.jsx)(n,{ref:r,className:b()(t,i),...o})}));return n.defaultProps=l,n.displayName=t,n}var B=K("form-floating");const U=s.forwardRef((({controlId:e,as:t="div",...a},l)=>{const n=(0,s.useMemo)((()=>({controlId:e})),[e]);return(0,_.jsx)(T.Provider,{value:n,children:(0,_.jsx)(t,{...a,ref:l})})}));U.displayName="FormGroup";var q=U;const W=["xxl","xl","lg","md","sm","xs"],z=s.forwardRef(((e,t)=>{const[{className:a,...l},{as:n="div",bsPrefix:o,spans:r}]=function({as:e,bsPrefix:t,className:a,...l}){t=w(t,"col");const n=[],o=[];return W.forEach((e=>{const a=l[e];let r,i,s;delete l[e],"object"==typeof a&&null!=a?({span:r,offset:i,order:s}=a):r=a;const c="xs"!==e?`-${e}`:"";r&&n.push(!0===r?`${t}${c}`:`${t}${c}-${r}`),null!=s&&o.push(`order${c}-${s}`),null!=i&&o.push(`offset${c}-${i}`)})),[{...l,className:b()(a,...n,...o)},{as:e,bsPrefix:t,spans:n}]}(e);return(0,_.jsx)(n,{...l,ref:t,className:b()(a,!r.length&&o)})}));z.displayName="Col";var V=z;const H=s.forwardRef((({as:e="label",bsPrefix:t,column:a,visuallyHidden:l,className:n,htmlFor:o,...r},i)=>{const{controlId:c}=(0,s.useContext)(T);t=w(t,"form-label");let u="col-form-label";"string"==typeof a&&(u=`${u} ${u}-${a}`);const d=b()(n,t,l&&"visually-hidden",a&&u);return o=o||c,a?(0,_.jsx)(V,{ref:i,as:"label",className:d,htmlFor:o,...r}):(0,_.jsx)(e,{ref:i,className:d,htmlFor:o,...r})}));H.displayName="FormLabel",H.defaultProps={column:!1,visuallyHidden:!1};var Y=H;const X=s.forwardRef((({bsPrefix:e,className:t,id:a,...l},n)=>{const{controlId:o}=(0,s.useContext)(T);return e=w(e,"form-range"),(0,_.jsx)("input",{...l,type:"range",ref:n,className:b()(t,e),id:a||o})}));X.displayName="FormRange";var Z=X;const J=s.forwardRef((({bsPrefix:e,size:t,htmlSize:a,className:l,isValid:n=!1,isInvalid:o=!1,id:r,...i},c)=>{const{controlId:u}=(0,s.useContext)(T);return e=w(e,"form-select"),(0,_.jsx)("select",{...i,size:a,ref:c,className:b()(l,e,t&&`${e}-${t}`,n&&"is-valid",o&&"is-invalid"),id:r||u})}));J.displayName="FormSelect";var Q=J;const ee=s.forwardRef((({bsPrefix:e,className:t,as:a="small",muted:l,...n},o)=>(e=w(e,"form-text"),(0,_.jsx)(a,{...n,ref:o,className:b()(t,e,l&&"text-muted")}))));ee.displayName="FormText";var te=ee;const ae=s.forwardRef(((e,t)=>(0,_.jsx)(R,{...e,ref:t,type:"switch"})));ae.displayName="Switch";var le=Object.assign(ae,{Input:R.Input,Label:R.Label});const ne=s.forwardRef((({bsPrefix:e,className:t,children:a,controlId:l,label:n,...o},r)=>(e=w(e,"form-floating"),(0,_.jsxs)(q,{ref:r,className:b()(t,e),controlId:l,...o,children:[a,(0,_.jsx)("label",{htmlFor:l,children:n})]}))));ne.displayName="FloatingLabel";var oe=ne;const re={_ref:S().any,validated:S().bool,as:S().elementType},ie=s.forwardRef((({className:e,validated:t,as:a="form",...l},n)=>(0,_.jsx)(a,{...l,ref:n,className:b()(e,t&&"was-validated")})));ie.displayName="Form",ie.propTypes=re;var se=Object.assign(ie,{Group:q,Control:A,Floating:B,Check:R,Switch:le,Label:Y,Text:te,Range:Z,Select:Q,FloatingLabel:oe});const ce=["xxl","xl","lg","md","sm","xs"],ue=s.forwardRef((({bsPrefix:e,className:t,as:a="div",...l},n)=>{const o=w(e,"row"),r=`${o}-cols`,i=[];return ce.forEach((e=>{const t=l[e];let a;delete l[e],null!=t&&"object"==typeof t?({cols:a}=t):a=t;const n="xs"!==e?`-${e}`:"";null!=a&&i.push(`${r}${n}-${a}`)})),(0,_.jsx)(a,{ref:n,...l,className:b()(t,o,...i)})}));ue.displayName="Row";var de=ue;function me(){return me=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var l in a)Object.prototype.hasOwnProperty.call(a,l)&&(e[l]=a[l])}return e},me.apply(this,arguments)}function pe(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}function fe(e){return"default"+e.charAt(0).toUpperCase()+e.substr(1)}function he(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var a=e[Symbol.toPrimitive];if(void 0!==a){var l=a.call(e,t);if("object"!=typeof l)return l;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:String(t)}function be(e,t,a){var l=(0,s.useRef)(void 0!==e),n=(0,s.useState)(t),o=n[0],r=n[1],i=void 0!==e,c=l.current;return l.current=i,!i&&c&&o!==t&&r(t),[i?e:o,(0,s.useCallback)((function(e){for(var t=arguments.length,l=new Array(t>1?t-1:0),n=1;n<t;n++)l[n-1]=arguments[n];a&&a.apply(void 0,[e].concat(l)),r(e)}),[a])]}function _e(e,t){return Object.keys(t).reduce((function(a,l){var n,o=a,r=o[fe(l)],i=o[l],s=pe(o,[fe(l),l].map(he)),c=t[l],u=be(i,r,e[c]),d=u[0],m=u[1];return me({},s,((n={})[l]=d,n[c]=m,n))}),e)}function ge(e,t,a,l){Object.defineProperty(e,t,{get:a,set:l,enumerable:!0,configurable:!0})}a(143);var ye={};ge(ye,"SSRProvider",(()=>xe)),ge(ye,"useSSRSafeId",(()=>ke)),ge(ye,"useIsSSR",(()=>Se));const ve={prefix:String(Math.round(1e10*Math.random())),current:0},we=c().createContext(ve);function xe(e){let t=(0,s.useContext)(we),a=(0,s.useMemo)((()=>({prefix:t===ve?"":`${t.prefix}-${++t.current}`,current:0})),[t]);return c().createElement(we.Provider,{value:a},e.children)}let Ee=Boolean("undefined"!=typeof window&&window.document&&window.document.createElement);function ke(e){let t=(0,s.useContext)(we);return t!==ve||Ee||console.warn("When server rendering, you must wrap your application in an <SSRProvider> to ensure consistent ids are generated between the client and server."),(0,s.useMemo)((()=>e||`react-aria${t.prefix}-${++t.current}`),[e])}function Se(){let e=(0,s.useContext)(we)!==ve,[t,a]=(0,s.useState)(e);return"undefined"!=typeof window&&e&&(0,s.useLayoutEffect)((()=>{a(!1)}),[]),t}var Ne=s.createContext(null);const Ce=(e,t=null)=>null!=e?String(e):t||null;var Fe=s.createContext(null),Te=function({children:e,in:t,mountOnEnter:a,unmountOnExit:l}){const n=(0,s.useRef)(t);return(0,s.useEffect)((()=>{t&&(n.current=!0)}),[t]),t?e:l||!n.current&&a?null:e};const Pe=["active","eventKey","mountOnEnter","transition","unmountOnExit","role"],Me=["activeKey","getControlledId","getControllerId"],Oe=["as"];function je(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}function Le(e){let{active:t,eventKey:a,mountOnEnter:l,transition:n,unmountOnExit:o,role:r="tabpanel"}=e,i=je(e,Pe);const c=(0,s.useContext)(Ne);if(!c)return[Object.assign({},i,{role:r}),{eventKey:a,isActive:t,mountOnEnter:l,transition:n,unmountOnExit:o}];const{activeKey:u,getControlledId:d,getControllerId:m}=c,p=je(c,Me),f=Ce(a);return[Object.assign({},i,{role:r,id:d(a),"aria-labelledby":m(a)}),{eventKey:a,isActive:null==t&&null!=f?Ce(u)===f:t,transition:n||p.transition,mountOnEnter:null!=l?l:p.mountOnEnter,unmountOnExit:null!=o?o:p.unmountOnExit}]}const Ie=s.forwardRef(((e,t)=>{let{as:a="div"}=e,l=je(e,Oe);const[n,{isActive:o,onEnter:r,onEntering:i,onEntered:s,onExit:c,onExiting:u,onExited:d,mountOnEnter:m,unmountOnExit:p,transition:f=Te}]=Le(l);return(0,_.jsx)(Ne.Provider,{value:null,children:(0,_.jsx)(Fe.Provider,{value:null,children:(0,_.jsx)(f,{in:o,onEnter:r,onEntering:i,onEntered:s,onExit:c,onExiting:u,onExited:d,mountOnEnter:m,unmountOnExit:p,children:(0,_.jsx)(a,Object.assign({},n,{ref:t,hidden:!o,"aria-hidden":!o}))})})})}));Ie.displayName="TabPanel";const Re=e=>{const{id:t,generateChildId:a,onSelect:l,activeKey:n,defaultActiveKey:o,transition:r,mountOnEnter:i,unmountOnExit:c,children:u}=e,[d,m]=be(n,o,l),p=ke(t),f=(0,s.useMemo)((()=>a||((e,t)=>p?`${p}-${t}-${e}`:null)),[p,a]),h=(0,s.useMemo)((()=>({onSelect:m,activeKey:d,transition:r,mountOnEnter:i||!1,unmountOnExit:c||!1,getControlledId:e=>f(e,"tabpane"),getControllerId:e=>f(e,"tab")})),[m,d,r,i,c,f]);return(0,_.jsx)(Ne.Provider,{value:h,children:(0,_.jsx)(Fe.Provider,{value:m||null,children:u})})};Re.Panel=Ie;var $e=Re,Ae=(a(391),Function.prototype.bind.call(Function.prototype.call,[].slice)),De=function(e){return e&&"function"!=typeof e?function(t){e.current=t}:e},Ge=function(e,t){return(0,s.useMemo)((function(){return function(e,t){var a=De(e),l=De(t);return function(e){a&&a(e),l&&l(e)}}(e,t)}),[e,t])};const Ke=s.createContext(null);Ke.displayName="NavContext";var Be=Ke;function Ue(e){return`data-rr-ui-${e}`}function qe(e){var t=function(e){var t=(0,s.useRef)(e);return(0,s.useEffect)((function(){t.current=e}),[e]),t}(e);return(0,s.useCallback)((function(){return t.current&&t.current.apply(t,arguments)}),[t])}const We=["as","disabled"];function ze({tagName:e,disabled:t,href:a,target:l,rel:n,onClick:o,tabIndex:r=0,type:i}){e||(e=null!=a||null!=l||null!=n?"a":"button");const s={tagName:e};if("button"===e)return[{type:i||"button",disabled:t},s];const c=l=>{(t||"a"===e&&function(e){return!e||"#"===e.trim()}(a))&&l.preventDefault(),t?l.stopPropagation():null==o||o(l)};return"a"===e&&(a||(a="#"),t&&(a=void 0)),[{role:"button",disabled:void 0,tabIndex:t?void 0:r,href:a,target:"a"===e?l:void 0,"aria-disabled":t||void 0,rel:"a"===e?n:void 0,onClick:c,onKeyDown:e=>{" "===e.key&&(e.preventDefault(),c(e))}},s]}const Ve=s.forwardRef(((e,t)=>{let{as:a,disabled:l}=e,n=function(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,We);const[o,{tagName:r}]=ze(Object.assign({tagName:a,disabled:l},n));return(0,_.jsx)(r,Object.assign({},n,o,{ref:t}))}));Ve.displayName="Button";var He=Ve;const Ye=["as","active","eventKey"];function Xe({key:e,onClick:t,active:a,id:l,role:n,disabled:o}){const r=(0,s.useContext)(Fe),i=(0,s.useContext)(Be);let c=a;const u={role:n};if(i){n||"tablist"!==i.role||(u.role="tab");const t=i.getControllerId(null!=e?e:null),o=i.getControlledId(null!=e?e:null);u[Ue("event-key")]=e,u.id=t||l,u["aria-controls"]=o,c=null==a&&null!=e?i.activeKey===e:a}return"tab"===u.role&&(o&&(u.tabIndex=-1,u["aria-disabled"]=!0),c?u["aria-selected"]=c:u.tabIndex=-1),u.onClick=qe((a=>{o||(null==t||t(a),null!=e&&r&&!a.isPropagationStopped()&&r(e,a))})),[u,{isActive:c}]}const Ze=s.forwardRef(((e,t)=>{let{as:a=He,active:l,eventKey:n}=e,o=function(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,Ye);const[r,i]=Xe(Object.assign({key:Ce(n,o.href),active:l},o));return r[Ue("active")]=i.isActive,(0,_.jsx)(a,Object.assign({},o,r,{ref:t}))}));Ze.displayName="NavItem";var Je=Ze;const Qe=["as","onSelect","activeKey","role","onKeyDown"],et=()=>{},tt=Ue("event-key"),at=s.forwardRef(((e,t)=>{let{as:a="div",onSelect:l,activeKey:n,role:o,onKeyDown:r}=e,i=function(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,Qe);const c=(0,s.useReducer)((function(e){return!e}),!1)[1],u=(0,s.useRef)(!1),d=(0,s.useContext)(Fe),m=(0,s.useContext)(Ne);let p,f;m&&(o=o||"tablist",n=m.activeKey,p=m.getControlledId,f=m.getControllerId);const h=(0,s.useRef)(null),b=e=>{const t=h.current;if(!t)return null;const a=(l=`[${tt}]:not([aria-disabled=true])`,Ae(t.querySelectorAll(l)));var l;const n=t.querySelector("[aria-selected=true]");if(!n)return null;const o=a.indexOf(n);if(-1===o)return null;let r=o+e;return r>=a.length&&(r=0),r<0&&(r=a.length-1),a[r]},g=(e,t)=>{null!=e&&(null==l||l(e,t),null==d||d(e,t))};(0,s.useEffect)((()=>{if(h.current&&u.current){const e=h.current.querySelector(`[${tt}][aria-selected=true]`);null==e||e.focus()}u.current=!1}));const y=Ge(t,h);return(0,_.jsx)(Fe.Provider,{value:g,children:(0,_.jsx)(Be.Provider,{value:{role:o,activeKey:Ce(n),getControlledId:p||et,getControllerId:f||et},children:(0,_.jsx)(a,Object.assign({},i,{onKeyDown:e=>{if(null==r||r(e),!m)return;let t;switch(e.key){case"ArrowLeft":case"ArrowUp":t=b(-1);break;case"ArrowRight":case"ArrowDown":t=b(1);break;default:return}t&&(e.preventDefault(),g(t.dataset[("EventKey","rrUiEventKey")]||null,e),u.current=!0,c())},ref:y,role:o}))})})}));at.displayName="Nav";var lt=Object.assign(at,{Item:Je});const nt=s.createContext(null);nt.displayName="NavbarContext";var ot=nt;const rt=s.createContext(null);rt.displayName="CardHeaderContext";var it=rt,st=K("nav-item"),ct=void 0!==a.g&&a.g.navigator&&"ReactNative"===a.g.navigator.product;"undefined"!=typeof document||ct?s.useLayoutEffect:s.useEffect,new WeakMap;const ut=["onKeyDown"],dt=s.forwardRef(((e,t)=>{let{onKeyDown:a}=e,l=function(e,t){if(null==e)return{};var a,l,n={},o=Object.keys(e);for(l=0;l<o.length;l++)a=o[l],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,ut);const[n]=ze(Object.assign({tagName:"a"},l)),o=qe((e=>{n.onKeyDown(e),null==a||a(e)}));return((r=l.href)&&"#"!==r.trim()||l.role)&&"button"!==l.role?(0,_.jsx)("a",Object.assign({ref:t},l,{onKeyDown:a})):(0,_.jsx)("a",Object.assign({ref:t},l,n,{onKeyDown:o}));var r}));dt.displayName="Anchor";var mt=dt;const pt=s.forwardRef((({bsPrefix:e,className:t,as:a=mt,active:l,eventKey:n,...o},r)=>{e=w(e,"nav-link");const[i,s]=Xe({key:Ce(n,o.href),active:l,...o});return(0,_.jsx)(a,{...o,...i,ref:r,className:b()(t,e,o.disabled&&"disabled",s.isActive&&"active")})}));pt.displayName="NavLink",pt.defaultProps={disabled:!1};var ft=pt;const ht=s.forwardRef(((e,t)=>{const{as:a="div",bsPrefix:l,variant:n,fill:o,justify:r,navbar:i,navbarScroll:c,className:u,activeKey:d,...m}=_e(e,{activeKey:"onSelect"}),p=w(l,"nav");let f,h,g=!1;const y=(0,s.useContext)(ot),v=(0,s.useContext)(it);return y?(f=y.bsPrefix,g=null==i||i):v&&({cardHeaderBsPrefix:h}=v),(0,_.jsx)(lt,{as:a,ref:t,activeKey:d,className:b()(u,{[p]:!g,[`${f}-nav`]:g,[`${f}-nav-scroll`]:g&&c,[`${h}-${n}`]:!!h,[`${p}-${n}`]:!!n,[`${p}-fill`]:o,[`${p}-justified`]:r}),...m})}));ht.displayName="Nav",ht.defaultProps={justify:!1,fill:!1};var bt=Object.assign(ht,{Item:st,Link:ft}),_t=K("tab-content");function gt(e,t){return gt=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},gt(e,t)}var yt=c().createContext(null),vt="unmounted",wt="exited",xt="entering",Et="entered",kt="exiting",St=function(e){var t,a;function l(t,a){var l;l=e.call(this,t,a)||this;var n,o=a&&!a.isMounting?t.enter:t.appear;return l.appearStatus=null,t.in?o?(n=wt,l.appearStatus=xt):n=Et:n=t.unmountOnExit||t.mountOnEnter?vt:wt,l.state={status:n},l.nextCallback=null,l}a=e,(t=l).prototype=Object.create(a.prototype),t.prototype.constructor=t,gt(t,a),l.getDerivedStateFromProps=function(e,t){return e.in&&t.status===vt?{status:wt}:null};var n=l.prototype;return n.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},n.componentDidUpdate=function(e){var t=null;if(e!==this.props){var a=this.state.status;this.props.in?a!==xt&&a!==Et&&(t=xt):a!==xt&&a!==Et||(t=kt)}this.updateStatus(!1,t)},n.componentWillUnmount=function(){this.cancelNextCallback()},n.getTimeouts=function(){var e,t,a,l=this.props.timeout;return e=t=a=l,null!=l&&"number"!=typeof l&&(e=l.exit,t=l.enter,a=void 0!==l.appear?l.appear:t),{exit:e,enter:t,appear:a}},n.updateStatus=function(e,t){void 0===e&&(e=!1),null!==t?(this.cancelNextCallback(),t===xt?this.performEnter(e):this.performExit()):this.props.unmountOnExit&&this.state.status===wt&&this.setState({status:vt})},n.performEnter=function(e){var t=this,a=this.props.enter,l=this.context?this.context.isMounting:e,n=this.props.nodeRef?[l]:[o().findDOMNode(this),l],r=n[0],i=n[1],s=this.getTimeouts(),c=l?s.appear:s.enter;e||a?(this.props.onEnter(r,i),this.safeSetState({status:xt},(function(){t.props.onEntering(r,i),t.onTransitionEnd(c,(function(){t.safeSetState({status:Et},(function(){t.props.onEntered(r,i)}))}))}))):this.safeSetState({status:Et},(function(){t.props.onEntered(r)}))},n.performExit=function(){var e=this,t=this.props.exit,a=this.getTimeouts(),l=this.props.nodeRef?void 0:o().findDOMNode(this);t?(this.props.onExit(l),this.safeSetState({status:kt},(function(){e.props.onExiting(l),e.onTransitionEnd(a.exit,(function(){e.safeSetState({status:wt},(function(){e.props.onExited(l)}))}))}))):this.safeSetState({status:wt},(function(){e.props.onExited(l)}))},n.cancelNextCallback=function(){null!==this.nextCallback&&(this.nextCallback.cancel(),this.nextCallback=null)},n.safeSetState=function(e,t){t=this.setNextCallback(t),this.setState(e,t)},n.setNextCallback=function(e){var t=this,a=!0;return this.nextCallback=function(l){a&&(a=!1,t.nextCallback=null,e(l))},this.nextCallback.cancel=function(){a=!1},this.nextCallback},n.onTransitionEnd=function(e,t){this.setNextCallback(t);var a=this.props.nodeRef?this.props.nodeRef.current:o().findDOMNode(this),l=null==e&&!this.props.addEndListener;if(a&&!l){if(this.props.addEndListener){var n=this.props.nodeRef?[this.nextCallback]:[a,this.nextCallback],r=n[0],i=n[1];this.props.addEndListener(r,i)}null!=e&&setTimeout(this.nextCallback,e)}else setTimeout(this.nextCallback,0)},n.render=function(){var e=this.state.status;if(e===vt)return null;var t=this.props,a=t.children,l=(t.in,t.mountOnEnter,t.unmountOnExit,t.appear,t.enter,t.exit,t.timeout,t.addEndListener,t.onEnter,t.onEntering,t.onEntered,t.onExit,t.onExiting,t.onExited,t.nodeRef,pe(t,["children","in","mountOnEnter","unmountOnExit","appear","enter","exit","timeout","addEndListener","onEnter","onEntering","onEntered","onExit","onExiting","onExited","nodeRef"]));return c().createElement(yt.Provider,{value:null},"function"==typeof a?a(e,l):c().cloneElement(c().Children.only(a),l))},l}(c().Component);function Nt(){}St.contextType=yt,St.propTypes={},St.defaultProps={in:!1,mountOnEnter:!1,unmountOnExit:!1,appear:!1,enter:!0,exit:!0,onEnter:Nt,onEntering:Nt,onEntered:Nt,onExit:Nt,onExiting:Nt,onExited:Nt},St.UNMOUNTED=vt,St.EXITED=wt,St.ENTERING=xt,St.ENTERED=Et,St.EXITING=kt;var Ct=St;var Ft=/([A-Z])/g,Tt=/^ms-/;function Pt(e){return function(e){return e.replace(Ft,"-$1").toLowerCase()}(e).replace(Tt,"-ms-")}var Mt=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,Ot=function(e,t){var a="",l="";if("string"==typeof t)return e.style.getPropertyValue(Pt(t))||function(e,t){return function(e){var t=function(e){return e&&e.ownerDocument||document}(e);return t&&t.defaultView||window}(e).getComputedStyle(e,void 0)}(e).getPropertyValue(Pt(t));Object.keys(t).forEach((function(n){var o=t[n];o||0===o?function(e){return!(!e||!Mt.test(e))}(n)?l+=n+"("+o+") ":a+=Pt(n)+": "+o+";":e.style.removeProperty(Pt(n))})),l&&(a+="transform: "+l+";"),e.style.cssText+=";"+a},jt=!("undefined"==typeof window||!window.document||!window.document.createElement),Lt=!1,It=!1;try{var Rt={get passive(){return Lt=!0},get once(){return It=Lt=!0}};jt&&(window.addEventListener("test",Rt,Rt),window.removeEventListener("test",Rt,!0))}catch(e){}var $t=function(e,t,a,l){return function(e,t,a,l){if(l&&"boolean"!=typeof l&&!It){var n=l.once,o=l.capture,r=a;!It&&n&&(r=a.__once||function e(l){this.removeEventListener(t,e,o),a.call(this,l)},a.__once=r),e.addEventListener(t,r,Lt?l:o)}e.addEventListener(t,a,l)}(e,t,a,l),function(){!function(e,t,a,l){var n=l&&"boolean"!=typeof l?l.capture:l;e.removeEventListener(t,a,n),a.__once&&e.removeEventListener(t,a.__once,n)}(e,t,a,l)}};function At(e,t,a,l){var n,o;null==a&&(o=-1===(n=Ot(e,"transitionDuration")||"").indexOf("ms")?1e3:1,a=parseFloat(n)*o||0);var r=function(e,t,a){void 0===a&&(a=5);var l=!1,n=setTimeout((function(){l||function(e,t,a,l){if(void 0===a&&(a=!1),void 0===l&&(l=!0),e){var n=document.createEvent("HTMLEvents");n.initEvent("transitionend",a,l),e.dispatchEvent(n)}}(e,0,!0)}),t+a),o=$t(e,"transitionend",(function(){l=!0}),{once:!0});return function(){clearTimeout(n),o()}}(e,a,l),i=$t(e,"transitionend",t);return function(){r(),i()}}function Dt(e,t){const a=Ot(e,t)||"",l=-1===a.indexOf("ms")?1e3:1;return parseFloat(a)*l}function Gt(e,t){const a=Dt(e,"transitionDuration"),l=Dt(e,"transitionDelay"),n=At(e,(a=>{a.target===e&&(n(),t(a))}),a+l)}var Kt=c().forwardRef((({onEnter:e,onEntering:t,onEntered:a,onExit:l,onExiting:n,onExited:r,addEndListener:i,children:u,childRef:d,...m},p)=>{const f=(0,s.useRef)(null),h=Ge(f,d),b=e=>{var t;h((t=e)&&"setState"in t?o().findDOMNode(t):null!=t?t:null)},g=e=>t=>{e&&f.current&&e(f.current,t)},y=(0,s.useCallback)(g(e),[e]),v=(0,s.useCallback)(g(t),[t]),w=(0,s.useCallback)(g(a),[a]),x=(0,s.useCallback)(g(l),[l]),E=(0,s.useCallback)(g(n),[n]),k=(0,s.useCallback)(g(r),[r]),S=(0,s.useCallback)(g(i),[i]);return(0,_.jsx)(Ct,{ref:p,...m,onEnter:y,onEntered:w,onEntering:v,onExit:x,onExited:k,onExiting:E,addEndListener:S,nodeRef:f,children:"function"==typeof u?(e,t)=>u(e,{...t,ref:b}):c().cloneElement(u,{ref:b})})}));const Bt={[xt]:"show",[Et]:"show"},Ut=s.forwardRef((({className:e,children:t,transitionClasses:a={},...l},n)=>{const o=(0,s.useCallback)(((e,t)=>{!function(e){e.offsetHeight}(e),null==l.onEnter||l.onEnter(e,t)}),[l]);return(0,_.jsx)(Kt,{ref:n,addEndListener:Gt,...l,onEnter:o,childRef:t.ref,children:(l,n)=>s.cloneElement(t,{...n,className:b()("fade",e,t.props.className,Bt[l],a[l])})})}));Ut.defaultProps={in:!1,timeout:300,mountOnEnter:!1,unmountOnExit:!1,appear:!1},Ut.displayName="Fade";var qt=Ut;function Wt(e){return"boolean"==typeof e?e?qt:void 0:e}const zt=s.forwardRef((({bsPrefix:e,transition:t,...a},l)=>{const[{className:n,as:o="div",...r},{isActive:i,onEnter:s,onEntering:c,onEntered:u,onExit:d,onExiting:m,onExited:p,mountOnEnter:f,unmountOnExit:h,transition:g=Te}]=Le({...a,transition:Wt(t)}),y=w(e,"tab-pane");return(0,_.jsx)(Ne.Provider,{value:null,children:(0,_.jsx)(Fe.Provider,{value:null,children:(0,_.jsx)(g,{in:i,onEnter:s,onEntering:c,onEntered:u,onExit:d,onExiting:m,onExited:p,mountOnEnter:f,unmountOnExit:h,children:(0,_.jsx)(o,{...r,ref:l,className:b()(n,y,i&&"active")})})})})}));zt.displayName="TabPane";var Vt=zt;function Ht(e){let t;return function(e,a){s.Children.forEach(e,(e=>{s.isValidElement(e)&&(e=>{null==t&&(t=e.props.eventKey)})(e)}))}(e),t}function Yt(e){const{title:t,eventKey:a,disabled:l,tabClassName:n,id:o}=e.props;return null==t?null:(0,_.jsx)(st,{as:"li",role:"presentation",children:(0,_.jsx)(ft,{as:"button",type:"button",eventKey:a,disabled:l,id:o,className:n,children:t})})}const Xt=e=>{const{id:t,onSelect:a,transition:l,mountOnEnter:n,unmountOnExit:o,children:r,activeKey:i=Ht(r),...s}=_e(e,{activeKey:"onSelect"});return(0,_.jsxs)($e,{id:t,activeKey:i,onSelect:a,transition:Wt(l),mountOnEnter:n,unmountOnExit:o,children:[(0,_.jsx)(bt,{...s,role:"tablist",as:"ul",children:L(r,Yt)}),(0,_.jsx)(_t,{children:L(r,(e=>{const t={...e.props};return delete t.title,delete t.disabled,delete t.tabClassName,(0,_.jsx)(Vt,{...t})}))})]})};Xt.defaultProps={variant:"tabs",mountOnEnter:!1,unmountOnExit:!1},Xt.displayName="Tabs";var Zt=Xt;const Jt=({transition:e,...t})=>(0,_.jsx)($e,{...t,transition:Wt(e)});Jt.displayName="TabContainer";var Qt=Jt;const ea={eventKey:S().oneOfType([S().string,S().number]),title:S().node.isRequired,disabled:S().bool,tabClassName:S().string},ta=()=>{throw new Error("ReactBootstrap: The `Tab` component is not meant to be rendered! It's an abstract component that is only valid as a direct Child of the `Tabs` Component. For custom tabs components use TabPane and TabsContainer directly")};ta.propTypes=ea;var aa=Object.assign(ta,{Container:Qt,Content:_t,Pane:Vt});S().string,S().bool,S().bool,S().bool,S().bool;const la=s.forwardRef((({bsPrefix:e,className:t,fluid:a,rounded:l,roundedCircle:n,thumbnail:o,...r},i)=>(e=w(e,"img"),(0,_.jsx)("img",{ref:i,...r,className:b()(t,a&&`${e}-fluid`,l&&"rounded",n&&"rounded-circle",o&&`${e}-thumbnail`)}))));la.displayName="Image",la.defaultProps={fluid:!1,rounded:!1,roundedCircle:!1,thumbnail:!1};var na=la;const oa=s.forwardRef((({as:e,bsPrefix:t,variant:a,size:l,active:n,className:o,...r},i)=>{const s=w(t,"btn"),[c,{tagName:u}]=ze({tagName:e,...r}),d=u;return(0,_.jsx)(d,{...c,...r,ref:i,className:b()(o,s,n&&"active",a&&`${s}-${a}`,l&&`${s}-${l}`,r.href&&r.disabled&&"disabled")})}));oa.displayName="Button",oa.defaultProps={variant:"primary",active:!1,disabled:!1};var ra=oa;const ia={accepted_sharethis_terms:!0===f().get(SocialMediaFeather.data,"accepted_sharethis_terms",!1),automatic_append_postfix:f().get(SocialMediaFeather.data,"automatic_append_postfix",""),automatic_append_prefix:f().get(SocialMediaFeather.data,"automatic_append_prefix",""),automatic_append_separator:f().get(SocialMediaFeather.data,"automatic_append_separator","<br />"),automatic_follow:!0===f().get(SocialMediaFeather.data,"automatic_follow",!0),automatic_follow_before_share:!0===f().get(SocialMediaFeather.data,"automatic_follow_before_share",!1),automatic_follow_position:f().get(SocialMediaFeather.data,"automatic_follow_position","after_post"),automatic_follow_postfix:f().get(SocialMediaFeather.data,"automatic_follow_postfix",""),automatic_follow_post_types:f().get(SocialMediaFeather.data,"automatic_follow_post_types",["post"]),automatic_follow_prefix:f().get(SocialMediaFeather.data,"automatic_follow_prefix",""),automatic_follow_single:f().get(SocialMediaFeather.data,"automatic_follow_single",!1),automatic_share:!0===f().get(SocialMediaFeather.data,"automatic_share",!1),automatic_share_prefix:f().get(SocialMediaFeather.data,"automatic_share_prefix",""),automatic_share_position:f().get(SocialMediaFeather.data,"automatic_share_position","after_post"),automatic_share_postfix:f().get(SocialMediaFeather.data,"automatic_share_postfix",""),automatic_share_post_types:f().get(SocialMediaFeather.data,"automatic_share_post_types",["post"]),automatic_share_single:!0===f().get(SocialMediaFeather.data,"automatic_share_single",!1),buttons_alignment_share:f().get(SocialMediaFeather.data,"buttons_alignment_share","none"),buttons_alignment_follow:f().get(SocialMediaFeather.data,"buttons_alignment_follow","none"),buttons_container:f().get(SocialMediaFeather.data,"buttons_container","none"),buttons_container_type:f().get(SocialMediaFeather.data,"buttons_container_type","basic"),custom_style:f().get(SocialMediaFeather.data,"custom_style",""),facebook_display:f().get(SocialMediaFeather.data,"facebook_display","both"),facebook_share_link:f().get(SocialMediaFeather.data,"facebook_share_link",""),facebook_share_title:f().get(SocialMediaFeather.data,"facebook_share_title",""),facebook_follow_link:f().get(SocialMediaFeather.data,"facebook_follow_link",""),facebook_follow_title:f().get(SocialMediaFeather.data,"facebook_follow_title",""),fb_app_id:f().get(SocialMediaFeather.data,"fb_app_id",""),flickr_display:f().get(SocialMediaFeather.data,"flickr_display","follow"),flickr_follow_link:f().get(SocialMediaFeather.data,"flickr_follow_link",""),flickr_follow_title:f().get(SocialMediaFeather.data,"flickr_follow_title",""),foursquare_display:f().get(SocialMediaFeather.data,"foursquare_display","follow"),foursquare_follow_link:f().get(SocialMediaFeather.data,"foursquare_follow_link",""),foursquare_follow_title:f().get(SocialMediaFeather.data,"foursquare_follow_title",""),hide_review:!0===f().get(SocialMediaFeather,"review",!1),icon_resolution:f().get(SocialMediaFeather.data,"icon_resolution","single"),icon_size:f().get(SocialMediaFeather.data,"icon_size","48"),icon_skin:f().get(SocialMediaFeather.data,"icon_skin","regular"),icon_spacing:f().get(SocialMediaFeather.data,"icon_spacing","5"),instagram_display:f().get(SocialMediaFeather.data,"instagram_display","follow"),instagram_follow_link:f().get(SocialMediaFeather.data,"instagram_follow_link",""),instagram_follow_title:f().get(SocialMediaFeather.data,"instagram_follow_title",""),layout_rtl:!0===f().get(SocialMediaFeather.data,"layout_rtl",!1),linkedin_display:f().get(SocialMediaFeather.data,"linkedin_display","both"),linkedin_share_link:f().get(SocialMediaFeather.data,"linkedin_share_link",""),linkedin_share_title:f().get(SocialMediaFeather.data,"linkedin_share_title",""),linkedin_follow_link:f().get(SocialMediaFeather.data,"linkedin_follow_link",""),linkedin_follow_title:f().get(SocialMediaFeather.data,"linkedin_follow_title",""),mail_display:f().get(SocialMediaFeather.data,"mail_display")||"both",mail_share_link:f().get(SocialMediaFeather.data,"mail_share_link",""),mail_share_title:f().get(SocialMediaFeather.data,"mail_share_title",""),mail_follow_link:f().get(SocialMediaFeather.data,"mail_follow_link",""),mail_follow_title:f().get(SocialMediaFeather.data,"mail_follow_title",""),pinterest_display:f().get(SocialMediaFeather.data,"pinterest_display","share"),pinterest_share_link:f().get(SocialMediaFeather.data,"pinterest_share_link",""),pinterest_share_title:f().get(SocialMediaFeather.data,"pinterest_share_title",""),pinterest_follow_link:f().get(SocialMediaFeather.data,"pinterest_follow_link",""),pinterest_follow_title:f().get(SocialMediaFeather.data,"pinterest_follow_title",""),reddit_display:f().get(SocialMediaFeather.data,"reddit_display","share"),reddit_share_link:f().get(SocialMediaFeather.data,"reddit_share_link",""),reddit_share_title:f().get(SocialMediaFeather.data,"reddit_share_title",""),rss_display:f().get(SocialMediaFeather.data,"rss_display","none"),rss_follow_link:f().get(SocialMediaFeather.data,"rss_follow_link",""),rss_follow_title:f().get(SocialMediaFeather.data,"rss_follow_title",""),share_full_url:!0===f().get(SocialMediaFeather.data,"share_full_url",!1),share_message_default:f().get(SocialMediaFeather.data,"share_message_default",(0,m.__)("Hey check this out","social-media-feather")),shortcode_widgets:!0===f().get(SocialMediaFeather.data,"shortcode_widgets",!0),show_credit:!0===f().get(SocialMediaFeather.data,"show_credit",!1),tumblr_display:f().get(SocialMediaFeather.data,"tumblr_display","none"),tumblr_share_link:f().get(SocialMediaFeather.data,"tumblr_share_link",""),tumblr_share_title:f().get(SocialMediaFeather.data,"tumblr_share_title",""),tumblr_follow_link:f().get(SocialMediaFeather.data,"tumblr_follow_link",""),tumblr_follow_title:f().get(SocialMediaFeather.data,"tumblr_follow_title",""),twitter_display:f().get(SocialMediaFeather.data,"twitter_display","both"),twitter_share_link:f().get(SocialMediaFeather.data,"twitter_share_link",""),twitter_share_title:f().get(SocialMediaFeather.data,"twitter_share_title",""),twitter_follow_link:f().get(SocialMediaFeather.data,"twitter_follow_link",""),twitter_follow_title:f().get(SocialMediaFeather.data,"twitter_follow_title",""),use_shortlinks:!0===f().get(SocialMediaFeather.data,"use_shortlinks",!1),vimeo_display:f().get(SocialMediaFeather.data,"vimeo_display","none"),vimeo_follow_link:f().get(SocialMediaFeather.data,"vimeo_follow_link",""),vimeo_follow_title:f().get(SocialMediaFeather.data,"vimeo_follow_title",""),youtube_display:f().get(SocialMediaFeather.data,"youtube_display","none"),youtube_follow_link:f().get(SocialMediaFeather.data,"youtube_follow_link",""),youtube_follow_title:f().get(SocialMediaFeather.data,"youtube_follow_title","")},sa=(e,t)=>"all"===t.type?{...e,...t.payload}:{...e,[t.type]:t.payload},ca=[{label:"After Post",value:"after_post"},{label:"Before Post",value:"before_post"},{label:"Before and After Post",value:"after_before_post"}],ua=[{label:"Post",value:"post"},{label:"Page",value:"page"},{label:"Attachment",value:"attachment"}],da=f().chunk([{label:"Regular",value:"regular",imagePath:"/synved-social/image/social/regular/preview.png"},{label:"Clear Slate",value:"clearslate",imagePath:"/synved-social/addons/extra-icons/image/social/clearslate/preview.png"},{label:"Dark Slate",value:"darkslate",imagePath:"/synved-social/addons/extra-icons/image/social/darkslate/preview.png"},{label:"Circle",value:"circle",imagePath:"/synved-social/addons/extra-icons/image/social/circle/preview.png"},{label:"Wheel",value:"wheel",imagePath:"/synved-social/addons/extra-icons/image/social/wheel/preview.png"},{label:"Flag",value:"flag",imagePath:"/synved-social/addons/extra-icons/image/social/flag/preview.png"},{label:"Medal",value:"medal",imagePath:"/synved-social/addons/extra-icons/image/social/medal/preview.png"},{label:"Shed",value:"shed",imagePath:"/synved-social/addons/extra-icons/image/social/shed/preview.png"},{label:"Balloon",value:"balloon",imagePath:"/synved-social/addons/extra-icons/image/social/balloon/preview.png"}],3),ma=[{value:16,label:"16x16"},{value:24,label:"24x24"},{value:32,label:"32x32"},{value:48,label:"48x48"},{value:64,label:"64x64"},{value:96,label:"96x96"}],pa=[{value:"single",label:"Single"},{value:"double",label:"Double"}],fa=[{value:"basic",label:"Basic"},{value:"block",label:"Block"}],ha=[{value:"none",label:"Theme Default"},{value:"left",label:"Align Left"},{value:"right",label:"Align Right"},{value:"center",label:"Align Center"}],ba=[{value:"none",label:"None"},{value:"share",label:"Share"},{value:"follow",label:"Follow"},{value:"both",label:"Share and Follow"}],_a=[{value:"none",label:"None"},{value:"share",label:"Share"}],ga=[{value:"none",label:"None"},{value:"follow",label:"Follow"}],ya=f().sortBy([{label:"Facebook",slug:"facebook",shareLink:"https://www.facebook.com/sharer.php?u=%%url%%&t=%%title%%&s=100&p[url]=%%url%%&p[images][0]=%%image%%&p[title]=%%title%%",shareTitle:"Share on Facebook",followLink:"https://www.facebook.com/facebook",followTitle:"Follow us on Facebook"},{label:"Twitter",slug:"twitter",shareLink:"https://twitter.com/intent/tweet?url=%%url%%&text=%%message%%",shareTitle:"Share on Twitter",followLink:"https://twitter.com/twitter",followTitle:"Follow us on Twitter"},{label:"Reddit",slug:"reddit",shareLink:"https://www.reddit.com/submit?url=%%url%%&title=%%title%%",shareTitle:"Share on Reddit"},{label:"Pinterest",slug:"pinterest",shareLink:"https://pinterest.com/pin/create/button/?url=%%url%%&media=%%image%%&description=%%title%%",shareTitle:"Pin it with Pinterest",followLink:"https://pinterest.com/MyUserName/",followTitle:"Our board on Pinterest"},{label:"LinkedIn",slug:"linkedin",shareLink:"https://www.linkedin.com/shareArticle?mini=true&url=%%url%%&title=%%title%%",shareTitle:"Share on Linkedin",followLink:"https://www.linkedin.com/in/yourid",followTitle:"Find us on Linkedin"},{label:"Tumblr",slug:"tumblr",shareLink:"https://tumblr.com/share?s=&v=3&t=%%title%%&u=%%url%%",shareTitle:"Share on tumblr",followLink:"https://myname.tumblr.com",followTitle:"Find us on tumblr"},{label:"Email",slug:"mail",shareLink:"mailto:mail@example.com?subject=Contact%20Request",shareTitle:"Share by e-mail",followLink:"mailto:mail@example.com?subject=Contact%20Request",followTitle:"Contact Us"},{label:"RSS",slug:"rss",followLink:"https://feeds.feedburner.com/MyFeedName",followTitle:"Subscribe to our RSS Feed"},{label:"YouTube",slug:"youtube",followLink:"https://www.youtube.com/MyYouTubeName",followTitle:"Find us on YouTube"},{label:"Vimeo",slug:"vimeo",followLink:"https://vimeo.com/MyVimeoName",followTitle:"Find us on Vimeo"},{label:"Instagram",slug:"instagram",followLink:"https://instagram.com/myusername",followTitle:"Check out our instagram feed"},{label:"Flickr",slug:"flickr",followLink:"https://www.flickr.com/photos/myusername/",followTitle:"Check out our flickr feed"},{label:"Foursquare",slug:"foursquare",followLink:"https://foursquare.com/myusername",followTitle:"Check out our foursquare feed"}],["slug"]),va={service:"Decides for what types of services Facebook will be used by default.",shareLink:(0,l.createElement)(l.Fragment,null,"The link used by default for sharing content on Facebook. ",(0,l.createElement)("strong",null,"Note: this generally doesn't need to be changed, only change it if you know what you're doing.")),shareTitle:"The title used by default for the Facebook share button (a standard one will be used if left empty).",followLink:"The link used by default for following you on Facebook. Change this to point to your own social profile page on Facebook.",followTitle:"The title used by default for the Facebook follow button (a standard one will be used if left empty)."};var wa=()=>{const[e,t]=(0,l.useState)(!1),a=(0,l.useRef)(null),[n,o]=(0,l.useReducer)(sa,ia),r=f().debounce((e=>{t(!0),d()({path:"/social-media-feather/v2/settings",method:"POST",data:e}).then((e=>{o({type:"all",payload:e.data}),t(!1)})).catch((e=>{console.error({err:e}),t(!1)}))}),250);return(0,l.createElement)(E,{className:"social-media-feather mt-5 mx-0"},(0,l.createElement)(se,null,(0,l.createElement)(de,{className:"mb-3"},(0,l.createElement)("h1",{className:"px-0"},(0,m.__)("Social Media Feather Settings","social-media-feather"))),(0,l.createElement)(Zt,{defaultActiveKey:"general",className:"mb-3"},(0,l.createElement)(aa,{eventKey:"general",title:"General",className:"mb-3",disabled:!!e},(0,l.createElement)(se.Group,{as:de,className:"mb-3"},(0,l.createElement)("h3",{className:"px-0"},(0,m.__)("General Settings","social-media-feather")),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},(0,m.__)("Settings affecting the general behaviour of the plugin.","social-media-feather"))),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckUseShortlinks"},(0,l.createElement)(se.Check,{type:"switch",label:"Use Shortlinks",id:"use_shortlinks",onClick:()=>o({type:"use_shortlinks",payload:!n.use_shortlinks}),checked:n.use_shortlinks}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Allows for shortened URLs to be used when sharing content if a shortening plugin is installed.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckShareFullURL"},(0,l.createElement)(se.Check,{type:"switch",label:"Share Full URL",id:"share_full_url",onChange:()=>o({type:"share_full_url",payload:!n.share_full_url}),checked:n.share_full_url}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Determines whether to always share the full URL or just the post permalink. You can override this for individual posts by setting the "synved_social_share_full_url" custom field to either "yes" or "no", case sensitive.')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckLayoutRTL"},(0,l.createElement)(se.Check,{type:"switch",label:"Right To Left Layout",id:"layout_rtl",onChange:()=>o({type:"layout_rtl",payload:!n.layout_rtl}),checked:n.layout_rtl}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Check this option if you have a right-to-left site layout and icons show spacing issues.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckShortcodeWidgets"},(0,l.createElement)(se.Check,{type:"switch",label:"Shortcodes In Widgets",id:"shortcode_widgets",onChange:()=>o({type:"shortcode_widgets",payload:!n.shortcode_widgets}),checked:n.shortcode_widgets}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Allow shortcodes in Text widgets.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckShowCredit"},(0,l.createElement)(se.Check,{type:"switch",label:"Show Credit",id:"show_credit",onChange:()=>o({type:"show_credit",payload:!n.show_credit}),checked:n.show_credit}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Display a small icon with a link to the Social Media Feather page.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextDefaultMessage"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Default Message"),(0,l.createElement)(se.Control,{placeholder:"Default message",onChange:e=>o({type:"share_message_default",payload:e.target.value}),value:n.share_message_default}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Specify the default message to use when sharing content, this is what gets replaced into the %%message%% variable.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextFacebookAppID"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Facebook App ID"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"fb_app_id",payload:e.target.value}),value:n.fb_app_id}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"To use Facebook functionality, please enter your Facebook App ID here.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckAcceptedShareThisTerms"},(0,l.createElement)(se.Check,{type:"switch",label:"Terms of Service",id:"accepted_sharethis_terms",onChange:()=>o({type:"accepted_sharethis_terms",payload:!n.accepted_sharethis_terms}),checked:n.accepted_sharethis_terms}),(0,l.createElement)(se.Text,{muted:!0},"Accept or decline ",(0,l.createElement)("a",{target:"_blank",href:"https://www.sharethis.com/terms/"},"ShareThis Terms of Service")," and ",(0,l.createElement)("a",{target:"_blank",href:"https://www.sharethis.com/privacy/"},"Privacy Notice"),"."))),(0,l.createElement)(aa,{eventKey:"automatic",title:"Automatic Display",disabled:!!e},(0,l.createElement)(se.Group,{as:de,className:"mb-3"},(0,l.createElement)("h3",{className:"px-0"},"Automatic Display"),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Settings affecting automating appending of social buttons to post contents.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckAutomaticShare"},(0,l.createElement)(se.Check,{type:"switch",label:"Display Sharing Buttons",id:"automatic_share",onChange:()=>o({type:"automatic_share",payload:!n.automatic_share}),checked:n.automatic_share}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Tries to automatically append sharing buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_share to "yes", case sensitive).')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectAutomaticSharePosition"},(0,l.createElement)(se.Label,{className:"px-0"},"Share Buttons Position"),(0,l.createElement)(se.Select,{value:n.automatic_share_position,onChange:e=>o({type:"automatic_share_position",payload:e.target.value})},ca.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Tries to automatically append sharing buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_share to "yes", case sensitive).')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckAutomaticShareSingle"},(0,l.createElement)(se.Check,{type:"switch",label:"Sharing Single Posts",id:"automatic_share_single",onChange:()=>o({type:"automatic_share_single",payload:!n.automatic_share_single}),checked:n.automatic_share_single}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Sharing buttons are only displayed on single posts/pages and not on archive pages like blog/category/tag/author pages.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectAutomaticPostTypes"},(0,l.createElement)(se.Label,{className:"px-0"},"Share Post Types"),(0,l.createElement)(se.Select,{className:"automatic_share_post_types",multiple:!0,onChange:e=>o({type:"automatic_share_post_types",payload:Array.from(e.target.querySelectorAll("option:checked")).map((e=>e.value))}),value:n.automatic_share_post_types},ua.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Post types for which automatic appending for share buttons should be attempted (CTRL + click to select multiple ones).")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextSharePrefixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Share Prefix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_share_prefix",payload:e.target.value}),value:n.automatic_share_prefix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup before the share buttons markup.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextSharePostfixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Share Postfix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_share_postfix",payload:e.target.value}),value:n.automatic_share_postfix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup after all of the share buttons markup.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckAutomaticFollow"},(0,l.createElement)(se.Check,{type:"switch",label:"Display Follow Buttons",id:"automatic_follow",onChange:()=>o({type:"automatic_follow",payload:!n.automatic_follow}),checked:n.automatic_follow}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Tries to automatically append follow buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_follow to "yes", case sensitive).')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectAutomaticFollowPostTypes"},(0,l.createElement)(se.Label,{className:"px-0"},"Follow Post Types"),(0,l.createElement)(se.Select,{className:"automatic_follow_post_types",multiple:!0,onChange:e=>o({type:"automatic_follow_post_types",payload:Array.from(e.target.querySelectorAll("option:checked")).map((e=>e.value))}),value:n.automatic_follow_post_types},ua.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Post types for which automatic appending for follow buttons should be attempted (CTRL + click to select multiple ones).")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formCheckAutomaticBeforeShare"},(0,l.createElement)(se.Check,{type:"switch",label:"Follow Before Share",id:"automatic_follow_before_share",onChange:()=>o({type:"automatic_follow_before_share",payload:!n.automatic_follow_before_share}),checked:n.automatic_follow_before_share}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place follow buttons before share buttons. Only valid when share and follow buttons positions are the same.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextFollowPrefixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Follow Prefix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_follow_prefix",payload:e.target.value}),value:n.automatic_follow_prefix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup before the follow buttons markup.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextFollowPostfixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Follow Postfix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_follow_postfix",payload:e.target.value}),value:n.automatic_follow_postfix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup after all of the follow buttons markup.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextPrefixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Prefix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_append_prefix",payload:e.target.value}),value:n.automatic_append_prefix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup before the buttons markup.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextSeparatorMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Separator Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_append_separator",payload:e.target.value}),value:n.automatic_append_separator}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending both, use this markup as separator between the set of share buttons and the set of follow buttons. Only valid when share and follow buttons positions are the same.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextPostfixMarkup"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Postfix Markup"),(0,l.createElement)(se.Control,{onChange:e=>o({type:"automatic_append_postfix",payload:e.target.value}),value:n.automatic_append_postfix}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup after all of the buttons markup."))),(0,l.createElement)(aa,{eventKey:"customize",title:"Customize Look",disabled:!!e},(0,l.createElement)(se.Group,{as:de,className:"mb-3"},(0,l.createElement)("h3",{className:"px-0"},"Customize Look"),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Customize the look & feel of Social Media Feather.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectIconSkin"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Icon Skin"),(0,l.createElement)(E,null,(0,l.createElement)(de,null,da.map(((e,t)=>(0,l.createElement)(l.Fragment,null,(0,l.createElement)(V,{md:"auto",className:"mb-3"},(0,l.createElement)(de,null,(0,l.createElement)(se.Check,{type:"radio",id:`icon-skin-${e[0].value}`,className:"smf__form-check"},(0,l.createElement)(se.Check.Label,null,(0,l.createElement)(na,{src:`${SocialMediaFeather.pluginURL}${e[0].imagePath}`}),(0,l.createElement)(se.Check.Input,{name:"icon_skin",type:"radio",checked:e[0].value===n.icon_skin,value:e[0].value,className:"smf__form-check-input--radio",onChange:e=>o({type:"icon_skin",payload:e.target.value})}),e[0].label)))),(0,l.createElement)(V,{md:"auto",className:"mb-3"},(0,l.createElement)(se.Check,{type:"radio",id:`icon-skin-${e[1].value}`,className:"smf__form-check"},(0,l.createElement)(se.Check.Label,null,(0,l.createElement)(na,{src:`${SocialMediaFeather.pluginURL}${e[1].imagePath}`}),(0,l.createElement)(se.Check.Input,{name:"icon_skin",type:"radio",checked:e[1].value===n.icon_skin,value:e[1].value,className:"smf__form-check-input--radio",onChange:e=>o({type:"icon_skin",payload:e.target.value})}),e[1].label))),(0,l.createElement)(V,{md:"auto",className:"mb-3"},(0,l.createElement)(se.Check,{type:"radio",id:`icon-skin-${e[2].value}`,className:"smf__form-check"},(0,l.createElement)(se.Check.Label,null,(0,l.createElement)(na,{src:`${SocialMediaFeather.pluginURL}${e[2].imagePath}`}),(0,l.createElement)(se.Check.Input,{name:"icon_skin",type:"radio",checked:e[2].value===n.icon_skin,value:e[2].value,className:"smf__form-check-input--radio",onChange:e=>o({type:"icon_skin",payload:e.target.value})}),e[2].label))))))))),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectIconSize"},(0,l.createElement)(se.Label,{className:"px-0"},"Icon Size"),(0,l.createElement)(se.Select,{value:n.icon_size,onChange:e=>o({type:"icon_size",payload:e.target.value})},ma.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Select the size in pixels for the icons. Note: for high resolution displays like Retina the maximum size is 64x64.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectIconResolution"},(0,l.createElement)(se.Label,{className:"px-0"},"Icon Resolution"),(0,l.createElement)(se.Select,{value:n.icon_resolution,onChange:e=>o({type:"icon_resolution",payload:e.target.value})},pa.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Select what icon resolutions will be used. Single might make the icons slightly blurry on low resolution displays. Double will always look the best but will consume more bandwidth.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextIconSpacing"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Icon Spacing"),(0,l.createElement)(se.Control,{placeholder:"Default message",type:"number",onChange:e=>o({type:"icon_spacing",payload:e.target.value}),value:n.icon_spacing}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Select the spacing in pixels between the icons.")),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectButtonsInContainer"},(0,l.createElement)(se.Label,{className:"px-0"},"Buttons in Container"),(0,l.createElement)(se.Select,{value:n.buttons_container,onChange:e=>o({type:"buttons_container",payload:e.target.value})},ba.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Determines whether or not to wrap the buttons in a container, which will affect how the buttons are rendered, based on the "Buttons Container Type" setting.')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectButtonsContainerType"},(0,l.createElement)(se.Label,{className:"px-0"},"Buttons Container Type"),(0,l.createElement)(se.Select,{value:n.buttons_container_type,onChange:e=>o({type:"buttons_container_type",payload:e.target.value})},fa.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'"Basic" should not affect rendering, while "Block" should display the buttons in their own row. Note: selecting "Block" might not look the way you want if you\'re using Prefix or Postfix markup.')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectShareButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},"Share Buttons Alignment"),(0,l.createElement)(se.Select,{value:n.buttons_alignment_share,onChange:e=>o({type:"buttons_alignment_share",payload:e.target.value})},ha.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Will attempt at aligning the share buttons accordingly. Note: this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes.')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectFollowButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},"Follow Buttons Alignment"),(0,l.createElement)(se.Select,{value:n.buttons_alignment_follow,onChange:e=>o({type:"buttons_alignment_follow",payload:e.target.value})},ha.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},'Will attempt at aligning the follow buttons accordingly. Note: this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes.')),(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextExtraStyles"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},"Extra Styles"),(0,l.createElement)(se.Control,{as:"textarea",onChange:e=>o({type:"custom_style",payload:e.target.value}),value:n.custom_style}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"When automatically appending, place this markup after all of the share buttons markup."))),(0,l.createElement)(aa,{eventKey:"service",title:"Service Providers",disabled:!!e},(0,l.createElement)(se.Group,{as:de,className:"mb-3"},(0,l.createElement)("h3",{className:"px-0"},"Service Providers"),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},"Customize social sharing and following providers.")),ya.map((e=>{let t="none";e.shareLink&&e.followLink?t="both":e.shareLink?t="share":e.followLink&&(t="follow");let a=[];return"both"===t?a=[...ba]:"share"===t?a=[..._a]:"follow"===t&&(a=[...ga]),(0,l.createElement)(l.Fragment,null,(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formPlaintextExtraStyles"},(0,l.createElement)(se.Label,{column:!0,sm:"2",className:"px-0"},e.label," Service"),(0,l.createElement)(se.Select,{value:n[`${e.slug}_display`],onChange:t=>o({type:`${e.slug}_display`,payload:t.target.value})},a.map((e=>(0,l.createElement)("option",{value:e.value},e.label)))),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},va.service)),e.shareLink&&(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectFollowButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},e.label," Share Link"),(0,l.createElement)(se.Control,{placeholder:e.shareLink,type:"text",onChange:t=>o({type:`${e.slug}_share_link`,payload:t.target.value}),value:n[`${e.slug}_share_link`]}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},va.shareLink)),e.shareTitle&&(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectFollowButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},e.label," Share Title"),(0,l.createElement)(se.Control,{placeholder:e.shareTitle,type:"text",onChange:t=>o({type:`${e.slug}_share_title`,payload:t.target.value}),value:n[`${e.slug}_share_title`]}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},va.shareTitle)),e.followLink&&(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectFollowButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},e.label," Follow Link"),(0,l.createElement)(se.Control,{placeholder:e.followLink,type:"text",onChange:t=>o({type:`${e.slug}_follow_link`,payload:t.target.value}),value:n[`${e.slug}_follow_link`]}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},va.followLink)),e.followTitle&&(0,l.createElement)(se.Group,{as:de,className:"mb-3",controlId:"formSelectFollowButtonsAlignment"},(0,l.createElement)(se.Label,{className:"px-0"},e.label," Follow Title"),(0,l.createElement)(se.Control,{placeholder:e.followTitle,type:"text",onChange:t=>o({type:`${e.slug}_follow_title`,payload:t.target.value}),value:n[`${e.slug}_follow_title`]}),(0,l.createElement)(se.Text,{muted:!0,className:"p-0"},va.followTitle)))})))),(0,l.createElement)(ra,{ref:a,variant:"primary",className:"mx-0",disabled:!!e,onClick:()=>r(n)},!0===e?"...":"Save Settings")))};i()((()=>{o().render((0,l.createElement)(wa,null),document.getElementById("social-media-feather-app"))}))},184:function(e,t){var a;!function(){"use strict";var l={}.hasOwnProperty;function n(){for(var e=[],t=0;t<arguments.length;t++){var a=arguments[t];if(a){var o=typeof a;if("string"===o||"number"===o)e.push(a);else if(Array.isArray(a)){if(a.length){var r=n.apply(null,a);r&&e.push(r)}}else if("object"===o)if(a.toString===Object.prototype.toString)for(var i in a)l.call(a,i)&&a[i]&&e.push(i);else e.push(a.toString())}}return e.join(" ")}e.exports?(n.default=n,e.exports=n):void 0===(a=function(){return n}.apply(t,[]))||(e.exports=a)}()},143:function(e){"use strict";e.exports=function(e,t,a,l,n,o,r,i){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[a,l,n,o,r,i],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},418:function(e){"use strict";var t=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;function n(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},a=0;a<10;a++)t["_"+String.fromCharCode(a)]=a;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var l={};return"abcdefghijklmnopqrst".split("").forEach((function(e){l[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},l)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var r,i,s=n(e),c=1;c<arguments.length;c++){for(var u in r=Object(arguments[c]))a.call(r,u)&&(s[u]=r[u]);if(t){i=t(r);for(var d=0;d<i.length;d++)l.call(r,i[d])&&(s[i[d]]=r[i[d]])}}return s}},391:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){for(var e=arguments.length,t=Array(e),a=0;a<e;a++)t[a]=arguments[a];function l(){for(var e=arguments.length,a=Array(e),l=0;l<e;l++)a[l]=arguments[l];var n=null;return t.forEach((function(e){if(null==n){var t=e.apply(void 0,a);null!=t&&(n=t)}})),n}return(0,n.default)(l)};var l,n=(l=a(613))&&l.__esModule?l:{default:l};e.exports=t.default},613:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){function t(t,a,l,n,o,r){var i=n||"<<anonymous>>",s=r||l;if(null==a[l])return t?new Error("Required "+o+" `"+s+"` was not specified in `"+i+"`."):null;for(var c=arguments.length,u=Array(c>6?c-6:0),d=6;d<c;d++)u[d-6]=arguments[d];return e.apply(void 0,[a,l,i,o,s].concat(u))}var a=t.bind(null,!1);return a.isRequired=t.bind(null,!0),a},e.exports=t.default},703:function(e,t,a){"use strict";var l=a(414);function n(){}function o(){}o.resetWarningCache=n,e.exports=function(){function e(e,t,a,n,o,r){if(r!==l){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var a={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:n};return a.PropTypes=a,a}},697:function(e,t,a){e.exports=a(703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},251:function(e,t,a){"use strict";a(418);var l=a(196),n=60103;if(t.Fragment=60107,"function"==typeof Symbol&&Symbol.for){var o=Symbol.for;n=o("react.element"),t.Fragment=o("react.fragment")}var r=l.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i=Object.prototype.hasOwnProperty,s={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,a){var l,o={},c=null,u=null;for(l in void 0!==a&&(c=""+a),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,l)&&!s.hasOwnProperty(l)&&(o[l]=t[l]);if(e&&e.defaultProps)for(l in t=e.defaultProps)void 0===o[l]&&(o[l]=t[l]);return{$$typeof:n,type:e,key:c,ref:u,props:o,_owner:r.current}}t.jsx=c,t.jsxs=c},893:function(e,t,a){"use strict";e.exports=a(251)},473:function(e){"use strict";e.exports=function(){}},196:function(e){"use strict";e.exports=window.React}},function(e){e(e.s=595)}]);
build/index.js.LICENSE.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ object-assign
3
+ (c) Sindre Sorhus
4
+ @license MIT
5
+ */
6
+
7
+ /*!
8
+ Copyright (c) 2018 Jed Watson.
9
+ Licensed under the MIT License (MIT), see
10
+ http://jedwatson.github.io/classnames
11
+ */
12
+
13
+ /** @license React v17.0.2
14
+ * react-jsx-runtime.production.min.js
15
+ *
16
+ * Copyright (c) Facebook, Inc. and its affiliates.
17
+ *
18
+ * This source code is licensed under the MIT license found in the
19
+ * LICENSE file in the root directory of this source tree.
20
+ */
build/loader.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){"use strict";var n,r={},e={};function t(n){var o=e[n];if(void 0!==o)return o.exports;var i=e[n]={exports:{}};return r[n](i,i.exports,t),i.exports}t.m=r,n=[],t.O=function(r,e,o,i){if(!e){var u=1/0;for(l=0;l<n.length;l++){e=n[l][0],o=n[l][1],i=n[l][2];for(var f=!0,c=0;c<e.length;c++)(!1&i||u>=i)&&Object.keys(t.O).every((function(n){return t.O[n](e[c])}))?e.splice(c--,1):(f=!1,i<u&&(u=i));if(f){n.splice(l--,1);var a=o();void 0!==a&&(r=a)}}return r}i=i||0;for(var l=n.length;l>0&&n[l-1][2]>i;l--)n[l]=n[l-1];n[l]=[e,o,i]},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,{a:r}),r},t.d=function(n,r){for(var e in r)t.o(r,e)&&!t.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:r[e]})},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),t.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},function(){var n={716:0};t.O.j=function(r){return 0===n[r]};var r=function(r,e){var o,i,u=e[0],f=e[1],c=e[2],a=0;if(u.some((function(r){return 0!==n[r]}))){for(o in f)t.o(f,o)&&(t.m[o]=f[o]);if(c)var l=c(t)}for(r&&r(e);a<u.length;a++)i=u[a],t.o(n,i)&&n[i]&&n[i][0](),n[i]=0;return t.O(l)},e=self.webpackChunksocial_media_feather=self.webpackChunksocial_media_feather||[];e.forEach(r.bind(null,0)),e.push=r.bind(null,e.push.bind(e))}()}();
instance.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Instantiates the Social Media Feather plugin.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ namespace SocialMediaFeather;
9
+
10
+ require_once __DIR__ . '/php/class-plugin-base.php';
11
+ require_once __DIR__ . '/php/class-plugin.php';
12
+
13
+ /**
14
+ * Social Media Feather Plugin Instance
15
+ *
16
+ * @return Plugin
17
+ */
18
+ function plugin_instance() {
19
+ static $instance = null;
20
+
21
+ if ( true === is_null( $instance ) ) {
22
+ $instance = new Plugin();
23
+ }
24
+
25
+ return $instance;
26
+ }
27
+
28
+ plugin_instance();
php/class-plugin-base.php ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Plugin_Base
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ namespace SocialMediaFeather;
9
+
10
+ /**
11
+ * Class Plugin_Base
12
+ *
13
+ * @package GDPRComplianceTool
14
+ */
15
+ abstract class Plugin_Base {
16
+
17
+ /**
18
+ * Plugin config.
19
+ *
20
+ * @var array
21
+ */
22
+ public $config = array();
23
+
24
+ /**
25
+ * Plugin slug.
26
+ *
27
+ * @var string
28
+ */
29
+ public $slug;
30
+
31
+ /**
32
+ * Plugin directory path.
33
+ *
34
+ * @var string
35
+ */
36
+ public $dir_path;
37
+
38
+ /**
39
+ * Plugin directory URL.
40
+ *
41
+ * @var string
42
+ */
43
+ public $dir_url;
44
+
45
+ /**
46
+ * Directory in plugin containing autoloaded classes.
47
+ *
48
+ * @var string
49
+ */
50
+ protected $autoload_class_dir = 'php';
51
+
52
+ /**
53
+ * Autoload matches cache.
54
+ *
55
+ * @var array
56
+ */
57
+ protected $autoload_matches_cache = array();
58
+
59
+ /**
60
+ * Required instead of a static variable inside the add_doc_hooks method
61
+ * for the sake of unit testing.
62
+ *
63
+ * @var array
64
+ */
65
+ protected $called_doc_hooks = array();
66
+
67
+ /**
68
+ * Plugin_Base constructor.
69
+ */
70
+ public function __construct() {
71
+ $location = $this->locate_plugin();
72
+ $this->slug = $location['dir_basename'];
73
+ $this->dir_path = $location['dir_path'];
74
+ $this->dir_url = $location['dir_url'];
75
+
76
+ spl_autoload_register( array( $this, 'autoload' ) );
77
+ $this->add_doc_hooks();
78
+ }
79
+
80
+ /**
81
+ * Plugin_Base destructor.
82
+ */
83
+ public function __destruct() {
84
+ $this->remove_doc_hooks();
85
+ }
86
+
87
+ /**
88
+ * Get reflection object for this class.
89
+ *
90
+ * @return \ReflectionObject
91
+ */
92
+ public function get_object_reflection() {
93
+ static $reflection;
94
+
95
+ if ( empty( $reflection ) ) {
96
+ $reflection = new \ReflectionObject( $this );
97
+ }
98
+
99
+ return $reflection;
100
+ }
101
+
102
+ /**
103
+ * Autoload for classes that are in the same namespace as $this.
104
+ *
105
+ * @param string $class Class name.
106
+ * @return void
107
+ */
108
+ public function autoload( $class ) {
109
+ if ( ! isset( $this->autoload_matches_cache[ $class ] ) ) {
110
+ if ( ! preg_match( '/^(?P<namespace>.+)\\\\(?P<class>[^\\\\]+)$/', $class, $matches ) ) {
111
+ $matches = false;
112
+ }
113
+
114
+ $this->autoload_matches_cache[ $class ] = $matches;
115
+ } else {
116
+ $matches = $this->autoload_matches_cache[ $class ];
117
+ }
118
+
119
+ if ( empty( $matches ) ) {
120
+ return;
121
+ }
122
+
123
+ if ( $this->get_object_reflection()->getNamespaceName() !== $matches['namespace'] ) {
124
+ return;
125
+ }
126
+
127
+ $class_name = $matches['class'];
128
+ $class_path = \trailingslashit( $this->dir_path );
129
+
130
+ if ( $this->autoload_class_dir ) {
131
+ $class_path .= \trailingslashit( $this->autoload_class_dir );
132
+ }
133
+
134
+ $class_path .= sprintf( 'class-%s.php', strtolower( str_replace( '_', '-', $class_name ) ) );
135
+
136
+ if ( is_readable( $class_path ) ) {
137
+ require_once $class_path;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Version of plugin_dir_url() which works for plugins installed in the plugins directory,
143
+ * and for plugins bundled with themes.
144
+ *
145
+ * @return array
146
+ */
147
+ public function locate_plugin() {
148
+ $base_file = str_replace( 'php', '', __FILE__ );
149
+ $dir_url = trailingslashit( plugins_url( '', $base_file ) );
150
+ $dir_path = substr( str_replace( 'class-plugin-base', '', $base_file ), 0, - 2 );
151
+ $dir_basename = basename( $dir_path );
152
+
153
+ return compact( 'dir_url', 'dir_path', 'dir_basename' );
154
+ }
155
+
156
+ /**
157
+ * Hooks a function on to a specific filter.
158
+ *
159
+ * @param string $name The hook name.
160
+ * @param array $callback The class object and method.
161
+ * @param array $args An array with priority and arg_count.
162
+ *
163
+ * @return mixed
164
+ */
165
+ public function add_filter( $name, $callback, $args = array() ) {
166
+ // Merge defaults.
167
+ $args = array_merge(
168
+ array(
169
+ 'priority' => 10,
170
+ 'arg_count' => PHP_INT_MAX,
171
+ ),
172
+ $args
173
+ );
174
+
175
+ return $this->add_hook( 'filter', $name, $callback, $args );
176
+ }
177
+
178
+ /**
179
+ * Hooks a function on to a specific action.
180
+ *
181
+ * @param string $name The hook name.
182
+ * @param array $callback The class object and method.
183
+ * @param array $args An array with priority and arg_count.
184
+ *
185
+ * @return mixed
186
+ */
187
+ public function add_action( $name, $callback, $args = array() ) {
188
+ // Merge defaults.
189
+ $args = array_merge(
190
+ array(
191
+ 'priority' => 12,
192
+ 'arg_count' => PHP_INT_MAX,
193
+ ),
194
+ $args
195
+ );
196
+
197
+ return $this->add_hook( 'action', $name, $callback, $args );
198
+ }
199
+
200
+ /**
201
+ * Hooks a function on to a specific shortcode.
202
+ *
203
+ * @param string $name The shortcode name.
204
+ * @param array $callback The class object and method.
205
+ *
206
+ * @return mixed
207
+ */
208
+ public function add_shortcode( $name, $callback ) {
209
+ return $this->add_hook( 'shortcode', $name, $callback );
210
+ }
211
+
212
+ /**
213
+ * Hooks a function on to a specific action/filter.
214
+ *
215
+ * @param string $type The hook type. Options are action/filter.
216
+ * @param string $name The hook name.
217
+ * @param array $callback The class object and method.
218
+ * @param array $args An array with priority and arg_count.
219
+ *
220
+ * @return mixed
221
+ */
222
+ protected function add_hook( $type, $name, $callback, $args = array() ) {
223
+ $priority = true === isset( $args['priority'] ) ? $args['priority'] : 10;
224
+ $arg_count = true === isset( $args['arg_count'] ) ? $args['arg_count'] : PHP_INT_MAX;
225
+ $fn = sprintf( '\add_%s', $type );
226
+ $retval = \call_user_func( $fn, $name, $callback, $priority, $arg_count );
227
+
228
+ return $retval;
229
+ }
230
+
231
+ /**
232
+ * Add actions/filters/shortcodes from the methods of a class based on DocBlocks.
233
+ *
234
+ * @param object $object The class object.
235
+ */
236
+ public function add_doc_hooks( $object = null ) {
237
+ if ( is_null( $object ) ) {
238
+ $object = $this;
239
+ }
240
+ $class_name = get_class( $object );
241
+ if ( isset( $this->called_doc_hooks[ $class_name ] ) ) {
242
+ $notice = sprintf( 'The add_doc_hooks method was already called on %s. Note that the Plugin_Base constructor automatically calls this method.', $class_name );
243
+ // @codingStandardsIgnoreStart
244
+ trigger_error( esc_html( $notice ), \E_USER_NOTICE );
245
+ // @codingStandardsIgnoreEnd
246
+ return;
247
+ }
248
+ $this->called_doc_hooks[ $class_name ] = true;
249
+ $reflector = new \ReflectionObject( $object );
250
+ foreach ( $reflector->getMethods() as $method ) {
251
+ $doc = $method->getDocComment();
252
+ $arg_count = $method->getNumberOfParameters();
253
+ if ( preg_match_all( '#\* @(?P<type>filter|action|shortcode)\s+(?P<name>[a-z0-9\-\._]+)(?:,\s+(?P<priority>\d+))?#', $doc, $matches, PREG_SET_ORDER ) ) {
254
+ foreach ( $matches as $match ) {
255
+ $type = $match['type'];
256
+ $name = $match['name'];
257
+ $priority = empty( $match['priority'] ) ? 11 : intval( $match['priority'] );
258
+ $callback = array( $object, $method->getName() );
259
+ call_user_func( array( $this, "add_{$type}" ), $name, $callback, compact( 'priority', 'arg_count' ) );
260
+ }
261
+ }
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Removes the added DocBlock hooks.
267
+ *
268
+ * @param object $object The class object.
269
+ */
270
+ public function remove_doc_hooks( $object = null ) {
271
+ if ( is_null( $object ) ) {
272
+ $object = $this;
273
+ }
274
+ $class_name = get_class( $object );
275
+ $reflector = new \ReflectionObject( $object );
276
+ foreach ( $reflector->getMethods() as $method ) {
277
+ $doc = $method->getDocComment();
278
+ if ( preg_match_all( '#\* @(?P<type>filter|action|shortcode)\s+(?P<name>[a-z0-9\-\._]+)(?:,\s+(?P<priority>\d+))?#', $doc, $matches, PREG_SET_ORDER ) ) {
279
+ foreach ( $matches as $match ) {
280
+ $type = $match['type'];
281
+ $name = $match['name'];
282
+ $priority = empty( $match['priority'] ) ? 10 : intval( $match['priority'] );
283
+ $callback = array( $object, $method->getName() );
284
+ call_user_func( "remove_{$type}", $name, $callback, $priority );
285
+ }
286
+ }
287
+ }
288
+ unset( $this->called_doc_hooks[ $class_name ] );
289
+ }
290
+ }
php/class-plugin.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bootstraps the Social Media Feather plugin.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ namespace SocialMediaFeather;
9
+
10
+ /**
11
+ * Main plugin bootstrap file.
12
+ */
13
+ class Plugin extends Plugin_Base {
14
+ /**
15
+ * Plugin assets prefix.
16
+ *
17
+ * @var string Lowercased dashed prefix.
18
+ */
19
+ public $assets_prefix;
20
+
21
+ /**
22
+ * Plugin meta prefix.
23
+ *
24
+ * @var string Lowercased underscored prefix.
25
+ */
26
+ public $meta_prefix;
27
+
28
+ /**
29
+ * Plugin constructor.
30
+ */
31
+ public function __construct() {
32
+ parent::__construct();
33
+
34
+ // Initiate classes.
35
+ $classes = array(
36
+ new SocialMediaFeather( $this ),
37
+ );
38
+
39
+ // Add classes doc hooks.
40
+ foreach ( $classes as $instance ) {
41
+ $this->add_doc_hooks( $instance );
42
+ }
43
+
44
+ // Define some prefixes to use throughout the plugin.
45
+ $this->assets_prefix = strtolower( preg_replace( '/\B([A-Z])/', '-$1', __NAMESPACE__ ) );
46
+ $this->meta_prefix = strtolower( preg_replace( '/\B([A-Z])/', '_$1', __NAMESPACE__ ) );
47
+ }
48
+ }
php/class-socialmediafeather.php ADDED
@@ -0,0 +1,926 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Social Media Feather.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ namespace SocialMediaFeather;
9
+
10
+ /**
11
+ * Social Media Feather Class
12
+ *
13
+ * @package SocialMediaFeather
14
+ */
15
+ class SocialMediaFeather {
16
+ /**
17
+ * Plugin instance.
18
+ *
19
+ * @var object
20
+ */
21
+ public $plugin;
22
+
23
+ /**
24
+ * Menu slug.
25
+ *
26
+ * @var string
27
+ */
28
+ public $menu_slug;
29
+
30
+ /**
31
+ * Menu hook suffix.
32
+ *
33
+ * @var string
34
+ */
35
+ private $hook_suffix;
36
+
37
+ /**
38
+ * Holds the settings fields.
39
+ *
40
+ * @var string
41
+ */
42
+ public $setting_fields;
43
+
44
+ /**
45
+ * Class constructor.
46
+ *
47
+ * @param object $plugin Plugin class.
48
+ */
49
+ public function __construct( $plugin ) {
50
+ $this->plugin = $plugin;
51
+ $this->menu_slug = 'social-media-feather';
52
+ $this->hook_suffix = 'settings_page_social-media-feather-settings';
53
+ }
54
+
55
+ /**
56
+ * Enqueue react assets in admin.
57
+ *
58
+ * @action admin_enqueue_scripts
59
+ *
60
+ * @param string $hook_suffix The current admin page.
61
+ */
62
+ public function enqueue_react_assets( $hook_suffix ) {
63
+ // Only enqueue assets on this plugin admin menu.
64
+ if ( $hook_suffix !== $this->hook_suffix ) {
65
+ return;
66
+ }
67
+
68
+ // Load loader.js.
69
+ if ( true === is_readable( "{$this->plugin->dir_path}build/loader.js" ) ) {
70
+ wp_enqueue_script(
71
+ "{$this->plugin->assets_prefix}-loader",
72
+ "{$this->plugin->dir_url}build/loader.js",
73
+ array(),
74
+ filemtime( "{$this->plugin->dir_path}build/loader.js" ),
75
+ false
76
+ );
77
+ }
78
+
79
+ // Load index.js and dependencies.
80
+ $dependencies_file = $this->plugin->dir_path . 'build/index.asset.php';
81
+
82
+ $dependencies = array();
83
+
84
+ $dependency_settings = array(
85
+ 'dependencies' => array(),
86
+ 'version' => null,
87
+ );
88
+
89
+ if ( true === is_readable( $dependencies_file ) ) {
90
+ $dependency_file_settings = require $dependencies_file;
91
+ $dependency_settings = wp_parse_args( $dependency_file_settings, $dependency_settings );
92
+ }
93
+
94
+ wp_enqueue_script(
95
+ "{$this->plugin->assets_prefix}-app",
96
+ $this->plugin->dir_url . 'build/index.js',
97
+ $dependency_settings['dependencies'],
98
+ $dependency_settings['version'],
99
+ false
100
+ );
101
+
102
+ wp_localize_script(
103
+ "{$this->plugin->assets_prefix}-app",
104
+ 'SocialMediaFeather',
105
+ array(
106
+ 'nonce' => wp_create_nonce( $this->plugin->meta_prefix ),
107
+ 'data' => get_option( 'synved_social_settings' ),
108
+ 'review' => get_option( 'smf-hide-review' ),
109
+ 'pluginDir' => SOCIAL_MEDIA_FEATHER_PLUGIN_DIRECTORY,
110
+ 'pluginURL' => SOCIAL_MEDIA_FEATHER_PLUGIN_URL,
111
+ )
112
+ );
113
+
114
+ // Load index.css, if exists.
115
+ if ( true === is_readable( $this->plugin->dir_path . 'build/index.css' ) ) {
116
+ wp_enqueue_style(
117
+ "{$this->plugin->assets_prefix}-app-style",
118
+ $this->plugin->dir_url . 'build/index.css',
119
+ array(),
120
+ filemtime( $this->plugin->dir_path . 'build/index.css' )
121
+ );
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Register REST routes.
127
+ *
128
+ * @action rest_api_init
129
+ */
130
+ public function register_rest_routes() {
131
+ register_rest_route(
132
+ 'social-media-feather/v2',
133
+ '/settings',
134
+ array(
135
+ 'methods' => 'POST',
136
+ 'callback' => array( $this, 'rest_settings_save' ),
137
+ 'permission_callback' => function ( \WP_REST_Request $request ) {
138
+ return current_user_can( 'manage_options' );
139
+ },
140
+ )
141
+ );
142
+ }
143
+
144
+ /**
145
+ * Add settings page.
146
+ *
147
+ * @action admin_menu
148
+ */
149
+ public function add_settings_page() {
150
+ add_options_page(
151
+ 'Social Media Feather',
152
+ 'Social Media',
153
+ 'manage_options',
154
+ 'social-media-feather-settings',
155
+ function () {
156
+ echo '<div id="social-media-feather-app"></div>';
157
+ echo wp_kses_post( synved_connect_support_social_follow_render() );
158
+ },
159
+ 99
160
+ );
161
+ }
162
+
163
+ /**
164
+ * Add plugin settings link.
165
+ *
166
+ * @param array $plugin_actions Plugin actions array.
167
+ * @param string $plugin_file Plugin file.
168
+ *
169
+ * @action plugin_action_links
170
+ */
171
+ public function add_plugin_settings_link( $plugin_actions, $plugin_file ) {
172
+ $local_actions = array();
173
+
174
+ if ( 'social-media-feather.php' === basename( $plugin_file ) ) {
175
+ $local_actions['settings'] = '<a href="'
176
+ . esc_url( admin_url( 'options-general.php?page=social-media-feather-settings' ) )
177
+ . '">'
178
+ . esc_html__( 'Settings', 'social-media-feather' )
179
+ . '</a>';
180
+
181
+ $plugin_actions = $plugin_actions + $local_actions;
182
+ }
183
+
184
+ return $plugin_actions;
185
+ }
186
+
187
+ /**
188
+ * Settings save endpoint.
189
+ *
190
+ * @param \WP_REST_Request $data Request data.
191
+ *
192
+ * @return void
193
+ */
194
+ public function rest_settings_save( \WP_REST_Request $data ) {
195
+ $settings_params_raw = $data->get_json_params();
196
+
197
+ $settings_params_filtered = $this->sanitize_incoming_fields( $settings_params_raw );
198
+
199
+ $current_settings = get_option( 'synved_social_settings' );
200
+
201
+ $settings = wp_parse_args( $settings_params_filtered, $current_settings );
202
+
203
+ update_option( 'synved_social_settings', $settings );
204
+
205
+ wp_send_json_success( $settings_params_filtered );
206
+ }
207
+
208
+ /**
209
+ * Sanitize incoming fields.
210
+ *
211
+ * @param array $fields Array of fields.
212
+ *
213
+ * @return array Sanitized array of fields.
214
+ */
215
+ public function sanitize_incoming_fields( array $fields ): array {
216
+ $whitelist = $this->get_field_whitelist();
217
+
218
+ // Remove fields that aren't in our whitelist.
219
+ $fields_filtered = array_intersect_key( $fields, $whitelist );
220
+
221
+ // Sanitize field values against their sanitizer type.
222
+ $fields_filtered = array_filter(
223
+ $fields_filtered,
224
+ function ( $raw_value, $field ) use ( $whitelist ) {
225
+ if ( false === array_key_exists( $field, $whitelist ) ) {
226
+ return false;
227
+ }
228
+
229
+ $type = $whitelist[ $field ]['type'];
230
+
231
+ switch ( $type ) {
232
+ case 'array':
233
+ return true === is_array( $raw_value );
234
+ case 'boolean':
235
+ return true === is_bool( $raw_value );
236
+ case 'string':
237
+ return true === is_string( $raw_value );
238
+ case 'number':
239
+ return true === is_numeric( $raw_value );
240
+ default:
241
+ return true;
242
+ }
243
+ },
244
+ ARRAY_FILTER_USE_BOTH
245
+ );
246
+
247
+ // Run through sanitizers.
248
+ array_walk(
249
+ $fields_filtered,
250
+ function ( $raw_value, $field ) use ( &$fields_filtered, $whitelist ) {
251
+ $sanitizer = $whitelist[ $field ]['sanitizer'];
252
+
253
+ if ( true === is_null( $sanitizer ) ) {
254
+ return;
255
+ }
256
+
257
+ switch ( $sanitizer ) {
258
+ case 'alphanum':
259
+ $fields_filtered[ $field ] =
260
+ preg_replace( '/[^A-Za-z0-9 ]/', '', $raw_value );
261
+ break;
262
+ case 'esc_asc':
263
+ $fields_filtered[ $field ] = esc_attr( $raw_value );
264
+ break;
265
+ case 'esc_html':
266
+ $fields_filtered[ $field ] = wp_kses_decode_entities( esc_html( $raw_value ) );
267
+ break;
268
+ case 'esc_style':
269
+ $fields_filtered[ $field ] = wp_kses(
270
+ $raw_value,
271
+ array(
272
+ 'style' => array(),
273
+ )
274
+ );
275
+ break;
276
+ case 'esc_url':
277
+ $fields_filtered[ $field ] = rawurldecode( esc_url_raw( $raw_value ) );
278
+ break;
279
+ case 'kses':
280
+ $fields_filtered[ $field ] = wp_kses(
281
+ $raw_value,
282
+ synved_get_allowed_html_array()
283
+ );
284
+ break;
285
+ case 'kses_post':
286
+ $fields_filtered[ $field ] = wp_kses_post( $raw_value );
287
+ break;
288
+ case 'in_array':
289
+ $options = $whitelist[ $field ]['options'];
290
+
291
+ if ( false === in_array( $raw_value, $options, true ) ) {
292
+ $fields_filtered[ $field ] = $options[0];
293
+
294
+ return;
295
+ }
296
+ break;
297
+ case 'numeric':
298
+ $fields_filtered[ $field ] =
299
+ preg_replace( '/[^0-9 ]/', '', $raw_value );
300
+ break;
301
+ case 'array_intersect':
302
+ $options = $whitelist[ $field ]['options'];
303
+
304
+ $fields_filtered[ $field ] = array_intersect( $raw_value, $options );
305
+ break;
306
+ }
307
+ }
308
+ );
309
+
310
+ return $fields_filtered;
311
+ }
312
+
313
+ /**
314
+ * Get field whitelist.
315
+ *
316
+ * @return array Hashed array with fields as key and sanitizer type as value.
317
+ */
318
+ public function get_field_whitelist(): array {
319
+ return array(
320
+ 'accepted_sharethis_terms' => array(
321
+ 'type' => 'boolean',
322
+ 'sanitizer' => null,
323
+ ),
324
+ 'automatic_append_postfix' => array(
325
+ 'type' => 'string',
326
+ 'sanitizer' => 'kses_post',
327
+ ),
328
+ 'automatic_append_prefix' => array(
329
+ 'type' => 'string',
330
+ 'sanitizer' => 'kses_post',
331
+ ),
332
+ 'automatic_append_separator' => array(
333
+ 'type' => 'string',
334
+ 'sanitizer' => 'kses_post',
335
+ ),
336
+ 'automatic_follow' => array(
337
+ 'type' => 'boolean',
338
+ 'sanitizer' => null,
339
+ ),
340
+ 'automatic_follow_before_share' => array(
341
+ 'type' => 'boolean',
342
+ 'sanitizer' => null,
343
+ ),
344
+ 'automatic_follow_position' => array(
345
+ 'type' => 'array',
346
+ 'sanitizer' => 'in_array',
347
+ 'options' => array(
348
+ 'after_post',
349
+ 'before_post',
350
+ 'after_before_post',
351
+ ),
352
+ ),
353
+ 'automatic_follow_post_types' => array(
354
+ 'type' => 'array',
355
+ 'sanitizer' => 'array_intersect',
356
+ 'options' => array(
357
+ 'post',
358
+ 'page',
359
+ 'attachment',
360
+ ),
361
+ ),
362
+ 'automatic_follow_postfix' => array(
363
+ 'type' => 'string',
364
+ 'sanitizer' => 'kses_post',
365
+ ),
366
+ 'automatic_follow_prefix' => array(
367
+ 'type' => 'string',
368
+ 'sanitizer' => 'kses_post',
369
+ ),
370
+ 'automatic_follow_single' => array(
371
+ 'type' => '',
372
+ 'sanitizer' => '',
373
+ ),
374
+ 'automatic_share' => array(
375
+ 'type' => 'boolean',
376
+ 'sanitizer' => null,
377
+ ),
378
+ 'automatic_share_position' => array(
379
+ 'type' => 'string',
380
+ 'sanitizer' => 'in_array',
381
+ 'options' => array(
382
+ 'after_post',
383
+ 'before_post',
384
+ 'after_before_post',
385
+ ),
386
+ ),
387
+ 'automatic_share_post_types' => array(
388
+ 'type' => 'array',
389
+ 'sanitizer' => 'array_intersect',
390
+ 'options' => array(
391
+ 'post',
392
+ 'page',
393
+ 'attachment',
394
+ ),
395
+ ),
396
+ 'automatic_share_postfix' => array(
397
+ 'type' => 'string',
398
+ 'sanitizer' => 'kses_post',
399
+ ),
400
+ 'automatic_share_prefix' => array(
401
+ 'type' => 'string',
402
+ 'sanitizer' => 'kses_post',
403
+ ),
404
+ 'automatic_share_single' => array(
405
+ 'type' => 'boolean',
406
+ 'sanitizer' => null,
407
+ ),
408
+ 'custom_style' => array(
409
+ 'type' => 'string',
410
+ 'sanitizer' => 'esc_style',
411
+ ),
412
+ 'buttons_alignment_follow' => array(
413
+ 'type' => 'string',
414
+ 'sanitizer' => 'in_array',
415
+ 'options' => array(
416
+ 'center',
417
+ 'left',
418
+ 'none',
419
+ 'right',
420
+ ),
421
+ ),
422
+ 'buttons_alignment_share' => array(
423
+ 'type' => 'string',
424
+ 'sanitizer' => 'in_array',
425
+ 'options' => array(
426
+ 'center',
427
+ 'left',
428
+ 'none',
429
+ 'right',
430
+ ),
431
+ ),
432
+ 'buttons_container' => array(
433
+ 'type' => 'string',
434
+ 'sanitizer' => 'in_array',
435
+ 'options' => array(
436
+ 'both',
437
+ 'follow',
438
+ 'none',
439
+ 'share',
440
+ ),
441
+ ),
442
+ 'buttons_container_type' => array(
443
+ 'type' => 'string',
444
+ 'sanitizer' => 'in_array',
445
+ 'options' => array(
446
+ 'basic',
447
+ 'block',
448
+ ),
449
+ ),
450
+ 'facebook_display' => array(
451
+ 'type' => 'string',
452
+ 'sanitizer' => 'in_array',
453
+ 'options' => array(
454
+ 'both',
455
+ 'follow',
456
+ 'none',
457
+ 'share',
458
+ ),
459
+ ),
460
+ 'facebook_follow_link' => array(
461
+ 'type' => 'string',
462
+ 'sanitizer' => 'esc_url',
463
+ ),
464
+ 'facebook_follow_title' => array(
465
+ 'type' => 'string',
466
+ 'sanitizer' => 'esc_html',
467
+ ),
468
+ 'facebook_share_link' => array(
469
+ 'type' => 'string',
470
+ 'sanitizer' => 'esc_url',
471
+ ),
472
+ 'facebook_share_title' => array(
473
+ 'type' => 'string',
474
+ 'sanitizer' => 'esc_html',
475
+ ),
476
+ 'fb_app_id' => array(
477
+ 'type' => 'string',
478
+ 'sanitizer' => 'numeric',
479
+ ),
480
+ 'flickr_display' => array(
481
+ 'type' => 'string',
482
+ 'sanitizer' => 'in_array',
483
+ 'options' => array(
484
+ 'follow',
485
+ 'none',
486
+ ),
487
+ ),
488
+ 'flickr_follow_link' => array(
489
+ 'type' => 'string',
490
+ 'sanitizer' => 'esc_url',
491
+ ),
492
+ 'flickr_follow_title' => array(
493
+ 'type' => 'string',
494
+ 'sanitizer' => 'esc_html',
495
+ ),
496
+ 'foursquare_display' => array(
497
+ 'type' => 'string',
498
+ 'sanitizer' => 'in_array',
499
+ 'options' => array(
500
+ 'follow',
501
+ 'none',
502
+ ),
503
+ ),
504
+ 'foursquare_follow_link' => array(
505
+ 'type' => 'string',
506
+ 'sanitizer' => 'esc_url',
507
+ ),
508
+ 'foursquare_follow_title' => array(
509
+ 'type' => 'string',
510
+ 'sanitizer' => 'esc_html',
511
+ ),
512
+ 'hide_sharethis_terms' => array(
513
+ 'type' => 'boolean',
514
+ 'sanitizer' => null,
515
+ ),
516
+ 'icon_resolution' => array(
517
+ 'type' => 'string',
518
+ 'sanitizer' => 'in_array',
519
+ 'options' => array(
520
+ 'double',
521
+ 'single',
522
+ ),
523
+ ),
524
+ 'icon_size' => array(
525
+ 'type' => 'number',
526
+ 'sanitizer' => null,
527
+ ),
528
+ 'icon_skin' => array(
529
+ 'type' => 'string',
530
+ 'sanitizer' => 'in_array',
531
+ 'options' => array(
532
+ 'balloon',
533
+ 'clearslate',
534
+ 'circle',
535
+ 'darkslate',
536
+ 'flag',
537
+ 'medal',
538
+ 'regular',
539
+ 'shed',
540
+ 'wheel',
541
+ ),
542
+ ),
543
+ 'icon_spacing' => array(
544
+ 'type' => 'number',
545
+ 'sanitizer' => null,
546
+ ),
547
+ 'instagram_display' => array(
548
+ 'type' => 'string',
549
+ 'sanitizer' => 'in_array',
550
+ 'options' => array(
551
+ 'follow',
552
+ 'none',
553
+ ),
554
+ ),
555
+ 'instagram_follow_link' => array(
556
+ 'type' => 'string',
557
+ 'sanitizer' => 'esc_url',
558
+ ),
559
+ 'instagram_follow_title' => array(
560
+ 'type' => 'string',
561
+ 'sanitizer' => 'esc_html',
562
+ ),
563
+ 'layout_rtl' => array(
564
+ 'type' => 'boolean',
565
+ 'sanitizer' => null,
566
+ ),
567
+ 'linkedin_display' => array(
568
+ 'type' => 'string',
569
+ 'sanitizer' => 'in_array',
570
+ 'options' => array(
571
+ 'both',
572
+ 'follow',
573
+ 'none',
574
+ 'share',
575
+ ),
576
+ ),
577
+ 'linkedin_follow_link' => array(
578
+ 'type' => 'string',
579
+ 'sanitizer' => 'esc_url',
580
+ ),
581
+ 'linkedin_follow_title' => array(
582
+ 'type' => 'string',
583
+ 'sanitizer' => 'esc_html',
584
+ ),
585
+ 'linkedin_share_link' => array(
586
+ 'type' => 'string',
587
+ 'sanitizer' => 'esc_url',
588
+ ),
589
+ 'linkedin_share_title' => array(
590
+ 'type' => 'string',
591
+ 'sanitizer' => 'esc_html',
592
+ ),
593
+ 'mail_display' => array(
594
+ 'type' => 'string',
595
+ 'sanitizer' => 'in_array',
596
+ 'options' => array(
597
+ 'both',
598
+ 'follow',
599
+ 'none',
600
+ 'share',
601
+ ),
602
+ ),
603
+ 'mail_follow_link' => array(
604
+ 'type' => 'string',
605
+ 'sanitizer' => 'esc_url',
606
+ ),
607
+ 'mail_follow_title' => array(
608
+ 'type' => 'string',
609
+ 'sanitizer' => 'esc_html',
610
+ ),
611
+ 'mail_share_link' => array(
612
+ 'type' => 'string',
613
+ 'sanitizer' => 'esc_url',
614
+ ),
615
+ 'mail_share_title' => array(
616
+ 'type' => 'string',
617
+ 'sanitizer' => 'esc_html',
618
+ ),
619
+ 'pinterest_display' => array(
620
+ 'type' => 'string',
621
+ 'sanitizer' => 'in_array',
622
+ 'options' => array(
623
+ 'both',
624
+ 'follow',
625
+ 'none',
626
+ 'share',
627
+ ),
628
+ ),
629
+ 'pinterest_follow_link' => array(
630
+ 'type' => 'string',
631
+ 'sanitizer' => 'esc_url',
632
+ ),
633
+ 'pinterest_follow_title' => array(
634
+ 'type' => 'string',
635
+ 'sanitizer' => 'esc_html',
636
+ ),
637
+ 'pinterest_share_link' => array(
638
+ 'type' => 'string',
639
+ 'sanitizer' => 'esc_url',
640
+ ),
641
+ 'pinterest_share_title' => array(
642
+ 'type' => 'string',
643
+ 'sanitizer' => 'esc_html',
644
+ ),
645
+ 'reddit_display' => array(
646
+ 'type' => 'string',
647
+ 'sanitizer' => 'in_array',
648
+ 'options' => array(
649
+ 'none',
650
+ 'share',
651
+ ),
652
+ ),
653
+ 'reddit_share_link' => array(
654
+ 'type' => 'string',
655
+ 'sanitizer' => 'esc_url',
656
+ ),
657
+ 'reddit_share_title' => array(
658
+ 'type' => 'string',
659
+ 'sanitizer' => 'esc_html',
660
+ ),
661
+ 'rss_display' => array(
662
+ 'type' => 'string',
663
+ 'sanitizer' => 'in_array',
664
+ 'options' => array(
665
+ 'follow',
666
+ 'none',
667
+ ),
668
+ ),
669
+ 'rss_follow_link' => array(
670
+ 'type' => 'string',
671
+ 'sanitizer' => 'esc_url',
672
+ ),
673
+ 'rss_follow_title' => array(
674
+ 'type' => 'string',
675
+ 'sanitizer' => 'esc_html',
676
+ ),
677
+ 'share_full_url' => array(
678
+ 'type' => 'boolean',
679
+ 'sanitizer' => null,
680
+ ),
681
+ 'share_message_default' => array(
682
+ 'type' => 'string',
683
+ 'sanitizer' => 'esc_html',
684
+ ),
685
+ 'shortcode_widgets' => array(
686
+ 'type' => 'boolean',
687
+ 'sanitizer' => null,
688
+ ),
689
+ 'show_credit' => array(
690
+ 'type' => 'boolean',
691
+ 'sanitizer' => null,
692
+ ),
693
+ 'tumblr_display' => array(
694
+ 'type' => 'string',
695
+ 'sanitizer' => 'in_array',
696
+ 'options' => array(
697
+ 'both',
698
+ 'follow',
699
+ 'none',
700
+ 'share',
701
+ ),
702
+ ),
703
+ 'tumblr_follow_link' => array(
704
+ 'type' => 'string',
705
+ 'sanitizer' => 'esc_url',
706
+ ),
707
+ 'tumblr_follow_title' => array(
708
+ 'type' => 'string',
709
+ 'sanitizer' => 'esc_html',
710
+ ),
711
+ 'tumblr_share_link' => array(
712
+ 'type' => 'string',
713
+ 'sanitizer' => 'esc_url',
714
+ ),
715
+ 'tumblr_share_title' => array(
716
+ 'type' => 'string',
717
+ 'sanitizer' => 'esc_html',
718
+ ),
719
+ 'twitter_display' => array(
720
+ 'type' => 'string',
721
+ 'sanitizer' => 'in_array',
722
+ 'options' => array(
723
+ 'both',
724
+ 'follow',
725
+ 'none',
726
+ 'share',
727
+ ),
728
+ ),
729
+ 'twitter_follow_link' => array(
730
+ 'type' => 'string',
731
+ 'sanitizer' => 'esc_url',
732
+ ),
733
+ 'twitter_follow_title' => array(
734
+ 'type' => 'string',
735
+ 'sanitizer' => 'esc_html',
736
+ ),
737
+ 'twitter_share_link' => array(
738
+ 'type' => 'string',
739
+ 'sanitizer' => 'esc_url',
740
+ ),
741
+ 'twitter_share_title' => array(
742
+ 'type' => 'string',
743
+ 'sanitizer' => 'esc_html',
744
+ ),
745
+ 'use_shortlinks' => array(
746
+ 'type' => 'boolean',
747
+ 'sanitizer' => null,
748
+ ),
749
+ 'vimeo_display' => array(
750
+ 'type' => 'string',
751
+ 'sanitizer' => 'in_array',
752
+ 'options' => array(
753
+ 'follow',
754
+ 'none',
755
+ ),
756
+ ),
757
+ 'vimeo_follow_link' => array(
758
+ 'type' => 'string',
759
+ 'sanitizer' => 'esc_url',
760
+ ),
761
+ 'vimeo_follow_title' => array(
762
+ 'type' => 'string',
763
+ 'sanitizer' => 'esc_html',
764
+ ),
765
+ 'youtube_display' => array(
766
+ 'type' => 'string',
767
+ 'sanitizer' => 'in_array',
768
+ 'options' => array(
769
+ 'follow',
770
+ 'none',
771
+ ),
772
+ ),
773
+ 'youtube_follow_link' => array(
774
+ 'type' => 'string',
775
+ 'sanitizer' => 'esc_url',
776
+ ),
777
+ 'youtube_follow_title' => array(
778
+ 'type' => 'string',
779
+ 'sanitizer' => 'esc_html',
780
+ ),
781
+ );
782
+ }
783
+
784
+ /**
785
+ * Show admin notices.
786
+ *
787
+ * @action admin_notices
788
+ */
789
+ public function show_sharethis_terms() {
790
+ $can_show_share_this_alert =
791
+ false === self::get_social_option( 'accepted_sharethis_terms', false )
792
+ && false === self::get_social_option( 'hide_sharethis_terms', false );
793
+
794
+ if ( true === $can_show_share_this_alert ) {
795
+ self::show_terms_notice();
796
+ }
797
+ }
798
+
799
+ /**
800
+ * Get Social Option by name with fallback default value.
801
+ *
802
+ * @param string $name Option name.
803
+ * @param mixed $default Option fallback value in case value not set.
804
+ *
805
+ * @return mixed|null
806
+ */
807
+ public static function get_social_option( $name, $default = null ) {
808
+ $social_settings = get_option( 'synved_social_settings' );
809
+
810
+ if ( true === empty( $social_settings[ $name ] ) ) {
811
+ return $default;
812
+ }
813
+
814
+ return $social_settings[ $name ];
815
+ }
816
+
817
+ /**
818
+ * Show terms notice.
819
+ *
820
+ * @param bool $render_html Whether to render HTML.
821
+ * @param bool $is_dismissible Whether notice is dismissable.
822
+ *
823
+ * @return string|void
824
+ */
825
+ public static function show_terms_notice( $render_html = true, $is_dismissible = true ) {
826
+ $out = '<div id="sharethis_terms_notice" class="notice-warning notice ' . esc_attr( false === empty( $is_dismissible ) ? 'is-dismissible' : '' ) . '">
827
+ <p>
828
+ To get the most out of Social Media Feather and to help enable its continued development,
829
+ please read the <a href="//sharethis.com/terms" target="_blank">ShareThis Terms of Service</a> and <a href="//sharethis.com/privacy" target="_blank">Privacy Notice</a>,
830
+ then <a href="' . esc_url( admin_url( 'options-general.php?page=social-media-feather-settings&accept-terms=yes' ) ) . '">click here to accept the terms</a>.
831
+ </p>
832
+ </div>
833
+ ';
834
+
835
+ if ( $render_html ) {
836
+ echo wp_kses( $out, synved_get_allowed_html_array() );
837
+ } else {
838
+ return wp_kses( $out, synved_get_allowed_html_array() );
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Print Styles.
844
+ *
845
+ * @action wp_head
846
+ */
847
+ public function print_styles() {
848
+ if ( true === is_admin() ) {
849
+ return;
850
+ }
851
+
852
+ ob_start();
853
+
854
+ // NOTE: Runs through escaping function on the way out!
855
+ // phpcs:ignore
856
+ echo <<<HEAD_STYLE
857
+ <style>
858
+ .synved-social-resolution-single {
859
+ display: inline-block;
860
+ }
861
+ .synved-social-resolution-normal {
862
+ display: inline-block;
863
+ }
864
+ .synved-social-resolution-hidef {
865
+ display: none;
866
+ }
867
+
868
+ @media only screen and (min--moz-device-pixel-ratio: 2),
869
+ only screen and (-o-min-device-pixel-ratio: 2/1),
870
+ only screen and (-webkit-min-device-pixel-ratio: 2),
871
+ only screen and (min-device-pixel-ratio: 2),
872
+ only screen and (min-resolution: 2dppx),
873
+ only screen and (min-resolution: 192dpi) {
874
+ .synved-social-resolution-normal {
875
+ display: none;
876
+ }
877
+ .synved-social-resolution-hidef {
878
+ display: inline-block;
879
+ }
880
+ }
881
+ </style>
882
+ HEAD_STYLE;
883
+
884
+ $styles = ob_get_clean();
885
+
886
+ echo wp_kses(
887
+ $styles,
888
+ array(
889
+ 'style' => array(),
890
+ )
891
+ );
892
+ }
893
+
894
+ /**
895
+ * Enqueue scripts.
896
+ *
897
+ * @action wp_enqueue_scripts
898
+ */
899
+ public function enqueue_scripts() {
900
+ if ( false === is_admin() && true === self::get_social_option( 'accepted_sharethis_terms', false ) ) {
901
+ if ( true === is_ssl() ) {
902
+ $st_insights = 'https://ws.sharethis.com/button/st_insights.js';
903
+ } else {
904
+ $st_insights = 'http://w.sharethis.com/button/st_insights.js';
905
+ }
906
+
907
+ $url = add_query_arg(
908
+ array(
909
+ 'publisher' => 'eba0f3ba-f9ab-408c-bc68-c28af5afe749',
910
+ 'product' => 'feather',
911
+ ),
912
+ $st_insights
913
+ );
914
+
915
+ wp_enqueue_script(
916
+ 'feather-sharethis',
917
+ $url,
918
+ null,
919
+ filemtime( SOCIAL_MEDIA_FEATHER_PLUGIN_MAIN_FILE ),
920
+ false
921
+ );
922
+
923
+ add_filter( 'script_loader_tag', 'synved_social_wp_script_loader_tag', 10, 2 );
924
+ }
925
+ }
926
+ }
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: socialmediafeather, scottstorebloom, scottmweaver
3
  Tags: social media, social sharing, social buttons, Facebook, Share, Like, twitter, google, Reddit, youtube, instagram, pinterest, social media buttons, button, shortcode, sidebar, sharing buttons, follow buttons
4
  Requires at least: 3.1
5
- Tested up to: 5.9
6
- Stable tag: 2.0.6
7
- Version: 2.0.6
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -190,6 +190,13 @@ margin-left: 10px;
190
 
191
  == Changelog ==
192
 
 
 
 
 
 
 
 
193
  = 2.0.6 =
194
  * Update screenshots.
195
 
2
  Contributors: socialmediafeather, scottstorebloom, scottmweaver
3
  Tags: social media, social sharing, social buttons, Facebook, Share, Like, twitter, google, Reddit, youtube, instagram, pinterest, social media buttons, button, shortcode, sidebar, sharing buttons, follow buttons
4
  Requires at least: 3.1
5
+ Tested up to: 5.9.1
6
+ Stable tag: 2.1.0
7
+ Version: 2.1.0
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
190
 
191
  == Changelog ==
192
 
193
+ = 2.1.0 =
194
+ * New settings interface.
195
+ * Sanitize everything!
196
+
197
+ = 2.0.7 =
198
+ * Add more sanitization.
199
+
200
  = 2.0.6 =
201
  * Update screenshots.
202
 
social-media-feather.php CHANGED
@@ -1,62 +1,74 @@
1
  <?php
2
- /*
3
- Plugin Name: Social Media Feather
4
- Contributors: scottstorebloom, scottmweaver, socialmediafeather
5
- Plugin URI: http://socialmediafeather.com/
6
- Description: Super lightweight social media plugin to add nice and effective social media sharing and following buttons and icons anywhere on your site quickly and easily.
7
- Author: socialmediafeather
8
- Version: 2.0.6
9
- Author URI: http://socialmediafeather.com/
10
- */
 
 
11
 
12
  define( 'SOCIAL_MEDIA_FEATHER_PLUGIN_DIRECTORY', plugin_dir_path( __FILE__ ) );
 
13
 
14
- const SYNVED_VERSION = '2.0.6';
15
 
16
- if (false === function_exists('synved_wp_social_load'))
17
- {
18
- function synved_wp_social_load()
19
- {
 
 
 
 
 
20
  global $plugin;
21
 
22
  $path = __FILE__;
23
 
24
- if (true === defined('SYNVED_SOCIAL_INCLUDE_PATH')) {
25
  $path = SYNVED_SOCIAL_INCLUDE_PATH;
26
- } elseif (isset($plugin)) {
27
  /* This is mostly for symlink support */
28
- $real_plugin = realpath($plugin);
29
 
30
- if (strtolower($real_plugin) == strtolower(__FILE__)) {
31
  $path = $plugin;
32
  }
33
  }
34
 
35
- $dir = dirname($path) . DIRECTORY_SEPARATOR;
36
 
37
- if (false === function_exists('synved_plugout_module_import'))
38
- {
39
- include($dir . 'synved-plugout' . DIRECTORY_SEPARATOR . 'synved-plugout.php');
40
  }
41
 
 
 
 
42
  /* Register used modules */
43
- synved_plugout_module_register('synved-connect');
44
- synved_plugout_module_path_add('synved-connect', 'core', $dir . 'synved-connect');
45
- synved_plugout_module_register('synved-option');
46
- synved_plugout_module_path_add('synved-option', 'core', $dir . 'synved-option');
47
- synved_plugout_module_register('synved-social');
48
- synved_plugout_module_path_add('synved-social', 'core', $dir . 'synved-social');
49
- synved_plugout_module_path_add('synved-social', 'provider', __FILE__);
50
 
51
  /* Import modules */
52
- synved_plugout_module_import('synved-connect');
53
- synved_plugout_module_import('synved-option');
54
- synved_plugout_module_import('synved-social');
55
  }
56
 
57
  synved_wp_social_load();
58
  }
59
 
60
- synved_plugout_module_path_add('synved-connect', 'addon', dirname((defined('SYNVED_SOCIAL_INCLUDE_PATH') ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__)) . '/synved-connect/addons');
61
- synved_plugout_module_path_add('synved-option', 'addon', dirname((defined('SYNVED_SOCIAL_INCLUDE_PATH') ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__)) . '/synved-option/addons');
62
- synved_plugout_module_path_add('synved-social', 'addon', dirname((defined('SYNVED_SOCIAL_INCLUDE_PATH') ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__)) . '/synved-social/addons');
 
 
1
  <?php
2
+ /**
3
+ * Plugin Name: Social Media Feather
4
+ * Contributors: scottstorebloom, scottmweaver, socialmediafeather
5
+ * Plugin URI: https://sharethis.com/platform/wordpress-social-media-feather/
6
+ * Description: Super lightweight social media plugin to add nice and effective social media sharing and following buttons and icons anywhere on your site quickly and easily.
7
+ * Author: socialmediafeather
8
+ * Version: 2.1.0
9
+ * Author URI: https://sharethis.com/platform/wordpress-social-media-feather/
10
+ *
11
+ * @package SocialMediaFeather
12
+ */
13
 
14
  define( 'SOCIAL_MEDIA_FEATHER_PLUGIN_DIRECTORY', plugin_dir_path( __FILE__ ) );
15
+ define( 'SOCIAL_MEDIA_FEATHER_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
16
 
17
+ const SOCIAL_MEDIA_FEATHER_PLUGIN_MAIN_FILE = __FILE__;
18
 
19
+ const SYNVED_VERSION = '2.1.0';
20
+
21
+ if ( false === function_exists( 'synved_wp_social_load' ) ) {
22
+ /**
23
+ * WP Social Load.
24
+ *
25
+ * @return void
26
+ */
27
+ function synved_wp_social_load() {
28
  global $plugin;
29
 
30
  $path = __FILE__;
31
 
32
+ if ( true === defined( 'SYNVED_SOCIAL_INCLUDE_PATH' ) ) {
33
  $path = SYNVED_SOCIAL_INCLUDE_PATH;
34
+ } elseif ( isset( $plugin ) ) {
35
  /* This is mostly for symlink support */
36
+ $real_plugin = realpath( $plugin );
37
 
38
+ if ( strtolower( $real_plugin ) === strtolower( __FILE__ ) ) {
39
  $path = $plugin;
40
  }
41
  }
42
 
43
+ $dir = dirname( $path ) . DIRECTORY_SEPARATOR;
44
 
45
+ if ( false === function_exists( 'synved_plugout_module_import' ) ) {
46
+ include $dir . 'synved-plugout' . DIRECTORY_SEPARATOR . 'synved-plugout.php';
 
47
  }
48
 
49
+ // Load extra icons.
50
+ include_once SOCIAL_MEDIA_FEATHER_PLUGIN_DIRECTORY . 'synved-social/addons/extra-icons/extra-icons.php';
51
+
52
  /* Register used modules */
53
+ synved_plugout_module_register( 'synved-connect' );
54
+ synved_plugout_module_path_add( 'synved-connect', 'core', $dir . 'synved-connect' );
55
+ synved_plugout_module_register( 'synved-option' );
56
+ synved_plugout_module_path_add( 'synved-option', 'core', $dir . 'synved-option' );
57
+ synved_plugout_module_register( 'synved-social' );
58
+ synved_plugout_module_path_add( 'synved-social', 'core', $dir . 'synved-social' );
59
+ synved_plugout_module_path_add( 'synved-social', 'provider', __FILE__ );
60
 
61
  /* Import modules */
62
+ synved_plugout_module_import( 'synved-connect' );
63
+ synved_plugout_module_import( 'synved-option' );
64
+ synved_plugout_module_import( 'synved-social' );
65
  }
66
 
67
  synved_wp_social_load();
68
  }
69
 
70
+ synved_plugout_module_path_add( 'synved-connect', 'addon', dirname( ( defined( 'SYNVED_SOCIAL_INCLUDE_PATH' ) ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__ ) ) . '/synved-connect/addons' );
71
+ synved_plugout_module_path_add( 'synved-option', 'addon', dirname( ( defined( 'SYNVED_SOCIAL_INCLUDE_PATH' ) ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__ ) ) . '/synved-option/addons' );
72
+ synved_plugout_module_path_add( 'synved-social', 'addon', dirname( ( defined( 'SYNVED_SOCIAL_INCLUDE_PATH' ) ? SYNVED_SOCIAL_INCLUDE_PATH : __FILE__ ) ) . '/synved-social/addons' );
73
+
74
+ require_once __DIR__ . '/instance.php';
synved-connect/synved-connect-key.php CHANGED
@@ -1,20 +1,29 @@
1
  <?php
 
 
 
 
 
2
 
3
- function synved_connect_key_item_match($item, $item_list)
4
- {
5
- if (is_string($item_list))
6
- {
 
 
 
 
 
 
7
  $item_key = $item_list;
8
 
9
- if ($item == $item_key)
10
- {
11
  return true;
12
  }
13
 
14
  $item_key = '/' . $item_key . '/';
15
 
16
- if (preg_match($item_key, $item))
17
- {
18
  return true;
19
  }
20
  }
1
  <?php
2
+ /**
3
+ * Connect key.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ /**
9
+ * Key item match.
10
+ *
11
+ * @param string $item Item string.
12
+ * @param string $item_list Item list string.
13
+ *
14
+ * @return bool
15
+ */
16
+ function synved_connect_key_item_match( $item, $item_list ) {
17
+ if ( true === is_string( $item_list ) ) {
18
  $item_key = $item_list;
19
 
20
+ if ( $item === $item_key ) {
 
21
  return true;
22
  }
23
 
24
  $item_key = '/' . $item_key . '/';
25
 
26
+ if ( false !== preg_match( $item_key, $item ) ) {
 
27
  return true;
28
  }
29
  }
synved-connect/synved-connect-sponsor.php CHANGED
@@ -1,132 +1,127 @@
1
  <?php
2
-
3
- function synved_connect_sponsor_list($filter = null)
4
- {
 
 
 
 
 
 
 
 
 
 
 
5
  global $synved_connect;
6
 
7
  $sponsor_list = array(
8
  'wordpress-themes-1' => array(
9
- 'type' => 'credit',
10
  'label' => 'WordPress Themes',
11
- 'tip' => 'WordPress plugins and themes',
12
- 'link' => 'https://synved.com',
13
- 'text' => '%%link%% by Synved'
14
  ),
15
  'wordpress-design-1' => array(
16
- 'type' => 'credit',
17
  'label' => 'WordPress Design',
18
- 'tip' => 'WordPress development, themes and custom plugins',
19
- 'link' => 'https://synved.com',
20
- 'text' => '%%link%% by Synved'
21
  ),
22
- 'synved-options' => array(
23
- 'type' => 'intern',
24
  'label' => 'WordPress Options',
25
- 'tip' => 'Add options to your products, the easy way!',
26
- 'link' => 'https://synved.com/wordpress-options/',
27
- 'text' => 'If you are a designer or developer you might want to chek out our free plugin %%link%% to easily add options to your WordPress products and sell your own addons for them too'
28
  ),
29
- 'hosting-1' => array(
30
- 'type' => 'extern',
31
  'label' => 'professional hosting',
32
- 'tip' => 'recommended hosting',
33
- 'link' => 'https://synved.com/suggests/hosting/',
34
- 'text' => 'If searching for a reliable hosting service you might wanna check out our recommended %%link%%'
35
  ),
36
- 'photocrati' => array(
37
- 'type' => 'extern',
38
  'label' => 'Photocrati',
39
- 'tip' => 'WordPress theme for gallery management',
40
- 'link' => 'https://synved.com/suggests/photocrati/',
41
- 'text' => 'For more advanced image and gallery management features we recommend %%link%% and their fantastic support ;)'
42
- )
43
  );
44
 
45
- if (isset($synved_connect['sponsor-list']))
46
- {
47
  $sponsor_list = $synved_connect['sponsor-list'];
48
- }
49
- else
50
- {
51
- $feed = fetch_feed('https://feeds.feedburner.com/_SynvedConnectList?format=xml');
52
-
53
- if (!is_wp_error($feed))
54
- {
55
- $maxitems = $feed->get_item_quantity();
56
- $feed_items = $feed->get_items(0, $maxitems);
57
- $feed_list = array();
58
-
59
- if ($maxitems > 0)
60
- {
61
- foreach ($feed_items as $feed_item)
62
- {
63
- $id = $feed_item->get_id();
64
  $label = $feed_item->get_title();
65
- $tip = $feed_item->get_description();
66
- $link = $feed_item->get_permalink();
67
- $text = $feed_item->get_content();
68
 
69
  $id_parts = array();
70
- parse_str(parse_url($id, PHP_URL_QUERY), $id_parts);
71
  $id = $id_parts['guid'];
72
 
73
- $feed_categories = $feed_item->get_categories();
74
- $type = null;
75
 
76
- if ($feed_categories != null)
77
- {
78
- $category_tag = 'synved-connect-type-';
79
 
80
- foreach ($feed_categories as $feed_category)
81
- {
82
- $feed_category = $feed_category->get_label();
83
 
84
- if (substr($feed_category, 0, strlen($category_tag)) == $category_tag)
85
- {
86
- $type = substr($feed_category, strlen($category_tag));
87
 
88
- break;
89
- }
90
- }
91
- }
92
 
93
- if ($type != null && $id != null)
94
- {
95
- $feed_list[$id] = array(
96
- 'type' => $type,
97
  'label' => $label,
98
- 'tip' => $tip,
99
- 'link' => $link,
100
- 'text' => $text
101
  );
102
- }
103
- }
104
- }
105
-
106
- if ($feed_list != null)
107
- {
108
- $sponsor_list = $feed_list;
109
- }
110
  }
111
 
112
  $synved_connect['sponsor-list'] = $sponsor_list;
113
  }
114
 
115
- if ($filter != null)
116
- {
117
  $final_list = array();
118
 
119
- foreach ($sponsor_list as $sponsor_key => $sponsor_item)
120
- {
121
- foreach ($filter as $filter_key => $filter_value)
122
- {
123
- if (isset($sponsor_item[$filter_key]))
124
- {
125
- $sponsor_value = $sponsor_item[$filter_key];
126
-
127
- if (true === synved_connect_key_item_match($sponsor_value, $filter_value))
128
- {
129
- $final_list[$sponsor_key] = $sponsor_item;
130
  }
131
  }
132
  }
@@ -135,35 +130,46 @@ function synved_connect_sponsor_list($filter = null)
135
  $sponsor_list = $final_list;
136
  }
137
 
138
- $sponsor_keys = array_keys($sponsor_list);
139
 
140
- foreach ($sponsor_keys as $sponsor_key)
141
- {
142
- $sponsor_list[$sponsor_key]['id'] = $sponsor_key;
143
  }
144
 
145
  return $sponsor_list;
146
  }
147
 
148
- function synved_connect_sponsor_id_pick($filter = null)
149
- {
150
- $sponsor_list = synved_connect_sponsor_list($filter);
151
- $sponsor_keys = array_keys($sponsor_list);
152
- $count = count($sponsor_keys);
153
-
154
- $index = rand(0, $count - 1);
155
- $sponsor_id = $sponsor_keys[$index];
 
 
 
 
 
 
156
 
157
  return $sponsor_id;
158
  }
159
 
160
- function synved_connect_sponsor_item_by_id($sponsor_id, $filter = null)
161
- {
162
- $sponsor_list = synved_connect_sponsor_list($filter);
 
 
 
 
 
 
 
163
 
164
- if ($sponsor_id != null && isset($sponsor_list[$sponsor_id]))
165
- {
166
- $sponsor = $sponsor_list[$sponsor_id];
167
 
168
  return $sponsor;
169
  }
@@ -171,96 +177,106 @@ function synved_connect_sponsor_item_by_id($sponsor_id, $filter = null)
171
  return null;
172
  }
173
 
174
- function synved_connect_sponsor_item_pick($filter = null)
175
- {
176
- $sponsor_id = synved_connect_sponsor_id_pick($filter);
177
-
178
- return synved_connect_sponsor_item_by_id($sponsor_id);
 
 
 
 
 
 
179
  }
180
 
181
- function synved_connect_sponsor_item($component = null, $filter = null)
182
- {
183
- $sponsor_id = synved_connect_id_get($component);
184
-
185
- return synved_connect_sponsor_item_by_id($sponsor_id, $filter);
 
 
 
 
 
 
 
186
  }
187
 
188
- function synved_connect_sponsor_link(array $sponsor_item = null)
189
- {
190
- if ($sponsor_item == null)
191
- {
 
 
 
 
 
192
  $sponsor_item = synved_connect_sponsor_item();
193
  }
194
 
195
- if ($sponsor_item == null)
196
- {
197
  return null;
198
  }
199
 
200
- $sponsor_label = isset($sponsor_item['label']) ? $sponsor_item['label'] : null;
201
- $sponsor_tip = isset($sponsor_item['tip']) ? $sponsor_item['tip'] : null;
202
- $sponsor_link = isset($sponsor_item['link']) ? $sponsor_item['link'] : null;
203
 
204
  return '<a class="synved-connect-link" href="' . $sponsor_link . '" target="_blank" title="' . $sponsor_tip . '">' . $sponsor_label . '</a>';
205
  }
206
 
207
- function synved_connect_sponsor_content(array $sponsor_item = null)
208
- {
209
- if ($sponsor_item == null)
210
- {
 
 
 
 
 
211
  $sponsor_item = synved_connect_sponsor_item();
212
 
213
- if ($sponsor_item == null)
214
- {
215
  $sponsor_item = synved_connect_sponsor_item_pick();
216
  }
217
  }
218
 
219
- if ($sponsor_item == null)
220
- {
221
  return null;
222
  }
223
 
224
- $sponsor_type = isset($sponsor_item['type']) ? $sponsor_item['type'] : null;
225
- $sponsor_text = isset($sponsor_item['text']) ? $sponsor_item['text'] : null;
226
- $sponsor_markup = isset($sponsor_item['markup']) ? $sponsor_item['markup'] : null;
227
- $sponsor_link = synved_connect_sponsor_link($sponsor_item);
228
 
229
- if ($sponsor_text == null)
230
- {
231
- if ($sponsor_type == 'credit')
232
- {
233
  $sponsor_text = '%%link%% by Synved';
234
- }
235
- else
236
- {
237
  return null;
238
  }
239
  }
240
 
241
- if ($sponsor_markup == null)
242
- {
243
- if ($sponsor_type == 'credit')
244
- {
245
  $sponsor_markup = '<span class="%%class%%">%%content%%</span>';
246
- }
247
- else
248
- {
249
  $sponsor_markup = '<div class="%%class%%">%%content%%</div>';
250
  }
251
  }
252
 
253
  $sponsor_class = 'sponsor-holder';
254
 
255
- if ($sponsor_type != null)
256
- {
257
  $sponsor_class .= ' sponsor-type-' . $sponsor_type;
258
  }
259
 
260
- $sponsor_markup = str_replace('%%class%%', $sponsor_class, $sponsor_markup);
261
 
262
- $sponsor_content = str_replace('%%link%%', $sponsor_link, $sponsor_text);
263
- $sponsor_content = str_replace('%%content%%', $sponsor_content, $sponsor_markup);
264
 
265
- return $sponsor_content;
266
  }
1
  <?php
2
+ /**
3
+ * Connect Sponsor.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Connect sponsor list.
10
+ *
11
+ * @param array $filter Filter array.
12
+ *
13
+ * @return array|mixed|string[][]
14
+ */
15
+ function synved_connect_sponsor_list( $filter = null ) {
16
  global $synved_connect;
17
 
18
  $sponsor_list = array(
19
  'wordpress-themes-1' => array(
20
+ 'type' => 'credit',
21
  'label' => 'WordPress Themes',
22
+ 'tip' => 'WordPress plugins and themes',
23
+ 'link' => 'https://synved.com',
24
+ 'text' => '%%link%% by Synved',
25
  ),
26
  'wordpress-design-1' => array(
27
+ 'type' => 'credit',
28
  'label' => 'WordPress Design',
29
+ 'tip' => 'WordPress development, themes and custom plugins',
30
+ 'link' => 'https://synved.com',
31
+ 'text' => '%%link%% by Synved',
32
  ),
33
+ 'synved-options' => array(
34
+ 'type' => 'intern',
35
  'label' => 'WordPress Options',
36
+ 'tip' => 'Add options to your products, the easy way!',
37
+ 'link' => 'https://synved.com/wordpress-options/',
38
+ 'text' => 'If you are a designer or developer you might want to chek out our free plugin %%link%% to easily add options to your WordPress products and sell your own addons for them too',
39
  ),
40
+ 'hosting-1' => array(
41
+ 'type' => 'extern',
42
  'label' => 'professional hosting',
43
+ 'tip' => 'recommended hosting',
44
+ 'link' => 'https://synved.com/suggests/hosting/',
45
+ 'text' => 'If searching for a reliable hosting service you might wanna check out our recommended %%link%%',
46
  ),
47
+ 'photocrati' => array(
48
+ 'type' => 'extern',
49
  'label' => 'Photocrati',
50
+ 'tip' => 'WordPress theme for gallery management',
51
+ 'link' => 'https://synved.com/suggests/photocrati/',
52
+ 'text' => 'For more advanced image and gallery management features we recommend %%link%% and their fantastic support ;)',
53
+ ),
54
  );
55
 
56
+ if ( true === isset( $synved_connect['sponsor-list'] ) ) {
 
57
  $sponsor_list = $synved_connect['sponsor-list'];
58
+ } else {
59
+ $feed = fetch_feed( 'https://feeds.feedburner.com/_SynvedConnectList?format=xml' );
60
+
61
+ if ( false === is_wp_error( $feed ) ) {
62
+ $maxitems = $feed->get_item_quantity();
63
+ $feed_items = $feed->get_items( 0, $maxitems );
64
+ $feed_list = array();
65
+
66
+ if ( $maxitems > 0 ) {
67
+ foreach ( $feed_items as $feed_item ) {
68
+ $id = $feed_item->get_id();
 
 
 
 
 
69
  $label = $feed_item->get_title();
70
+ $tip = $feed_item->get_description();
71
+ $link = $feed_item->get_permalink();
72
+ $text = $feed_item->get_content();
73
 
74
  $id_parts = array();
75
+ parse_str( wp_parse_url( $id, PHP_URL_QUERY ), $id_parts );
76
  $id = $id_parts['guid'];
77
 
78
+ $feed_categories = $feed_item->get_categories();
79
+ $type = null;
80
 
81
+ if ( false === empty( $feed_categories ) ) {
82
+ $category_tag = 'synved-connect-type-';
 
83
 
84
+ foreach ( $feed_categories as $feed_category ) {
85
+ $feed_category = $feed_category->get_label();
 
86
 
87
+ if ( substr( $feed_category, 0, strlen( $category_tag ) ) === $category_tag ) {
88
+ $type = substr( $feed_category, strlen( $category_tag ) );
 
89
 
90
+ break;
91
+ }
92
+ }
93
+ }
94
 
95
+ if ( false === empty( $type ) && false === empty( $id ) ) {
96
+ $feed_list[ $id ] = array(
97
+ 'type' => $type,
 
98
  'label' => $label,
99
+ 'tip' => $tip,
100
+ 'link' => $link,
101
+ 'text' => $text,
102
  );
103
+ }
104
+ }
105
+ }
106
+
107
+ if ( false === empty( $feed_list ) ) {
108
+ $sponsor_list = $feed_list;
109
+ }
 
110
  }
111
 
112
  $synved_connect['sponsor-list'] = $sponsor_list;
113
  }
114
 
115
+ if ( false === empty( $filter ) ) {
 
116
  $final_list = array();
117
 
118
+ foreach ( $sponsor_list as $sponsor_key => $sponsor_item ) {
119
+ foreach ( $filter as $filter_key => $filter_value ) {
120
+ if ( isset( $sponsor_item[ $filter_key ] ) ) {
121
+ $sponsor_value = $sponsor_item[ $filter_key ];
122
+
123
+ if ( true === synved_connect_key_item_match( $sponsor_value, $filter_value ) ) {
124
+ $final_list[ $sponsor_key ] = $sponsor_item;
 
 
 
 
125
  }
126
  }
127
  }
130
  $sponsor_list = $final_list;
131
  }
132
 
133
+ $sponsor_keys = array_keys( $sponsor_list );
134
 
135
+ foreach ( $sponsor_keys as $sponsor_key ) {
136
+ $sponsor_list[ $sponsor_key ]['id'] = $sponsor_key;
 
137
  }
138
 
139
  return $sponsor_list;
140
  }
141
 
142
+ /**
143
+ * Sponsor ID pick.
144
+ *
145
+ * @param array $filter Filter array.
146
+ *
147
+ * @return int|string
148
+ */
149
+ function synved_connect_sponsor_id_pick( $filter = null ) {
150
+ $sponsor_list = synved_connect_sponsor_list( $filter );
151
+ $sponsor_keys = array_keys( $sponsor_list );
152
+ $count = count( $sponsor_keys );
153
+
154
+ $index = wp_rand( 0, $count - 1 );
155
+ $sponsor_id = $sponsor_keys[ $index ];
156
 
157
  return $sponsor_id;
158
  }
159
 
160
+ /**
161
+ * Sponsor item by id.
162
+ *
163
+ * @param string $sponsor_id Sponsor ID string.
164
+ * @param array $filter Filter array.
165
+ *
166
+ * @return mixed|string[]|null
167
+ */
168
+ function synved_connect_sponsor_item_by_id( $sponsor_id, $filter = null ) {
169
+ $sponsor_list = synved_connect_sponsor_list( $filter );
170
 
171
+ if ( false === empty( $sponsor_id ) && true === isset( $sponsor_list[ $sponsor_id ] ) ) {
172
+ $sponsor = $sponsor_list[ $sponsor_id ];
 
173
 
174
  return $sponsor;
175
  }
177
  return null;
178
  }
179
 
180
+ /**
181
+ * Sponsor item pick.
182
+ *
183
+ * @param array $filter Filter array.
184
+ *
185
+ * @return mixed|string[]|null
186
+ */
187
+ function synved_connect_sponsor_item_pick( $filter = null ) {
188
+ $sponsor_id = synved_connect_sponsor_id_pick( $filter );
189
+
190
+ return synved_connect_sponsor_item_by_id( $sponsor_id );
191
  }
192
 
193
+ /**
194
+ * Sponsor item.
195
+ *
196
+ * @param string $component Component string.
197
+ * @param array $filter Filter array.
198
+ *
199
+ * @return mixed|string[]|null
200
+ */
201
+ function synved_connect_sponsor_item( $component = null, $filter = null ) {
202
+ $sponsor_id = synved_connect_id_get( $component );
203
+
204
+ return synved_connect_sponsor_item_by_id( $sponsor_id, $filter );
205
  }
206
 
207
+ /**
208
+ * Sponsor link.
209
+ *
210
+ * @param array|null $sponsor_item Sponsor item array.
211
+ *
212
+ * @return string|null
213
+ */
214
+ function synved_connect_sponsor_link( array $sponsor_item = null ) {
215
+ if ( true === empty( $sponsor_item ) ) {
216
  $sponsor_item = synved_connect_sponsor_item();
217
  }
218
 
219
+ if ( true === empty( $sponsor_item ) ) {
 
220
  return null;
221
  }
222
 
223
+ $sponsor_label = true === isset( $sponsor_item['label'] ) ? $sponsor_item['label'] : null;
224
+ $sponsor_tip = true === isset( $sponsor_item['tip'] ) ? $sponsor_item['tip'] : null;
225
+ $sponsor_link = true === isset( $sponsor_item['link'] ) ? $sponsor_item['link'] : null;
226
 
227
  return '<a class="synved-connect-link" href="' . $sponsor_link . '" target="_blank" title="' . $sponsor_tip . '">' . $sponsor_label . '</a>';
228
  }
229
 
230
+ /**
231
+ * Sponsor content.
232
+ *
233
+ * @param array|null $sponsor_item Sponsor array.
234
+ *
235
+ * @return array|string|string[]|null
236
+ */
237
+ function synved_connect_sponsor_content( array $sponsor_item = null ) {
238
+ if ( true === empty( $sponsor_item ) ) {
239
  $sponsor_item = synved_connect_sponsor_item();
240
 
241
+ if ( true === empty( $sponsor_item ) ) {
 
242
  $sponsor_item = synved_connect_sponsor_item_pick();
243
  }
244
  }
245
 
246
+ if ( true === empty( $sponsor_item ) ) {
 
247
  return null;
248
  }
249
 
250
+ $sponsor_type = true === isset( $sponsor_item['type'] ) ? $sponsor_item['type'] : null;
251
+ $sponsor_text = true === isset( $sponsor_item['text'] ) ? $sponsor_item['text'] : null;
252
+ $sponsor_markup = true === isset( $sponsor_item['markup'] ) ? $sponsor_item['markup'] : null;
253
+ $sponsor_link = synved_connect_sponsor_link( $sponsor_item );
254
 
255
+ if ( true === empty( $sponsor_text ) ) {
256
+ if ( 'credit' === $sponsor_type ) {
 
 
257
  $sponsor_text = '%%link%% by Synved';
258
+ } else {
 
 
259
  return null;
260
  }
261
  }
262
 
263
+ if ( true === empty( $sponsor_markup ) ) {
264
+ if ( 'credit' === $sponsor_type ) {
 
 
265
  $sponsor_markup = '<span class="%%class%%">%%content%%</span>';
266
+ } else {
 
 
267
  $sponsor_markup = '<div class="%%class%%">%%content%%</div>';
268
  }
269
  }
270
 
271
  $sponsor_class = 'sponsor-holder';
272
 
273
+ if ( false === empty( $sponsor_type ) ) {
 
274
  $sponsor_class .= ' sponsor-type-' . $sponsor_type;
275
  }
276
 
277
+ $sponsor_markup = str_replace( '%%class%%', $sponsor_class, $sponsor_markup );
278
 
279
+ $sponsor_content = str_replace( '%%link%%', $sponsor_link, $sponsor_text );
 
280
 
281
+ return str_replace( '%%content%%', $sponsor_content, $sponsor_markup );
282
  }
synved-connect/synved-connect-support.php CHANGED
@@ -1,31 +1,40 @@
1
  <?php
 
 
 
 
 
2
 
3
- function synved_connect_support_social_follow_render()
4
- {
5
- $uri = synved_connect_path_uri();
 
 
 
 
6
 
7
- $out = null;
8
 
9
- $out .= '<div class="synved-connect-notice" style="position:fixed; right:30px; bottom:35px; width:220px; background:#ececec; font-size:110%; color:#444;">';
10
 
11
- if (empty(get_option('smf-hide-review'))) {
12
- $out .= '<div class="smf-review-us">';
13
- $out .= '<h3>';
14
- $out .= esc_html__('Love this plugin?', 'synved-connect');
15
- $out .= '<p>';
16
- $out .= '<a href="https://wordpress.org/support/plugin/social-media-feather/reviews/#new-post" target="_blank">';
17
- $out .= esc_html__(
18
- 'Please spread the word by leaving us a 5 star review!',
19
- 'synved-connect'
20
- );
21
- $out .= '</a>';
22
- $out .= '</p>';
23
- $out .= '<div id="close-review-us">close</div>';
24
- $out .= '</h3>';
25
- $out .= '</div>';
26
- }
27
 
28
- $out .= '</div>';
29
 
30
- return $out;
31
  }
1
  <?php
2
+ /**
3
+ * Connect support.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ /**
9
+ * Social follow render.
10
+ *
11
+ * @return string
12
+ */
13
+ function synved_connect_support_social_follow_render() {
14
+ $uri = synved_connect_path_uri();
15
 
16
+ $out = null;
17
 
18
+ $out .= '<div class="synved-connect-notice" style="z-index: 999; position:fixed; right:30px; bottom:35px; width:220px; background:#ececec; font-size:110%; color:#444;">';
19
 
20
+ if ( true === empty( get_option( 'smf-hide-review' ) ) ) {
21
+ $out .= '<div class="smf-review-us">';
22
+ $out .= '<h3>';
23
+ $out .= esc_html__( 'Love this plugin?', 'synved-connect' );
24
+ $out .= '<p>';
25
+ $out .= '<a href="https://wordpress.org/support/plugin/social-media-feather/reviews/#new-post" target="_blank">';
26
+ $out .= esc_html__(
27
+ 'Please spread the word by leaving us a 5 star review!',
28
+ 'synved-connect'
29
+ );
30
+ $out .= '</a>';
31
+ $out .= '</p>';
32
+ $out .= '<div id="close-review-us">close</div>';
33
+ $out .= '</h3>';
34
+ $out .= '</div>';
35
+ }
36
 
37
+ $out .= '</div>';
38
 
39
+ return $out;
40
  }
synved-connect/synved-connect.php CHANGED
@@ -1,49 +1,53 @@
1
  <?php
2
- /*
3
- Module Name: Synved Connect
4
- Description: Connect and sync components in a WordPress installation with a remote server
5
- Author: Synved
6
- Version: 1.0.4
7
- Author URI: http://synved.com/
8
- License: GPLv2
9
-
10
- LEGAL STATEMENTS
11
-
12
- NO WARRANTY
13
- All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
14
-
15
- NO LIABILITY
16
- In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
17
- */
 
 
18
 
19
  define( 'SYNVED_CONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
20
 
21
  const SYNVED_WP_MODERN_VERSION = '4.1';
22
 
23
- include_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-key.php';
24
- include_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-support.php';
25
- include_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-sponsor.php';
26
 
27
- $synved_connect = [];
28
 
29
- function synved_connect_path_uri($path = null)
30
- {
31
- $uri = plugins_url('/synved-wp-connect') . '/synved-connect';
 
 
 
 
 
 
32
 
33
- if (function_exists('synved_plugout_module_uri_get'))
34
- {
35
- $mod_uri = synved_plugout_module_uri_get('synved-connect');
36
 
37
- if ($mod_uri != null)
38
- {
39
  $uri = $mod_uri;
40
  }
41
  }
42
 
43
- if ($path != null)
44
- {
45
- if (substr($uri, -1) != '/' && $path[0] != '/')
46
- {
47
  $uri .= '/';
48
  }
49
 
@@ -53,35 +57,43 @@ function synved_connect_path_uri($path = null)
53
  return $uri;
54
  }
55
 
56
- function synved_connect_id_get($component = null, $part = null)
57
- {
 
 
 
 
 
 
 
58
  $option_key = 'default';
59
 
60
- if ($component != null)
61
- {
62
  $option_key = 'component_' . $component;
63
  }
64
 
65
- $id = get_option('synved_connect_id_' . $option_key);
66
-
67
- return $id;
68
  }
69
 
70
- function synved_connect_enqueue_scripts()
71
- {
 
 
 
 
72
  $uri = synved_connect_path_uri();
73
- $dir = plugin_dir_path(__FILE__);
74
 
75
  wp_register_style(
76
  'synved-connect-admin',
77
  $uri . '/style/admin.css',
78
  false,
79
- filemtime($dir . '/style/admin.css')
80
  );
81
 
82
- wp_enqueue_style('synved-connect-admin');
83
 
84
- if ( version_compare( get_bloginfo( 'version' ), SYNVED_WP_MODERN_VERSION, 'lt' ) ) {
85
  wp_register_style(
86
  'synved-connect-old-wp-support-css',
87
  $uri . '/style/synved_old_wp_support.css',
@@ -93,24 +105,30 @@ function synved_connect_enqueue_scripts()
93
  }
94
  }
95
 
 
 
 
 
 
96
  function synved_connect_init() {
97
  $install_date = get_option( 'synved_connect_install_date' );
98
 
99
  // Fresh installation.
100
- if ( ! $install_date ) {
101
  update_option( 'synved_connect_install_date', time() );
102
  update_option( 'synved_version', SYNVED_VERSION );
103
  synved_option_set( 'synved_social', 'accepted_sharethis_terms', false );
104
  }
105
 
106
  $version = get_option( 'synved_version' );
107
- if ( $version !== SYNVED_VERSION ) {
108
  synved_connect_upgrade( $version );
109
  }
110
  }
111
 
112
  /**
113
  * Upgrades the plugin.
 
114
  * @param string $version The current version.
115
  * @return void
116
  */
@@ -124,11 +142,15 @@ function synved_connect_upgrade( $version ) {
124
 
125
  add_action( 'init', 'synved_connect_init', 9 );
126
  add_action( 'admin_enqueue_scripts', 'synved_connect_enqueue_scripts' );
127
- add_action('wp_ajax_smf_ajax_hide_review', 'smfHideReview');
128
 
129
- function smfHideReview()
130
- {
131
- update_option('smf-hide-review', true);
 
 
 
 
132
 
133
- wp_send_json_success('hidden');
134
  }
1
  <?php
2
+ /**
3
+ * Module Name: Synved Connect
4
+ * Description: Connect and sync components in a WordPress installation with a remote server
5
+ * Author: Synved
6
+ * Version: 1.0.4
7
+ * Author URI: http://synved.com/
8
+ * License: GPLv2
9
+ *
10
+ * LEGAL STATEMENTS
11
+ *
12
+ * NO WARRANTY
13
+ * All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
14
+ *
15
+ * NO LIABILITY
16
+ * In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
17
+ *
18
+ * @package SocialMediaFeather
19
+ */
20
 
21
  define( 'SYNVED_CONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
22
 
23
  const SYNVED_WP_MODERN_VERSION = '4.1';
24
 
25
+ require_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-key.php';
26
+ require_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-support.php';
27
+ require_once SYNVED_CONNECT_PLUGIN_PATH . 'synved-connect-sponsor.php';
28
 
29
+ $synved_connect = array();
30
 
31
+ /**
32
+ * Path URI.
33
+ *
34
+ * @param string $path Path string.
35
+ *
36
+ * @return string
37
+ */
38
+ function synved_connect_path_uri( $path = null ) {
39
+ $uri = plugins_url( '/synved-wp-connect' ) . '/synved-connect';
40
 
41
+ if ( function_exists( 'synved_plugout_module_uri_get' ) ) {
42
+ $mod_uri = synved_plugout_module_uri_get( 'synved-connect' );
 
43
 
44
+ if ( false === empty( $mod_uri ) ) {
 
45
  $uri = $mod_uri;
46
  }
47
  }
48
 
49
+ if ( false === empty( $path ) ) {
50
+ if ( '/' !== substr( $uri, -1 ) && '/' !== $path[0] ) {
 
 
51
  $uri .= '/';
52
  }
53
 
57
  return $uri;
58
  }
59
 
60
+ /**
61
+ * ID get.
62
+ *
63
+ * @param string|null $component Component string.
64
+ * @param string|null $part Part string.
65
+ *
66
+ * @return false|mixed|void
67
+ */
68
+ function synved_connect_id_get( $component = null, $part = null ) {
69
  $option_key = 'default';
70
 
71
+ if ( false === empty( $component ) ) {
 
72
  $option_key = 'component_' . $component;
73
  }
74
 
75
+ return get_option( 'synved_connect_id_' . $option_key );
 
 
76
  }
77
 
78
+ /**
79
+ * Enqueue scripts.
80
+ *
81
+ * @return void
82
+ */
83
+ function synved_connect_enqueue_scripts() {
84
  $uri = synved_connect_path_uri();
85
+ $dir = plugin_dir_path( __FILE__ );
86
 
87
  wp_register_style(
88
  'synved-connect-admin',
89
  $uri . '/style/admin.css',
90
  false,
91
+ filemtime( $dir . '/style/admin.css' )
92
  );
93
 
94
+ wp_enqueue_style( 'synved-connect-admin' );
95
 
96
+ if ( true === version_compare( get_bloginfo( 'version' ), SYNVED_WP_MODERN_VERSION, 'lt' ) ) {
97
  wp_register_style(
98
  'synved-connect-old-wp-support-css',
99
  $uri . '/style/synved_old_wp_support.css',
105
  }
106
  }
107
 
108
+ /**
109
+ * Connect init.
110
+ *
111
+ * @return void
112
+ */
113
  function synved_connect_init() {
114
  $install_date = get_option( 'synved_connect_install_date' );
115
 
116
  // Fresh installation.
117
+ if ( true === empty( $install_date ) ) {
118
  update_option( 'synved_connect_install_date', time() );
119
  update_option( 'synved_version', SYNVED_VERSION );
120
  synved_option_set( 'synved_social', 'accepted_sharethis_terms', false );
121
  }
122
 
123
  $version = get_option( 'synved_version' );
124
+ if ( SYNVED_VERSION !== $version ) {
125
  synved_connect_upgrade( $version );
126
  }
127
  }
128
 
129
  /**
130
  * Upgrades the plugin.
131
+ *
132
  * @param string $version The current version.
133
  * @return void
134
  */
142
 
143
  add_action( 'init', 'synved_connect_init', 9 );
144
  add_action( 'admin_enqueue_scripts', 'synved_connect_enqueue_scripts' );
145
+ add_action( 'wp_ajax_smf_ajax_hide_review', 'synved_hide_review' );
146
 
147
+ /**
148
+ * Hide review.
149
+ *
150
+ * @return void
151
+ */
152
+ function synved_hide_review() {
153
+ update_option( 'smf-hide-review', true );
154
 
155
+ wp_send_json_success( 'hidden' );
156
  }
synved-option/addons/option-type-addon/option-type-addon.php CHANGED
@@ -1,208 +1,8 @@
1
  <?php
 
 
 
 
 
2
 
3
- if ( ! function_exists( 'synved_option_render_type_addon' ) ) {
4
-
5
- /**
6
- * Render type addon.
7
- *
8
- * @param $id
9
- * @param $name
10
- * @param $item
11
- * @param $out_name
12
- * @param $extra
13
- *
14
- * @return string
15
- */
16
- function synved_option_render_type_addon( $id, $name, $item, $out_name, $extra = null ) {
17
- $type = synved_option_item_type( $item );
18
- $folder = synved_option_item_property( $item, 'folder' );
19
- $out_id = isset( $extra['out_id'] ) ? $extra['out_id'] : null;
20
- $label = isset( $extra['label'] ) ? $extra['label'] : null;
21
- $out = null;
22
-
23
- $out .= '<div class="synved-option-overlay-markup snvdopt" style="display:none;"><div class="overlay-ui"><div id="' . $out_id . '_overlay_container' . '" class="overlay-container">&nbsp;</div><div class="overlay-message">' . __( 'Click "Upload" and select the addon file, "' . $folder . '.zip". Only 1 file can be selected.',
24
- 'synved-option' ) . '</div>' . __( 'Progress',
25
- 'synved-option' ) . ': <div class="overlay-progress"></div></div><input id="' . $out_id . '_overlay_button' . '" type="button" class="overlay-button button-primary" value="' . __( 'Upload',
26
- 'synved-option' ) . '"/></div>';
27
- $out .= '<div class="synved-option-item-info" style="display:none;">' . "\n" . json_encode( [ 'id' => $id,
28
- 'name' => $name,
29
- ] ) . "\n" . '</div>';
30
- $out .= '<input type="hidden" name="' . synved_option_render_field_name( $id,
31
- $name . '_info_' ) . '" value="' . $type . '" />';
32
- $out .= '<input name="' . $out_name . '" id="' . $out_id . '" type="button" value="' . $label . '" class="button-secondary synved-option-overlay-button" />';
33
- $out .= '<input type="hidden" name="synved_option_addon_uploaded" value="0" />';
34
-
35
- return $out;
36
- }
37
-
38
- /**
39
- * Item addon install.
40
- *
41
- * @param $id
42
- * @param $name
43
- * @param $item
44
- *
45
- * @return bool|true|WP_Error|null
46
- */
47
- function synved_option_item_addon_install( $id, $name, $item ) {
48
- $return = null;
49
- $type = synved_option_item_type( $item );
50
- $target = synved_option_item_property( $item, 'target' );
51
- $folder = synved_option_item_property( $item, 'folder' );
52
- $field_name = synved_option_name_default( $id );
53
- $path = null;
54
-
55
- if ( file_exists( $target ) ) {
56
- $path = $target;
57
- }
58
-
59
- if ( $type != 'addon' || $path == null ) {
60
- return false;
61
- }
62
-
63
- $path = str_replace( [ '/', '\\' ], DIRECTORY_SEPARATOR, $path );
64
-
65
- if ( substr( $path, - 1 ) != DIRECTORY_SEPARATOR ) {
66
- $path .= DIRECTORY_SEPARATOR;
67
- }
68
-
69
- if ( isset( $_FILES[ $field_name ] ) ) {
70
- foreach ( $_FILES[ $field_name ]["error"] as $key => $error ) {
71
- if ( $key == $name && $error == UPLOAD_ERR_OK ) {
72
- $tmp_name = $_FILES[ $field_name ]["tmp_name"][ $key ];
73
- $name = $_FILES[ $field_name ]["name"][ $key ];
74
- $tmpfname = wp_tempnam( $name . '.zip' );
75
-
76
- if ( move_uploaded_file( $tmp_name, $tmpfname ) ) {
77
- global $wp_filesystem;
78
-
79
- $unzip_path = realpath( $path );
80
- $dirs = glob( $path . '*', GLOB_ONLYDIR );
81
-
82
- if ( false === empty( $wp_filesystem ) ) {
83
- $unzip_path = $wp_filesystem->find_folder( $unzip_path );
84
- }
85
-
86
- wp_mkdir_p( realpath( $path ) );
87
- $return = unzip_file( $tmpfname, $unzip_path );
88
-
89
- if ( $wp_filesystem != null ) {
90
- $wp_filesystem->delete( $tmpfname );
91
- }
92
-
93
- $dirs_new = glob( $path . '*', GLOB_ONLYDIR );
94
- $dirs_diff = array_values( array_diff( $dirs_new, $dirs ) );
95
- $addon_path = $path;
96
-
97
- if ( false === empty( $dirs_diff ) ) {
98
- $folder_path = null;
99
-
100
- foreach ( $dirs_diff as $dir ) {
101
- if ( basename( $dir ) == $folder ) {
102
- $folder_path = $dir;
103
- }
104
- }
105
-
106
- if ( false === empty( $folder_path ) ) {
107
- $folder_path = $dirs_diff[0];
108
- }
109
-
110
- $addon_path = $folder_path;
111
- }
112
-
113
- synved_option_set( $id, $name, $addon_path );
114
- }
115
- }
116
- }
117
- }
118
-
119
- return $return;
120
- }
121
-
122
- /**
123
- * Ajax type addon.
124
- *
125
- * @param $action
126
- * @param $params
127
- *
128
- * @return array
129
- */
130
- function synved_option_ajax_type_addon( $action, $params ) {
131
- $response = null;
132
-
133
- check_ajax_referer('synved-option-submit-nonce', 'synvedSecurity');
134
-
135
- if ( current_user_can( 'upload_files' ) && current_user_can( 'install_plugins' ) ) {
136
- $id = isset( $params['id'] ) ? $params['id'] : null;
137
- $name = isset( $params['name'] ) ? $params['name'] : null;
138
-
139
- if ( false === empty( $id ) && false === empty( $name ) ) {
140
- $item = synved_option_item_find( $id, $name );
141
-
142
- if ( $item != null ) {
143
- $return = null;
144
- $error_list = [];
145
-
146
- try {
147
- $page_name = synved_option_item_page( $id, $name );
148
- $page = synved_option_item( $id, $page_name );
149
- $parent = synved_option_item_parent( $page );
150
- $url = wp_nonce_url( $parent . '?page=' . $page_name, 'synved-option' );
151
-
152
- ob_start();
153
- $old_err = error_reporting( 0 );
154
- $credentials = request_filesystem_credentials( $url );
155
- $form = ob_get_clean();
156
- error_reporting( $old_err );
157
-
158
- ob_start();
159
- var_dump( $_POST );
160
- $posted = ob_get_clean();
161
-
162
- if ( $credentials === false ) {
163
- $response['result'] = 'ERROR';
164
- $response['error'] = 'NO_CREDS';
165
- $response['creds_form'] = $form;
166
- $response['posted'] = $posted;
167
- } elseif ( WP_Filesystem( $credentials ) ) {
168
- $return = synved_option_item_addon_install( $id, $name, $item );
169
- }
170
- } catch ( Exception $ex ) {
171
- $return = null;
172
- }
173
-
174
- if ( $return != null ) {
175
- $response['result'] = 'OK';
176
- }
177
- }
178
- }
179
- }
180
-
181
- return $response;
182
- }
183
-
184
- /**
185
- * Enqueue scripts.
186
- *
187
- * @return void
188
- */
189
- function synved_option_enqueue_scripts_type_addon() {
190
- $uri = synved_option_path_uri( 'addons/' . basename( dirname( __FILE__ ) ) );
191
- $dir = plugin_dir_path(__FILE__);
192
-
193
- wp_register_script(
194
- 'synved-option-type-addon-script-custom',
195
- $uri . '/script/custom.js',
196
- [ 'jquery', 'thickbox', 'jquery-ui-core', 'jquery-ui-progressbar', 'jquery-ui-dialog' ],
197
- filemtime( $dir . 'script/custom.js' )
198
- );
199
-
200
- wp_enqueue_script( 'plupload-all' );
201
- wp_enqueue_script( 'synved-option-type-addon-script-custom' );
202
- }
203
-
204
- if ( is_admin() ) {
205
- add_action( 'admin_enqueue_scripts', 'synved_option_enqueue_scripts_type_addon' );
206
- }
207
-
208
- }
1
  <?php
2
+ /**
3
+ * Option type addon.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ // Silence is golden.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-option/addons/option-type-addon/script/custom.js DELETED
@@ -1,235 +0,0 @@
1
- // Synved WP Options - Addon Type
2
- // Custom jquery code
3
- // Version: 1.0
4
- //
5
- // Copyright (c) 2011 Synved Ltd.
6
- // All rights reserved
7
-
8
- jQuery( document ).ready( function() {
9
-
10
- jQuery( '.synved-option-overlay-button' ).click( function() {
11
- tb_show( this.value, '#TB_inline' );
12
- var tb = jQuery( "#TB_window" );
13
-
14
- if ( tb ) {
15
- var tbCont = tb.find( '#TB_ajaxContent' );
16
- tbCont.css( { width: tbCont.parent().width(), height: '100%' } );
17
-
18
- var jthis = jQuery( this );
19
- var info = jthis.prevAll( '.synved-option-item-info:first' ).html();
20
-
21
- var infoObj;
22
-
23
- try {
24
- infoObj = jQuery.parseJSON( info );
25
- } catch ( ex ) {
26
- infoObj = jQuery.parseJSON( jQuery( '<div/>' ).html( info ).text() );
27
- }
28
-
29
- var markup = jthis.prevAll( '.synved-option-overlay-markup' );
30
-
31
- if ( markup ) {
32
- markup = markup.clone();
33
- var progressBar = markup.find( '.overlay-progress' );
34
- var containerId = markup.find( '.overlay-container' ).attr( 'id' );
35
- var buttonId = markup.find( '.overlay-button' ).attr( 'id' );
36
- var fileField = jthis.attr( 'name' );
37
-
38
- var counter = 0;
39
- containerId += '_tb';
40
- buttonId += '_tb';
41
-
42
- while ( jQuery( '#' + containerId + counter.toString() ).size() > 0 ) {
43
- counter += 1;
44
- }
45
-
46
- containerId += counter.toString();
47
- buttonId += counter.toString();
48
-
49
- markup.find( '.overlay-container' ).attr( 'id', containerId );
50
- markup.find( '.overlay-button' ).attr( 'id', buttonId );
51
-
52
- markup.append( jQuery( '<div class="overlay-message overlay-status" />' ) );
53
- markup.append( jQuery( '<button class="button-primary overlay-close">Close and continue</button>' ).hide().click( function() {
54
- tb_remove();
55
- window.location = window.location;
56
- } ) );
57
-
58
- tbCont.html( markup );
59
- markup.show();
60
-
61
- progressBar.progressbar();
62
-
63
- var finishInstall = function( message, error ) {
64
- var status = markup.find( '.overlay-status' );
65
-
66
- if ( status != null ) {
67
- if ( error != undefined && error == true ) {
68
- status.css( 'color', '#b06066' );
69
- } else {
70
- status.css( 'color', '#66b060' );
71
- }
72
-
73
- status.html( message );
74
- }
75
-
76
- markup.find( '#' + buttonId ).hide();
77
- markup.find( '.overlay-close' ).css( 'display', 'inline' );
78
- };
79
-
80
- var params = infoObj;
81
- params = JSON.stringify( params );
82
-
83
- var uploader = new plupload.Uploader( {
84
- runtimes: 'html5,flash,silverlight,html4',
85
- autostart: true,
86
- browse_button: buttonId,
87
- container: containerId,
88
- file_data_name: fileField,
89
- max_file_size: '8mb',
90
- max_file_count: 1,
91
- flash_swf_url: SynvedOptionVars.flash_swf_url,
92
- silverlight_xap_url: SynvedOptionVars.silverlight_xap_url,
93
- url: SynvedOptionVars.ajaxurl,
94
- multipart: true,
95
- urlstream_upload: true,
96
- multipart_params:
97
- {
98
- action: 'synved_option',
99
- synvedSecurity: SynvedOptionVars.synvedSecurity,
100
- synvedAction: 'install-addon',
101
- synvedParams: params,
102
- },
103
- filters: [
104
- { title: "Zip files", extensions: "zip" },
105
- ],
106
- multiple_queues: true,
107
- debug: true,
108
- } );
109
-
110
- uploader.bind( 'Init', function( up ) {
111
- up.bind( 'FilesAdded', function( up, files ) {
112
-
113
- progressBar.progressbar( 'option', 'value', 0 );
114
-
115
- if ( files.length > 1 ) {
116
- up.splice( 1 );
117
- }
118
-
119
- plupload.each( files, function( file ) {
120
- } );
121
-
122
- up.refresh();
123
- up.start();
124
- } );
125
- } );
126
-
127
- uploader.bind( 'UploadProgress', function( up, file ) {
128
- progressBar.progressbar( 'option', 'value', file.percent );
129
- } );
130
-
131
- uploader.bind( 'FileUploaded', function( up, file, info ) {
132
- var response = info.response;
133
- var responseObj = null;
134
-
135
- try {
136
- responseObj = jQuery.parseJSON( response );
137
- } catch ( ex ) {
138
- responseObj = jQuery.parseJSON( jQuery( '<div/>' ).html( response ).text() );
139
- }
140
-
141
- if ( responseObj != null ) {
142
-
143
- var result = responseObj['result'];
144
-
145
- if ( result == 'ERROR' ) {
146
- progressBar.progressbar( 'option', 'value', 0 );
147
-
148
- var error = null;
149
-
150
- if ( 'error' in responseObj ) {
151
- error = responseObj['error'];
152
- }
153
-
154
- if ( error == 'NO_CREDS' ) {
155
- var form = jQuery( '<div>' + responseObj['creds_form'] + '</div>' ).find( 'form' );
156
- var submitData = up.settings.multipart_params;
157
-
158
- if ( submitData ) {
159
- for ( var i in submitData ) {
160
- form.find( '[name=' + i + ']' ).val( submitData[i] );
161
- }
162
- }
163
-
164
- form.data( 'submit-ok', false );
165
- form.submit( function() {
166
- form.data( 'submit-ok', true );
167
- form.dialog( 'close' );
168
-
169
- return false;
170
- } );
171
-
172
- form.find( '.wrap .icon32' ).attr( 'id', 'icon-index' );
173
-
174
- form.dialog( {
175
- dialogClass: 'wp-dialog synved-option-creds-form',
176
- title: 'Connection Details',
177
- width: 550,
178
- modal: true,
179
- resizable: false,
180
- close: function() {
181
- if ( form.data( 'submit-ok' ) == true ) {
182
- var formData = form.serializeArray();
183
- var submitData = {};
184
-
185
- for ( var i in formData ) {
186
- submitData[formData[i].name] = formData[i].value;
187
- }
188
-
189
- for ( var i in up.settings.multipart_params ) {
190
- submitData[i] = up.settings.multipart_params[i];
191
- }
192
-
193
- up.settings.multipart_params = submitData;
194
-
195
- for ( var f in up.files ) {
196
- up.files[f].loaded = 0;
197
- up.files[f].percent = 0;
198
- up.files[f].status = plupload.STOPPED;
199
- }
200
-
201
- up.refresh();
202
- up.start();
203
- } else {
204
- finishInstall( 'Installation was canceled.', true );
205
- }
206
- },
207
- } );
208
- } else {
209
- finishInstall( 'An error occurred.', true );
210
- }
211
- } else {
212
- if ( 'OK' === result ) {
213
- finishInstall( 'Installation was successful.', false );
214
- }
215
-
216
- progressBar.progressbar( 'option', 'value', file.percent );
217
- }
218
- }
219
- } );
220
-
221
- uploader.bind( 'Error', function( up, err ) {
222
- console.log( err );
223
- finishInstall( err.message, true );
224
- } );
225
-
226
- uploader.init();
227
- } else {
228
- tbCont.html( 'Error' );
229
- }
230
- }
231
-
232
- return false;
233
- } );
234
- } );
235
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-option/inc/SynvedOptionCallback.php DELETED
@@ -1,76 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Option callback class.
5
- */
6
- class SynvedOptionCallback {
7
- private $_Object;
8
- private $_Callback;
9
- private $_Default;
10
- private $_Params;
11
-
12
- public function __construct( $callback, $object = null, $default = null, array $callback_parameters = null ) {
13
- $this->_Object = $object;
14
- $this->_Callback = $callback;
15
- $this->_Default = $default;
16
- $this->_Params = $callback_parameters;
17
- }
18
-
19
- public function __invoke( $arguments = null ) {
20
- if ( ! is_array( $arguments ) || func_num_args() > 1 ) {
21
- $arguments = func_get_args();
22
- }
23
-
24
- return $this->InvokeInternal( $arguments );
25
- }
26
-
27
- public function Invoke( $arguments = null ) {
28
- if ( ! is_array( $arguments ) || func_num_args() > 1 ) {
29
- $arguments = func_get_args();
30
- }
31
-
32
- return $this->InvokeInternal( $arguments );
33
- }
34
-
35
- protected function InvokeInternal( array $arguments = null ) {
36
- $func = $this->_Callback;
37
-
38
- if ( $this->_Object != null ) {
39
- $func = [ $this->_Object, $func ];
40
- }
41
-
42
- $parameters = $this->_Params;
43
-
44
- if ( $parameters != null ) {
45
- $parameter_keys = array_keys( $parameters );
46
- $count = count( $parameter_keys );
47
- $argument_list = [];
48
-
49
- for ( $i = 0; $i < $count; $i ++ ) {
50
- $key = $parameter_keys[ $i ];
51
- $parameter = $parameters[ $key ];
52
- $value = isset( $parameter['default'] ) ? $parameter['default'] : null;
53
-
54
- if ( isset( $arguments[ $key ] ) ) {
55
- $value = $arguments[ $key ];
56
- } elseif ( isset( $arguments[ $i ] ) ) {
57
- $value = $arguments[ $i ];
58
- }
59
-
60
- $argument_list[ $i ] = $value;
61
- }
62
-
63
- $arguments = $argument_list;
64
- }
65
-
66
- if ( ! isset( $arguments[0] ) || $arguments[0] === null ) {
67
- $arguments[0] = $this->_Default;
68
- }
69
-
70
- if ( is_callable( $func ) ) {
71
- return call_user_func_array( $func, $arguments );
72
- }
73
-
74
- return $arguments[0];
75
- }
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-option/inc/class-synvedoptioncallback.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Option callback class.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Option callback class.
10
+ */
11
+ class SynvedOptionCallback {
12
+ /**
13
+ * Object var.
14
+ *
15
+ * @var mixed|null
16
+ */
17
+ private $object;
18
+
19
+ /**
20
+ * Callback.
21
+ *
22
+ * @var callable Callback.
23
+ */
24
+ private $callback;
25
+
26
+ /**
27
+ * Default.
28
+ *
29
+ * @var mixed|null Default value.
30
+ */
31
+ private $default;
32
+
33
+ /**
34
+ * Callback params.
35
+ *
36
+ * @var array|null Callback parameters array.
37
+ */
38
+ private $callback_parameters;
39
+
40
+ /**
41
+ * Constructor.
42
+ *
43
+ * @param callable $callback Callback function.
44
+ * @param object $object Callback object.
45
+ * @param mixed|null $default Default fallback value.
46
+ * @param array|null $callback_parameters Callback parameters.
47
+ */
48
+ public function __construct( $callback, $object = null, $default = null, array $callback_parameters = null ) {
49
+ $this->object = $object;
50
+ $this->callback = $callback;
51
+ $this->default = $default;
52
+ $this->callback_parameters = $callback_parameters;
53
+ }
54
+
55
+ /**
56
+ * Invoke function.
57
+ *
58
+ * @param array|null $arguments Arguments array.
59
+ *
60
+ * @return false|mixed|null
61
+ */
62
+ public function __invoke( $arguments = null ) {
63
+ if ( false === is_array( $arguments ) || func_num_args() > 1 ) {
64
+ $arguments = func_get_args();
65
+ }
66
+
67
+ return $this->invoke_internal( $arguments );
68
+ }
69
+
70
+ /**
71
+ * Invoke function.
72
+ *
73
+ * @param array|null $arguments Arguments array.
74
+ *
75
+ * @return false|mixed|null
76
+ */
77
+ public function invoke( $arguments = null ) {
78
+ if ( false === is_array( $arguments ) || func_num_args() > 1 ) {
79
+ $arguments = func_get_args();
80
+ }
81
+
82
+ return $this->invoke_internal( $arguments );
83
+ }
84
+
85
+ /**
86
+ * Internal invoke.
87
+ *
88
+ * @param array|null $arguments Arguments array.
89
+ *
90
+ * @return false|mixed|null
91
+ */
92
+ protected function invoke_internal( array $arguments = null ) {
93
+ $func = $this->callback;
94
+
95
+ if ( false === empty( $this->object ) ) {
96
+ $func = array( $this->object, $func );
97
+ }
98
+
99
+ $parameters = $this->callback_parameters;
100
+
101
+ if ( false === empty( $parameters ) ) {
102
+ $parameter_keys = array_keys( $parameters );
103
+ $count = count( $parameter_keys );
104
+ $argument_list = array();
105
+
106
+ for ( $i = 0; $i < $count; $i ++ ) {
107
+ $key = $parameter_keys[ $i ];
108
+ $parameter = $parameters[ $key ];
109
+ $value = true === isset( $parameter['default'] ) ? $parameter['default'] : null;
110
+
111
+ if ( isset( $arguments[ $key ] ) ) {
112
+ $value = $arguments[ $key ];
113
+ } elseif ( isset( $arguments[ $i ] ) ) {
114
+ $value = $arguments[ $i ];
115
+ }
116
+
117
+ $argument_list[ $i ] = $value;
118
+ }
119
+
120
+ $arguments = $argument_list;
121
+ }
122
+
123
+ if ( false === isset( $arguments[0] ) || true === empty( $arguments[0] ) ) {
124
+ $arguments[0] = $this->default;
125
+ }
126
+
127
+ if ( is_callable( $func ) ) {
128
+ return call_user_func_array( $func, $arguments );
129
+ }
130
+
131
+ return $arguments[0];
132
+ }
133
+ }
synved-option/script/custom.js CHANGED
@@ -141,24 +141,29 @@ jQuery( document ).ready( function() {
141
  checkbox.removeProp( 'checked' );
142
  }
143
 
144
- $( "#synved-slider" ).on( "click", function( e ) {
145
-
146
- checkbox = $( "#synved-disable" );
147
- if ( checkbox[0].checked ) {
148
- if ( confirm( 'This will decline ShareThis Terms of Service, please confirm.' ) ) {
149
- window.location.href = SYNVED_DISABLE_FEATURE_URL;
 
 
 
 
 
 
 
 
 
 
 
 
150
  } else {
151
- var int = setInterval( function() {
152
- if ( ! checkbox[0].checked ) {
153
- checkbox[0].checked = true;
154
- clearInterval( int );
155
- }
156
- }, 10 );
157
  }
158
- } else { // disable
159
- window.location.href = SYNVED_ENABLE_FEATURE_URL;
160
- }
161
- } );
162
  },
163
  };
164
  } )( window.jQuery, window.wp );
141
  checkbox.removeProp( 'checked' );
142
  }
143
 
144
+ $( "#synved-slider" ).on(
145
+ "click",
146
+ function( e ) {
147
+ checkbox = $( "#synved-disable" );
148
+ if ( checkbox[0].checked ) {
149
+ if ( confirm( 'This will decline ShareThis Terms of Service, please confirm.' ) ) {
150
+ window.location.href = SynvedOptionVars.termsURLDisagree;
151
+ } else {
152
+ var int = setInterval(
153
+ function() {
154
+ if ( ! checkbox[0].checked ) {
155
+ checkbox[0].checked = true;
156
+ clearInterval( int );
157
+ }
158
+ },
159
+ 10,
160
+ );
161
+ }
162
  } else {
163
+ window.location.href = SynvedOptionVars.termsURLAgree;
 
 
 
 
 
164
  }
165
+ },
166
+ );
 
 
167
  },
168
  };
169
  } )( window.jQuery, window.wp );
synved-option/synved-option-item.php CHANGED
@@ -1,83 +1,81 @@
1
  <?php
2
-
3
- function synved_option_item_query_into($filter, $list)
4
- {
5
- if ($list == null)
6
- {
 
 
 
 
 
 
 
 
 
 
 
7
  return null;
8
  }
9
 
10
- foreach ($list as $item_name => $item)
11
- {
12
- if ($filter != null)
13
- {
14
- $filter = $filter;
15
- $filter_keys = array_keys($filter);
16
- $filter_name = $filter_keys[0];
17
- $filter_value = $filter[$filter_keys[0]];
18
 
19
- if (is_string($filter_name) || !is_array($filter_value))
20
- {
21
- $filter = array($filter);
22
  }
23
 
24
  $found_item = true;
25
 
26
- foreach ($filter as $filter_index => $filter_list)
27
- {
28
  $pass = false;
29
 
30
- foreach ($filter_list as $filter_name => $filter_value)
31
- {
32
- if ($filter_name == 'name')
33
- {
34
- if ($item_name == $filter_value)
35
- {
36
  $pass = true;
37
  }
38
- }
39
- else
40
- {
41
- $property = synved_option_item_property($item, $filter_name);
42
 
43
- if ($property == $filter_value)
44
- {
45
  $pass = true;
46
  }
47
  }
48
  }
49
 
50
- $found_item = ($found_item && $pass);
51
 
52
- if (!$found_item)
53
- {
54
  break;
55
  }
56
  }
57
 
58
- if ($found_item)
59
- {
60
  return $item;
61
  }
62
  }
63
 
64
- $type = synved_option_item_type($item);
65
 
66
- if ($type == 'options-page' && isset($item['sections']) && $item['sections'] != null)
67
- {
68
- $ret = synved_option_item_query_into($filter, $item['sections']);
 
69
 
70
- if ($ret != null)
71
- {
72
  return $ret;
73
  }
74
- }
75
- else if ($type == 'options-section' && isset($item['settings']) && $item['settings'] != null)
76
- {
77
- $ret = synved_option_item_query_into($filter, $item['settings']);
 
78
 
79
- if ($ret != null)
80
- {
81
  return $ret;
82
  }
83
  }
@@ -86,20 +84,24 @@ function synved_option_item_query_into($filter, $list)
86
  return null;
87
  }
88
 
89
- function synved_option_item_query($id, $filter)
90
- {
 
 
 
 
 
 
 
91
  global $synved_option_list;
92
 
93
- foreach ($synved_option_list as $list_id => $list)
94
- {
95
- if ($id == null || $list_id == $id)
96
- {
97
- $items = synved_option_item_list($list_id);
98
 
99
- $ret = synved_option_item_query_into($filter, $items);
100
 
101
- if ($ret != null || $id != null)
102
- {
103
  return $ret;
104
  }
105
  }
@@ -108,314 +110,315 @@ function synved_option_item_query($id, $filter)
108
  return null;
109
  }
110
 
111
- function synved_option_item_find($id, $name)
112
- {
113
- return synved_option_item_query($id, array('name' => $name));
 
 
 
 
 
 
 
114
  }
115
 
116
- function synved_option_item($id, $name)
117
- {
118
- return synved_option_item_find($id, $name);
 
 
 
 
 
 
 
119
  }
120
 
121
- function synved_option_item_property($item, $property, $default = null)
122
- {
123
- $prop = isset($item[$property]) ? $item[$property] : $default;
 
 
 
 
 
 
 
 
124
 
125
- if ($prop instanceof SynvedOptionCallback)
126
- {
127
- $prop = $prop->Invoke(array($default, $item));
128
  }
129
 
130
  return $prop;
131
  }
132
 
133
- function synved_option_item_type(array $item)
134
- {
135
- $type = isset($item['type']) ? $item['type'] : null;
136
- $default = synved_option_item_default($item);
 
 
 
 
 
 
137
  $callback = null;
138
 
139
- if ($type instanceof SynvedOptionCallback)
140
- {
141
  $callback = $type;
142
 
143
  $type = null;
144
  }
145
 
146
- if ($type == null && isset($item['sections']))
147
- {
148
  $type = 'options-page';
149
  }
150
 
151
- if ($type == null && isset($item['settings']))
152
- {
153
  $type = 'options-section';
154
  }
155
 
156
- if ($type == null)
157
- {
158
  $type = 'text';
159
 
160
- if ($default !== null)
161
- {
162
- if (is_bool($default))
163
- {
164
  $type = 'boolean';
165
- }
166
- else if (is_int($default))
167
- {
168
  $type = 'integer';
169
- }
170
- else if (is_string($default))
171
- {
172
  $type = 'text';
173
- }
174
- else if (is_float($default))
175
- {
176
  $type = 'decimal';
177
  }
178
  }
179
  }
180
 
181
- if ($callback != null)
182
- {
183
- return $callback->Invoke(array($type, $item));
184
  }
185
 
186
  return $type;
187
  }
188
 
189
- function synved_option_item_mode(array $item)
190
- {
191
- $mode = isset($item['mode']) ? $item['mode'] : null;
 
 
 
 
 
 
192
 
193
- if ($mode instanceof SynvedOptionCallback)
194
- {
195
- $mode = $mode->Invoke(array(null, $item));
196
  }
197
 
198
- if ($mode != null && is_string($mode))
199
- {
200
- $mode = explode(',', $mode);
201
  }
202
 
203
- if ($mode == null)
204
- {
205
  $mode = array();
206
  }
207
 
208
  return $mode;
209
  }
210
 
211
- function synved_option_item_style(array $item)
212
- {
213
- $style = isset($item['style']) ? $item['style'] : null;
 
 
 
 
 
 
214
 
215
- if ($style instanceof SynvedOptionCallback)
216
- {
217
- $style = $style->Invoke(array(null, $item));
218
  }
219
 
220
- if ($style != null && is_string($style))
221
- {
222
- $style = explode(',', $style);
223
  }
224
 
225
- if ($style == null)
226
- {
227
  $style = array();
228
  }
229
 
230
  return $style;
231
  }
232
 
233
- function synved_option_item_hidden(array $item)
234
- {
235
- $hidden = isset($item['hidden']) ? $item['hidden'] : null;
236
-
237
- if ($hidden instanceof SynvedOptionCallback)
238
- {
239
- $hidden = $hidden->Invoke(array(null, $item));
240
- }
241
-
242
- return $hidden;
243
- }
244
-
245
- function synved_option_item_label(array $item)
246
- {
247
- $label = isset($item['label']) ? $item['label'] : null;
248
 
249
- if ($label instanceof SynvedOptionCallback)
250
- {
251
- $label = $label->Invoke(array(null, $item));
252
  }
253
 
254
  return $label;
255
  }
256
 
257
- function synved_option_item_title(array $item)
258
- {
259
- $title = isset($item['title']) ? $item['title'] : null;
260
-
261
- if ($title instanceof SynvedOptionCallback)
262
- {
263
- $title = $title->Invoke(array(null, $item));
264
- }
265
-
266
- return $title;
267
- }
268
-
269
- function synved_option_item_tip(array $item)
270
- {
271
- $tip = isset($item['tip']) ? $item['tip'] : null;
272
 
273
- if ($tip instanceof SynvedOptionCallback)
274
- {
275
- $tip = $tip->Invoke(array(null, $item));
276
  }
277
 
278
  return $tip;
279
  }
280
 
281
- function synved_option_item_hint(array $item)
282
- {
283
- $hint = isset($item['hint']) ? $item['hint'] : null;
 
 
 
 
 
 
284
 
285
- if ($hint instanceof SynvedOptionCallback)
286
- {
287
- $hint = $hint->Invoke(array(null, $item));
288
  }
289
 
290
  return $hint;
291
  }
292
 
293
- function synved_option_item_default(array $item)
294
- {
295
- $default = isset($item['default']) ? $item['default'] : null;
 
 
 
 
 
 
296
 
297
- if ($default instanceof SynvedOptionCallback)
298
- {
299
- $default = $default->Invoke(array(null, $item));
300
  }
301
 
302
  return $default;
303
  }
304
 
305
- function synved_option_item_role(array $item)
306
- {
307
- $role = isset($item['role']) ? $item['role'] : null;
 
 
 
 
 
 
308
 
309
- if ($role instanceof SynvedOptionCallback)
310
- {
311
- $role = $role->Invoke(array(null, $item));
312
  }
313
 
314
- if ($role === null)
315
- {
316
  $role = 'manage_options';
317
  }
318
 
319
  return $role;
320
  }
321
 
322
- function synved_option_item_parent(array $item)
323
- {
324
- $parent = isset($item['parent']) ? $item['parent'] : null;
 
 
 
 
 
 
325
 
326
- if ($parent instanceof SynvedOptionCallback)
327
- {
328
- $parent = $parent->Invoke(array(null, $item));
329
  }
330
 
331
- switch ($parent)
332
- {
333
  case 'dashboard':
334
- {
335
  $parent = 'index.php';
336
-
337
  break;
338
- }
339
  case 'posts':
340
- {
341
  $parent = 'edit.php';
342
-
343
  break;
344
- }
345
  case 'media':
346
- {
347
  $parent = 'upload.php';
348
-
349
  break;
350
- }
351
  case 'links':
352
- {
353
  $parent = 'link-manager.php';
354
-
355
  break;
356
- }
357
  case 'pages':
358
- {
359
  $parent = 'edit.php?post_type=page';
360
-
361
  break;
362
- }
363
  case 'comments':
364
- {
365
  $parent = 'edit-comments.php';
366
-
367
  break;
368
- }
369
  case 'appearance':
370
- {
371
  $parent = 'themes.php';
372
-
373
  break;
374
- }
375
  case 'plugins':
376
- {
377
  $parent = 'plugins.php';
378
-
379
  break;
380
- }
381
  case 'users':
382
- {
383
  $parent = 'users.php';
384
-
385
  break;
386
- }
387
  case 'tools':
388
- {
389
  $parent = 'tools.php';
390
-
391
  break;
392
- }
393
  case null:
 
394
  case 'settings':
395
- {
396
  $parent = 'options-general.php';
397
-
398
  break;
399
- }
400
  }
401
 
402
  return $parent;
403
  }
404
 
405
- function synved_option_item_page($id, $name)
406
- {
407
- $items = synved_option_item_list($id);
408
-
409
- if ($items != null)
410
- {
411
- foreach ($items as $page_name => $page)
412
- {
413
- $sections = isset($page['sections']) ? $page['sections'] : array();
414
-
415
- foreach ($sections as $section_name => $section)
416
- {
417
- if ($section_name == $name || (isset($section['settings']) && array_key_exists($name, $section['settings'])))
418
- {
 
 
 
 
 
 
 
 
 
419
  return $page_name;
420
  }
421
  }
@@ -425,59 +428,66 @@ function synved_option_item_page($id, $name)
425
  return null;
426
  }
427
 
428
- function synved_option_item_page_link_url($id, $name)
429
- {
430
- $page_name = synved_option_item_page($id, $name);
 
 
 
 
 
 
 
431
 
432
- if ($page_name != null)
433
- {
434
- return synved_option_page_link_url($id, $page_name);
435
  }
436
 
437
  return null;
438
  }
439
 
440
- function synved_option_item_set_parse(array $item, $set)
441
- {
442
- $type = synved_option_item_type($item);
443
- preg_match_all('/\\s*(?:(\\d+(?:(?:\\.|(?:\\s*-\\s*))\\d+)*)|([^=,]+))\s*(?:=\s*((?:[^,"]+)|(?:"(?:(?:[^"\\\\])|(?:\\.))*")))?(?:,|$)/', $set, $matches, PREG_SET_ORDER);
 
 
 
 
 
 
 
444
 
445
  $set = array();
446
 
447
- foreach ($matches as $match)
448
- {
449
- $number = isset($match[1]) ? $match[1] : null;
450
- $value = isset($match[2]) ? $match[2] : null;
451
- $label = isset($match[3]) ? $match[3] : null;
452
 
453
- if ($number != null && $value == null)
454
- {
455
  $value = $number;
456
  }
457
 
458
- $label = trim($label, '"');
459
- $value = array($value => $label);
460
 
461
- if ($number != null)
462
- {
463
- $range = explode('-', $number);
464
- $count = count($range);
465
 
466
- if ($count > 1)
467
- {
468
  $value_range = array();
469
 
470
- for ($i = 0; $i < $count; $i++)
471
- {
472
- $range_item = $range[$i];
473
- $range_value = synved_option_item_sanitize_value_basic($item, $range_item, 0);
474
 
475
- if ($range_value == 0)
476
- {
477
  $range_value = $range_item;
478
  }
479
 
480
- $value_range[$range_value] = $range_value;
481
  }
482
 
483
  $value = $value_range;
@@ -490,44 +500,46 @@ function synved_option_item_set_parse(array $item, $set)
490
  return $set;
491
  }
492
 
493
- function synved_option_item_set(array $item)
494
- {
495
- $set = isset($item['set']) ? $item['set'] : null;
 
 
 
 
 
 
496
 
497
- if ($set instanceof SynvedOptionCallback)
498
- {
499
- $set = $set->Invoke(array(null, $item));
500
  }
501
 
502
- if ($set != null && !is_array($set))
503
- {
504
- $set = synved_option_item_set_parse($item, $set);
505
  }
506
 
507
  return $set;
508
  }
509
 
510
- function synved_option_item_callback(array $item, $callback_id, $callback_parameters = null)
511
- {
512
- $callback = isset($item[$callback_id]) ? $item[$callback_id] : null;
513
-
514
- if ($callback != null)
515
- {
516
- $callback = trim($callback);
517
-
518
- if (is_string($callback) && !function_exists($callback))
519
- {
520
- $callback = synved_option_callback_create($callback_code, $callback_parameters);
521
- }
522
-
523
- if (!($callback instanceof SynvedOptionCallback))
524
- {
525
- if (is_callable($callback))
526
- {
527
- $callback = synved_option_callback($callback);
528
- }
529
- else
530
- {
531
  $callback = null;
532
  }
533
  }
@@ -536,56 +548,87 @@ function synved_option_item_callback(array $item, $callback_id, $callback_parame
536
  return $callback;
537
  }
538
 
539
- function synved_option_item_validate(array $item)
540
- {
541
- return synved_option_item_callback($item, 'validate', '$value, $name, $id, $item');
 
 
 
 
 
 
542
  }
543
 
544
- function synved_option_item_render(array $item)
545
- {
546
- return synved_option_item_callback($item, 'render', '$value, $params, $name, $id, $item');
 
 
 
 
 
 
547
  }
548
 
549
- function synved_option_item_render_fragment(array $item)
550
- {
551
- return synved_option_item_callback($item, 'render-fragment', '$fragment, $output, $params, $name, $id, $item');
 
 
 
 
 
 
552
  }
553
 
554
- function synved_option_item_sanitize(array $item)
555
- {
556
- return synved_option_item_callback($item, 'sanitize', '$value, $name, $id, $item');
 
 
 
 
 
 
557
  }
558
 
559
- function synved_option_item_sanitize_raw(array $item)
560
- {
561
- return synved_option_item_callback($item, 'sanitize-raw', '$value, $name, $id, $item');
 
 
 
 
 
 
562
  }
563
 
564
- function synved_option_item_set_check_value(array $item, $set, $value)
565
- {
566
- if ($set == null)
567
- {
 
 
 
 
 
 
 
568
  return true;
569
  }
570
 
571
- foreach ($set as $set_it)
572
- {
573
- if (!is_array($set_it))
574
- {
575
- $set_it = array($set_it);
576
  }
577
 
578
- $set_it_keys = array_keys($set_it);
579
 
580
- if (isset($set_it_keys[1]))
581
- {
582
- if ($value >= $set_it_keys[0] && $value <= $set_it_keys[1])
583
- {
584
  return true;
585
  }
586
- }
587
- else if (isset($set_it_keys[0]) && $value == $set_it_keys[0])
588
- {
589
  return true;
590
  }
591
  }
@@ -593,185 +636,177 @@ function synved_option_item_set_check_value(array $item, $set, $value)
593
  return false;
594
  }
595
 
596
- function synved_option_item_validate_value($id, $name, $value, &$new_value = null, array $item = null)
597
- {
598
- if ($item == null)
599
- {
 
 
 
 
 
 
 
 
 
600
  return null;
601
  }
602
 
603
- $validate = synved_option_item_validate($item);
604
- $is_valid = true;
605
- $error = null;
606
  $error_list = array();
607
 
608
- if ($validate != null)
609
- {
610
  $new_value = $value;
611
 
612
- try
613
- {
614
- $validate->Invoke(array($new_value, $name, $id, $item));
615
- }
616
- catch (Exception $ex)
617
- {
618
  $is_valid = false;
619
 
620
  $error = $ex->getMessage();
621
  }
622
  }
623
 
624
- if (!$is_valid)
625
- {
626
- if ($error == null)
627
- {
628
- $error = __('Selected value is invalid', 'synved-option');
629
  }
630
 
631
- $error_list[] = array('code' => null, 'type' => null, 'message' => $error);
 
 
 
 
632
  }
633
 
634
  return $error_list;
635
  }
636
 
637
- function synved_option_item_sanitize_value_basic(array $item, $value, $default = null)
638
- {
639
- $type = synved_option_item_type($item);
640
- $set = isset($item['set']) ? $item['set'] : null;
 
 
 
 
 
 
 
 
641
 
642
- if ($default === null)
643
- {
644
- $default = synved_option_item_default($item);
645
  }
646
 
647
- switch ($type)
648
- {
649
  case 'boolean':
650
- {
651
- if ($value === null)
652
- {
653
  $value = $default;
654
  }
655
 
656
  $value = $value ? true : 0;
657
 
658
  break;
659
- }
660
  case 'integer':
661
- {
662
- if ($value === null || $value === '')
663
- {
664
  $value = $default;
665
  }
666
 
667
- $value = intval($value);
668
-
669
  break;
670
- }
671
  case 'decimal':
672
- {
673
- if ($value === null || $value === '')
674
- {
675
  $value = $default;
676
  }
677
 
678
- $value = floatval($value);
679
-
680
  break;
681
- }
682
  case 'text':
683
  case 'style':
684
  case 'script':
685
  case 'image':
686
  case 'video':
687
- {
688
  $old_value = $value;
689
- $value = strval($value);
690
 
691
- if ($old_value === null || ($value == null && $set != null))
692
- {
693
  $value = $default;
694
  }
695
 
696
  break;
697
- }
698
  case 'color':
699
- {
700
- $value = strval($value);
701
 
702
- if ($value == null)
703
- {
704
  $value = $default;
705
  }
706
 
707
  break;
708
- }
709
  }
710
 
711
  return $value;
712
  }
713
 
714
- function synved_option_item_sanitize_value($id, $name, $value, array $item = null)
715
- {
716
- if ($item == null)
717
- {
718
- $item = synved_option_item($id, $name);
719
- }
720
-
721
- if ($item == null)
722
- {
 
 
 
 
 
 
 
723
  return null;
724
  }
725
 
726
- $type = synved_option_item_type($item);
727
- $default = synved_option_item_default($item);
728
- $set = synved_option_item_set($item);
729
- $sanitize = synved_option_item_sanitize($item);
730
- $sanitize_raw = synved_option_item_sanitize_raw($item);
731
 
732
- if ($sanitize_raw != null)
733
- {
734
- return $sanitize_raw->Invoke(array($value, $name, $id, $item));
735
  }
736
 
737
- $value = synved_option_item_sanitize_value_basic($item, $value, $default);
738
  $is_valid = true;
739
 
740
- if ($set != null)
741
- {
742
- if (is_array($value))
743
- {
744
- $is_valid = false;
745
  $new_value = array();
746
 
747
- foreach ($value as $single_key => $single_value)
748
- {
749
- if (synved_option_item_set_check_value($item, $set, $single_value))
750
- {
751
- $new_value[$single_key] = $single_value;
752
  }
753
  }
754
 
755
- if ($new_value != null)
756
- {
757
  $is_valid = true;
758
- $value = $new_value;
759
  }
760
- }
761
- else
762
- {
763
- if (!synved_option_item_set_check_value($item, $set, $value))
764
- {
765
  $value = $default;
766
  }
767
  }
768
  }
769
 
770
- if ($is_valid)
771
- {
772
- if ($sanitize != null)
773
- {
774
- $value = $sanitize->Invoke(array($value, $name, $id, $item));
775
  }
776
 
777
  return $value;
@@ -779,50 +814,3 @@ function synved_option_item_sanitize_value($id, $name, $value, array $item = nul
779
 
780
  return null;
781
  }
782
-
783
- function synved_option_item_addon_is_installed(array $item)
784
- {
785
- if ($item != null)
786
- {
787
- $type = synved_option_item_type($item);
788
-
789
- if ($type == 'addon')
790
- {
791
- $target = synved_option_item_property($item, 'target');
792
- $folder = synved_option_item_property($item, 'folder');
793
-
794
- $path = $target;
795
-
796
- if ($path != null)
797
- {
798
- $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
799
-
800
- if (substr($path, -1) != DIRECTORY_SEPARATOR)
801
- {
802
- $path .= DIRECTORY_SEPARATOR;
803
- }
804
-
805
- $path .= $folder;
806
-
807
- if (is_dir($path))
808
- {
809
- return true;
810
- }
811
- }
812
-
813
- $module = synved_option_item_property($item, 'module');
814
-
815
- if ($module != null)
816
- {
817
- $addon_list = synved_plugout_module_addon_list($module);
818
-
819
- if (isset($addon_list[$folder]))
820
- {
821
- return true;
822
- }
823
- }
824
- }
825
- }
826
-
827
- return false;
828
- }
1
  <?php
2
+ /**
3
+ * Option items.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Item query into.
10
+ *
11
+ * @param array|null $filter Filter array.
12
+ * @param array|null $list List array.
13
+ *
14
+ * @return mixed|null
15
+ */
16
+ function synved_option_item_query_into( $filter, $list ) {
17
+ if ( true === empty( $list ) ) {
18
  return null;
19
  }
20
 
21
+ foreach ( $list as $item_name => $item ) {
22
+ if ( false === empty( $filter ) ) {
23
+ $filter_keys = array_keys( $filter );
24
+ $filter_name = $filter_keys[0];
25
+ $filter_value = $filter[ $filter_keys[0] ];
 
 
 
26
 
27
+ if ( true === is_string( $filter_name ) || false === is_array( $filter_value ) ) {
28
+ $filter = array( $filter );
 
29
  }
30
 
31
  $found_item = true;
32
 
33
+ foreach ( $filter as $filter_index => $filter_list ) {
 
34
  $pass = false;
35
 
36
+ foreach ( $filter_list as $filter_name => $filter_value ) {
37
+ if ( 'name' === $filter_name ) {
38
+ if ( $item_name === $filter_value ) {
 
 
 
39
  $pass = true;
40
  }
41
+ } else {
42
+ $property = synved_option_item_property( $item, $filter_name );
 
 
43
 
44
+ if ( $property === $filter_value ) {
 
45
  $pass = true;
46
  }
47
  }
48
  }
49
 
50
+ $found_item = ( $found_item && $pass );
51
 
52
+ if ( false === $found_item ) {
 
53
  break;
54
  }
55
  }
56
 
57
+ if ( $found_item ) {
 
58
  return $item;
59
  }
60
  }
61
 
62
+ $type = synved_option_item_type( $item );
63
 
64
+ if ( 'options-page' === $type
65
+ && true === isset( $item['sections'] )
66
+ && false === empty( $item['sections'] ) ) {
67
+ $ret = synved_option_item_query_into( $filter, $item['sections'] );
68
 
69
+ if ( false === empty( $ret ) ) {
 
70
  return $ret;
71
  }
72
+ } elseif ( 'options-section' === $type
73
+ && true === isset( $item['settings'] )
74
+ && false === empty( $item['settings'] )
75
+ ) {
76
+ $ret = synved_option_item_query_into( $filter, $item['settings'] );
77
 
78
+ if ( false === empty( $ret ) ) {
 
79
  return $ret;
80
  }
81
  }
84
  return null;
85
  }
86
 
87
+ /**
88
+ * Item Query.
89
+ *
90
+ * @param string $id ID string.
91
+ * @param array $filter Filter array.
92
+ *
93
+ * @return mixed|null
94
+ */
95
+ function synved_option_item_query( $id, $filter ) {
96
  global $synved_option_list;
97
 
98
+ foreach ( $synved_option_list as $list_id => $list ) {
99
+ if ( true === empty( $id ) || $list_id === $id ) {
100
+ $items = synved_option_item_list( $list_id );
 
 
101
 
102
+ $ret = synved_option_item_query_into( $filter, $items );
103
 
104
+ if ( false === empty( $ret ) || false === empty( $id ) ) {
 
105
  return $ret;
106
  }
107
  }
110
  return null;
111
  }
112
 
113
+ /**
114
+ * Item find.
115
+ *
116
+ * @param string $id ID string.
117
+ * @param string $name Name string.
118
+ *
119
+ * @return mixed|null
120
+ */
121
+ function synved_option_item_find( $id, $name ) {
122
+ return synved_option_item_query( $id, array( 'name' => $name ) );
123
  }
124
 
125
+ /**
126
+ * Find item alias.
127
+ *
128
+ * @param string $id ID string.
129
+ * @param string $name Name string.
130
+ *
131
+ * @return mixed|null
132
+ */
133
+ function synved_option_item( $id, $name ) {
134
+ return synved_option_item_find( $id, $name );
135
  }
136
 
137
+ /**
138
+ * Item property with fallback.
139
+ *
140
+ * @param array $item Item array.
141
+ * @param string $property Property string.
142
+ * @param mixed $default Fallback value.
143
+ *
144
+ * @return false|mixed|null
145
+ */
146
+ function synved_option_item_property( $item, $property, $default = null ) {
147
+ $prop = true === isset( $item[ $property ] ) ? $item[ $property ] : $default;
148
 
149
+ if ( true === $prop instanceof SynvedOptionCallback ) {
150
+ $prop = $prop->invoke( array( $default, $item ) );
 
151
  }
152
 
153
  return $prop;
154
  }
155
 
156
+ /**
157
+ * Item type.
158
+ *
159
+ * @param array $item Item array.
160
+ *
161
+ * @return false|mixed|string|null
162
+ */
163
+ function synved_option_item_type( array $item ) {
164
+ $type = true === isset( $item['type'] ) ? $item['type'] : null;
165
+ $default = synved_option_item_default( $item );
166
  $callback = null;
167
 
168
+ if ( $type instanceof SynvedOptionCallback ) {
 
169
  $callback = $type;
170
 
171
  $type = null;
172
  }
173
 
174
+ if ( true === empty( $type ) && true === isset( $item['sections'] ) ) {
 
175
  $type = 'options-page';
176
  }
177
 
178
+ if ( true === empty( $type ) && true === isset( $item['settings'] ) ) {
 
179
  $type = 'options-section';
180
  }
181
 
182
+ if ( true === empty( $type ) ) {
 
183
  $type = 'text';
184
 
185
+ if ( null !== $default ) {
186
+ if ( true === is_bool( $default ) ) {
 
 
187
  $type = 'boolean';
188
+ } elseif ( true === is_int( $default ) ) {
 
 
189
  $type = 'integer';
190
+ } elseif ( true === is_string( $default ) ) {
 
 
191
  $type = 'text';
192
+ } elseif ( true === is_float( $default ) ) {
 
 
193
  $type = 'decimal';
194
  }
195
  }
196
  }
197
 
198
+ if ( false === empty( $callback ) ) {
199
+ return $callback->invoke( array( $type, $item ) );
 
200
  }
201
 
202
  return $type;
203
  }
204
 
205
+ /**
206
+ * Item mode.
207
+ *
208
+ * @param array $item Item array.
209
+ *
210
+ * @return array|false|mixed|string[]|null
211
+ */
212
+ function synved_option_item_mode( array $item ) {
213
+ $mode = true === isset( $item['mode'] ) ? $item['mode'] : null;
214
 
215
+ if ( true === $mode instanceof SynvedOptionCallback ) {
216
+ $mode = $mode->invoke( array( null, $item ) );
 
217
  }
218
 
219
+ if ( false === empty( $mode ) && true === is_string( $mode ) ) {
220
+ $mode = explode( ',', $mode );
 
221
  }
222
 
223
+ if ( true === empty( $mode ) ) {
 
224
  $mode = array();
225
  }
226
 
227
  return $mode;
228
  }
229
 
230
+ /**
231
+ * Item style.
232
+ *
233
+ * @param array $item Item array.
234
+ *
235
+ * @return array|false|mixed|string[]|null
236
+ */
237
+ function synved_option_item_style( array $item ) {
238
+ $style = true === isset( $item['style'] ) ? $item['style'] : null;
239
 
240
+ if ( $style instanceof SynvedOptionCallback ) {
241
+ $style = $style->invoke( array( null, $item ) );
 
242
  }
243
 
244
+ if ( false === empty( $style ) && true === is_string( $style ) ) {
245
+ $style = explode( ',', $style );
 
246
  }
247
 
248
+ if ( true === empty( $style ) ) {
 
249
  $style = array();
250
  }
251
 
252
  return $style;
253
  }
254
 
255
+ /**
256
+ * Item label.
257
+ *
258
+ * @param array $item Item array.
259
+ *
260
+ * @return false|mixed|null
261
+ */
262
+ function synved_option_item_label( array $item ) {
263
+ $label = true === isset( $item['label'] ) ? $item['label'] : null;
 
 
 
 
 
 
264
 
265
+ if ( true === $label instanceof SynvedOptionCallback ) {
266
+ $label = $label->invoke( array( null, $item ) );
 
267
  }
268
 
269
  return $label;
270
  }
271
 
272
+ /**
273
+ * Item tip.
274
+ *
275
+ * @param array $item Item array.
276
+ *
277
+ * @return false|mixed|null
278
+ */
279
+ function synved_option_item_tip( array $item ) {
280
+ $tip = true === isset( $item['tip'] ) ? $item['tip'] : null;
 
 
 
 
 
 
281
 
282
+ if ( true === $tip instanceof SynvedOptionCallback ) {
283
+ $tip = $tip->invoke( array( null, $item ) );
 
284
  }
285
 
286
  return $tip;
287
  }
288
 
289
+ /**
290
+ * Item hint.
291
+ *
292
+ * @param array $item Item array.
293
+ *
294
+ * @return false|mixed|null
295
+ */
296
+ function synved_option_item_hint( array $item ) {
297
+ $hint = true === isset( $item['hint'] ) ? $item['hint'] : null;
298
 
299
+ if ( true === $hint instanceof SynvedOptionCallback ) {
300
+ $hint = $hint->invoke( array( null, $item ) );
 
301
  }
302
 
303
  return $hint;
304
  }
305
 
306
+ /**
307
+ * Item default.
308
+ *
309
+ * @param array $item Item array.
310
+ *
311
+ * @return false|mixed|null
312
+ */
313
+ function synved_option_item_default( array $item ) {
314
+ $default = true === isset( $item['default'] ) ? $item['default'] : null;
315
 
316
+ if ( true === $default instanceof SynvedOptionCallback ) {
317
+ $default = $default->invoke( array( null, $item ) );
 
318
  }
319
 
320
  return $default;
321
  }
322
 
323
+ /**
324
+ * Item role.
325
+ *
326
+ * @param array $item Item array.
327
+ *
328
+ * @return false|mixed|string|null
329
+ */
330
+ function synved_option_item_role( array $item ) {
331
+ $role = true === isset( $item['role'] ) ? $item['role'] : null;
332
 
333
+ if ( true === $role instanceof SynvedOptionCallback ) {
334
+ $role = $role->invoke( array( null, $item ) );
 
335
  }
336
 
337
+ if ( true === empty( $role ) ) {
 
338
  $role = 'manage_options';
339
  }
340
 
341
  return $role;
342
  }
343
 
344
+ /**
345
+ * Item parent.
346
+ *
347
+ * @param array $item Item array.
348
+ *
349
+ * @return false|mixed|string|null
350
+ */
351
+ function synved_option_item_parent( array $item ) {
352
+ $parent = true === isset( $item['parent'] ) ? $item['parent'] : null;
353
 
354
+ if ( true === $parent instanceof SynvedOptionCallback ) {
355
+ $parent = $parent->invoke( array( null, $item ) );
 
356
  }
357
 
358
+ switch ( $parent ) {
 
359
  case 'dashboard':
 
360
  $parent = 'index.php';
 
361
  break;
 
362
  case 'posts':
 
363
  $parent = 'edit.php';
 
364
  break;
 
365
  case 'media':
 
366
  $parent = 'upload.php';
 
367
  break;
 
368
  case 'links':
 
369
  $parent = 'link-manager.php';
 
370
  break;
 
371
  case 'pages':
 
372
  $parent = 'edit.php?post_type=page';
 
373
  break;
 
374
  case 'comments':
 
375
  $parent = 'edit-comments.php';
 
376
  break;
 
377
  case 'appearance':
 
378
  $parent = 'themes.php';
 
379
  break;
 
380
  case 'plugins':
 
381
  $parent = 'plugins.php';
 
382
  break;
 
383
  case 'users':
 
384
  $parent = 'users.php';
 
385
  break;
 
386
  case 'tools':
 
387
  $parent = 'tools.php';
 
388
  break;
 
389
  case null:
390
+ // no break.
391
  case 'settings':
 
392
  $parent = 'options-general.php';
 
393
  break;
 
394
  }
395
 
396
  return $parent;
397
  }
398
 
399
+ /**
400
+ * Item page.
401
+ *
402
+ * @param string $id ID string.
403
+ * @param string $name Name string.
404
+ *
405
+ * @return int|string|null
406
+ */
407
+ function synved_option_item_page( $id, $name ) {
408
+ $items = synved_option_item_list( $id );
409
+
410
+ if ( false === empty( $items ) ) {
411
+ foreach ( $items as $page_name => $page ) {
412
+ $sections = true === isset( $page['sections'] ) ? $page['sections'] : array();
413
+
414
+ foreach ( $sections as $section_name => $section ) {
415
+ if (
416
+ $section_name === $name
417
+ || (
418
+ true === isset( $section['settings'] )
419
+ && true === array_key_exists( $name, $section['settings'] )
420
+ )
421
+ ) {
422
  return $page_name;
423
  }
424
  }
428
  return null;
429
  }
430
 
431
+ /**
432
+ * Page link URL.
433
+ *
434
+ * @param string $id ID string.
435
+ * @param string $name Name string.
436
+ *
437
+ * @return string|null
438
+ */
439
+ function synved_option_item_page_link_url( $id, $name ) {
440
+ $page_name = synved_option_item_page( $id, $name );
441
 
442
+ if ( false === empty( $page_name ) ) {
443
+ return synved_option_page_link_url( $id, $page_name );
 
444
  }
445
 
446
  return null;
447
  }
448
 
449
+ /**
450
+ * Item set parse.
451
+ *
452
+ * @param array $item Item array.
453
+ * @param string $set Set string.
454
+ *
455
+ * @return array
456
+ */
457
+ function synved_option_item_set_parse( array $item, $set ) {
458
+ $type = synved_option_item_type( $item );
459
+ preg_match_all( '/\\s*(?:(\\d+(?:(?:\\.|(?:\\s*-\\s*))\\d+)*)|([^=,]+))\s*(?:=\s*((?:[^,"]+)|(?:"(?:(?:[^"\\\\])|(?:\\.))*")))?(?:,|$)/', $set, $matches, PREG_SET_ORDER );
460
 
461
  $set = array();
462
 
463
+ foreach ( $matches as $match ) {
464
+ $number = true === isset( $match[1] ) ? $match[1] : null;
465
+ $value = true === isset( $match[2] ) ? $match[2] : null;
466
+ $label = true === isset( $match[3] ) ? $match[3] : null;
 
467
 
468
+ if ( false === empty( $number ) && true === empty( $value ) ) {
 
469
  $value = $number;
470
  }
471
 
472
+ $label = trim( $label, '"' );
473
+ $value = array( $value => $label );
474
 
475
+ if ( false === empty( $number ) ) {
476
+ $range = explode( '-', $number );
477
+ $count = count( $range );
 
478
 
479
+ if ( $count > 1 ) {
 
480
  $value_range = array();
481
 
482
+ for ( $i = 0; $i < $count; $i++ ) {
483
+ $range_item = $range[ $i ];
484
+ $range_value = synved_option_item_sanitize_value_basic( $item, $range_item, 0 );
 
485
 
486
+ if ( 0 === $range_value ) {
 
487
  $range_value = $range_item;
488
  }
489
 
490
+ $value_range[ $range_value ] = $range_value;
491
  }
492
 
493
  $value = $value_range;
500
  return $set;
501
  }
502
 
503
+ /**
504
+ * Item set.
505
+ *
506
+ * @param array $item Item array.
507
+ *
508
+ * @return array|false|mixed|null
509
+ */
510
+ function synved_option_item_set( array $item ) {
511
+ $set = true === isset( $item['set'] ) ? $item['set'] : null;
512
 
513
+ if ( true === $set instanceof SynvedOptionCallback ) {
514
+ $set = $set->invoke( array( null, $item ) );
 
515
  }
516
 
517
+ if ( null !== $set && false === is_array( $set ) ) {
518
+ $set = synved_option_item_set_parse( $item, $set );
 
519
  }
520
 
521
  return $set;
522
  }
523
 
524
+ /**
525
+ * Item callback.
526
+ *
527
+ * @param array $item Item array.
528
+ * @param string $callback_id Callback ID string.
529
+ * @param array $callback_parameters Callback params array.
530
+ *
531
+ * @return mixed|string|SynvedOptionCallback|null
532
+ */
533
+ function synved_option_item_callback( array $item, $callback_id, $callback_parameters = null ) {
534
+ $callback = $item[ $callback_id ] ?? null;
535
+
536
+ if ( false === empty( $callback ) ) {
537
+ $callback = trim( $callback );
538
+
539
+ if ( false === $callback instanceof SynvedOptionCallback ) {
540
+ if ( true === is_callable( $callback ) ) {
541
+ $callback = synved_option_callback( $callback );
542
+ } else {
 
 
543
  $callback = null;
544
  }
545
  }
548
  return $callback;
549
  }
550
 
551
+ /**
552
+ * Item validate.
553
+ *
554
+ * @param array $item Item array.
555
+ *
556
+ * @return mixed|string|SynvedOptionCallback|null
557
+ */
558
+ function synved_option_item_validate( array $item ) {
559
+ return synved_option_item_callback( $item, 'validate', '$value, $name, $id, $item' );
560
  }
561
 
562
+ /**
563
+ * Item render.
564
+ *
565
+ * @param array $item Item array.
566
+ *
567
+ * @return mixed|string|SynvedOptionCallback|null
568
+ */
569
+ function synved_option_item_render( array $item ) {
570
+ return synved_option_item_callback( $item, 'render', '$value, $params, $name, $id, $item' );
571
  }
572
 
573
+ /**
574
+ * Render fragment.
575
+ *
576
+ * @param array $item Item array.
577
+ *
578
+ * @return mixed|string|SynvedOptionCallback|null
579
+ */
580
+ function synved_option_item_render_fragment( array $item ) {
581
+ return synved_option_item_callback( $item, 'render-fragment', '$fragment, $output, $params, $name, $id, $item' );
582
  }
583
 
584
+ /**
585
+ * Sanitize item.
586
+ *
587
+ * @param array $item Item array.
588
+ *
589
+ * @return mixed|string|SynvedOptionCallback|null
590
+ */
591
+ function synved_option_item_sanitize( array $item ) {
592
+ return synved_option_item_callback( $item, 'sanitize', '$value, $name, $id, $item' );
593
  }
594
 
595
+ /**
596
+ * Sanitize raw item.
597
+ *
598
+ * @param array $item Item array.
599
+ *
600
+ * @return mixed|string|SynvedOptionCallback|null
601
+ */
602
+ function synved_option_item_sanitize_raw( array $item ) {
603
+ return synved_option_item_callback( $item, 'sanitize-raw', '$value, $name, $id, $item' );
604
  }
605
 
606
+ /**
607
+ * Set check value.
608
+ *
609
+ * @param array $item Item array.
610
+ * @param array $set Set array.
611
+ * @param string $value Value string.
612
+ *
613
+ * @return bool
614
+ */
615
+ function synved_option_item_set_check_value( array $item, $set, $value ) {
616
+ if ( true === empty( $set ) ) {
617
  return true;
618
  }
619
 
620
+ foreach ( $set as $set_it ) {
621
+ if ( false === is_array( $set_it ) ) {
622
+ $set_it = array( $set_it );
 
 
623
  }
624
 
625
+ $set_it_keys = array_keys( $set_it );
626
 
627
+ if ( true === isset( $set_it_keys[1] ) ) {
628
+ if ( $value >= $set_it_keys[0] && $value <= $set_it_keys[1] ) {
 
 
629
  return true;
630
  }
631
+ } elseif ( true === isset( $set_it_keys[0] ) && $set_it_keys[0] === $value ) {
 
 
632
  return true;
633
  }
634
  }
636
  return false;
637
  }
638
 
639
+ /**
640
+ * Item validate value.
641
+ *
642
+ * @param string $id ID string.
643
+ * @param string $name Name string.
644
+ * @param string $value Value string.
645
+ * @param string $new_value New value string.
646
+ * @param array|null $item Item array.
647
+ *
648
+ * @return array|null
649
+ */
650
+ function synved_option_item_validate_value( $id, $name, $value, &$new_value = null, array $item = null ) {
651
+ if ( true === empty( $item ) ) {
652
  return null;
653
  }
654
 
655
+ $validate = synved_option_item_validate( $item );
656
+ $is_valid = true;
657
+ $error = null;
658
  $error_list = array();
659
 
660
+ if ( false === empty( $validate ) ) {
 
661
  $new_value = $value;
662
 
663
+ try {
664
+ $validate->invoke( array( $new_value, $name, $id, $item ) );
665
+ } catch ( Exception $ex ) {
 
 
 
666
  $is_valid = false;
667
 
668
  $error = $ex->getMessage();
669
  }
670
  }
671
 
672
+ if ( false === $is_valid ) {
673
+ if ( true === empty( $error ) ) {
674
+ $error = __( 'Selected value is invalid', 'synved-option' );
 
 
675
  }
676
 
677
+ $error_list[] = array(
678
+ 'code' => null,
679
+ 'type' => null,
680
+ 'message' => $error,
681
+ );
682
  }
683
 
684
  return $error_list;
685
  }
686
 
687
+ /**
688
+ * Item sanitize value basic.
689
+ *
690
+ * @param array $item Item array.
691
+ * @param string $value Value string.
692
+ * @param string $default Default value string.
693
+ *
694
+ * @return bool|float|int|mixed|string|null
695
+ */
696
+ function synved_option_item_sanitize_value_basic( array $item, $value, $default = null ) {
697
+ $type = synved_option_item_type( $item );
698
+ $set = true === isset( $item['set'] ) ? $item['set'] : null;
699
 
700
+ if ( true === empty( $default ) ) {
701
+ $default = synved_option_item_default( $item );
 
702
  }
703
 
704
+ switch ( $type ) {
 
705
  case 'boolean':
706
+ if ( true === empty( $value ) ) {
 
 
707
  $value = $default;
708
  }
709
 
710
  $value = $value ? true : 0;
711
 
712
  break;
 
713
  case 'integer':
714
+ if ( true === empty( $value ) ) {
 
 
715
  $value = $default;
716
  }
717
 
718
+ $value = intval( $value );
 
719
  break;
 
720
  case 'decimal':
721
+ if ( true === empty( $value ) ) {
 
 
722
  $value = $default;
723
  }
724
 
725
+ $value = floatval( $value );
 
726
  break;
 
727
  case 'text':
728
  case 'style':
729
  case 'script':
730
  case 'image':
731
  case 'video':
 
732
  $old_value = $value;
733
+ $value = strval( $value );
734
 
735
+ if ( true === empty( $old_value ) || ( true === empty( $value ) && null !== $set ) ) {
 
736
  $value = $default;
737
  }
738
 
739
  break;
 
740
  case 'color':
741
+ $value = strval( $value );
 
742
 
743
+ if ( true === empty( $value ) ) {
 
744
  $value = $default;
745
  }
746
 
747
  break;
 
748
  }
749
 
750
  return $value;
751
  }
752
 
753
+ /**
754
+ * Sanitize item value.
755
+ *
756
+ * @param string $id ID string.
757
+ * @param string $name Name string.
758
+ * @param string $value Value string.
759
+ * @param array|null $item Item array.
760
+ *
761
+ * @return array|bool|float|int|mixed|string|null
762
+ */
763
+ function synved_option_item_sanitize_value( $id, $name, $value, array $item = null ) {
764
+ if ( true === empty( $item ) ) {
765
+ $item = synved_option_item( $id, $name );
766
+ }
767
+
768
+ if ( true === empty( $item ) ) {
769
  return null;
770
  }
771
 
772
+ $type = synved_option_item_type( $item );
773
+ $default = synved_option_item_default( $item );
774
+ $set = synved_option_item_set( $item );
775
+ $sanitize = synved_option_item_sanitize( $item );
776
+ $sanitize_raw = synved_option_item_sanitize_raw( $item );
777
 
778
+ if ( false === empty( $sanitize_raw ) ) {
779
+ return $sanitize_raw->invoke( array( $value, $name, $id, $item ) );
 
780
  }
781
 
782
+ $value = synved_option_item_sanitize_value_basic( $item, $value, $default );
783
  $is_valid = true;
784
 
785
+ if ( false === empty( $set ) ) {
786
+ if ( true === is_array( $value ) ) {
787
+ $is_valid = false;
 
 
788
  $new_value = array();
789
 
790
+ foreach ( $value as $single_key => $single_value ) {
791
+ if ( true === synved_option_item_set_check_value( $item, $set, $single_value ) ) {
792
+ $new_value[ $single_key ] = $single_value;
 
 
793
  }
794
  }
795
 
796
+ if ( false === empty( $new_value ) ) {
 
797
  $is_valid = true;
798
+ $value = $new_value;
799
  }
800
+ } else {
801
+ if ( false === synved_option_item_set_check_value( $item, $set, $value ) ) {
 
 
 
802
  $value = $default;
803
  }
804
  }
805
  }
806
 
807
+ if ( $is_valid ) {
808
+ if ( false === empty( $sanitize ) ) {
809
+ $value = $sanitize->invoke( array( $value, $name, $id, $item ) );
 
 
810
  }
811
 
812
  return $value;
814
 
815
  return null;
816
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-option/synved-option-page.php CHANGED
@@ -1,27 +1,36 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
  * Option page default values.
5
  *
6
- * @param $id
7
  *
8
- * @return array
9
  */
10
  function synved_option_page_default( $id ) {
11
- return [ 'name' => 'page_settings', 'type' => 'options-page', 'label' => synved_option_label_from_id( $id ) ];
 
 
 
 
12
  }
13
 
14
  /**
15
  * Option page slug.
16
  *
17
- * @param $id
18
- * @param $name
19
- * @param $item
20
  *
21
  * @return mixed|null
22
  */
23
  function synved_option_page_slug( $id, $name, $item = null ) {
24
- if ( $item == null ) {
25
  $item = synved_option_item( $id, $name );
26
  }
27
 
@@ -41,14 +50,14 @@ function synved_option_page_slug( $id, $name, $item = null ) {
41
  /**
42
  * Option page link.
43
  *
44
- * @param $id
45
- * @param $name
46
- * @param $item
47
  *
48
  * @return string|null
49
  */
50
  function synved_option_page_link_url( $id, $name, $item = null ) {
51
- if ( $item == null ) {
52
  $item = synved_option_item( $id, $name );
53
  }
54
 
@@ -66,82 +75,29 @@ function synved_option_page_link_url( $id, $name, $item = null ) {
66
  /**
67
  * Option page callback function.
68
  *
69
- * @param $id
70
- * @param $name
71
- * @param $item
72
  *
73
  * @return void
74
  */
75
  function synved_option_page_cb( $id, $name, $item ) {
76
- $group = synved_option_group_default( $id );
77
- $label = synved_option_item_label( $item );
78
- $title = synved_option_item_title( $item );
79
- $tip = synved_option_item_tip( $item );
80
- $role = synved_option_item_role( $item );
81
- $style = synved_option_item_style( $item );
82
-
83
- if ( ! current_user_can( $role ) ) {
84
- wp_die( __( 'You do not have sufficient permissions to access this page.', 'synved-option' ) );
85
- }
86
-
87
- if ( $title === null ) {
88
- $title = $label;
89
- }
90
-
91
- $class_list = [ 'wrap' ];
92
-
93
- if ( false === empty( $style ) ) {
94
- foreach ( $style as $style_name ) {
95
- $class_list[] = 'synved-option-style-' . $style_name;
96
- }
97
  }
98
 
99
  ob_start();
100
  ?>
101
- <div class="<?php echo esc_attr( implode( ' ', $class_list ) ); ?>">
102
- <div class="icon32" id="icon-options-general"><br/></div>
103
- <h2><?php echo esc_html( $title ); ?></h2>
104
- <p><?php echo wp_kses_post( $tip ); ?></p>
105
- <form action="options.php" method="post">
106
- <?php settings_fields( $group ); ?>
107
- <?php
108
- $page_slug = synved_option_page_slug( $id, $name, $item );
109
- do_settings_sections( $page_slug );
110
- ?>
111
- <p class="submit">
112
- <input name="Submit" type="submit" class="button-primary"
113
- value="<?php esc_attr_e( 'Save Changes', 'synved-option' ); ?>"/>
114
- <?php
115
- $render_fragment = synved_option_item_render_fragment( $item );
116
- $out = null;
117
-
118
- if ( false === empty( $render_fragment ) ) {
119
- try {
120
- $params = [];
121
- $new_out = $render_fragment->Invoke( [ 'page-submit-tail', '', $params, $name, $id, $item ] );
122
- } catch ( Exception $ex ) {
123
- $new_out = null;
124
- }
125
-
126
- if ( false === empty( $new_out ) ) {
127
- $out = $new_out;
128
- }
129
- }
130
-
131
- echo $out;
132
- ?>
133
- </p>
134
- </form>
135
- </div>
136
-
137
- <script type="text/javascript">
138
- const SYNVED_DISABLE_FEATURE_URL = '<?php echo esc_js( admin_url( 'options-general.php?page=synved_social_settings&accept-terms=no' ) ); ?>';
139
- const SYNVED_ENABLE_FEATURE_URL = '<?php echo esc_js( admin_url( 'options-general.php?page=synved_social_settings&accept-terms=yes' ) ); ?>';
140
-
141
- jQuery( document ).ready( function() {
142
- synved_switcher.init(<?php echo synved_option_get( 'synved_social', 'accepted_sharethis_terms' ); ?>);
143
- } );
144
- </script>
145
  <?php
146
  $html = ob_get_clean();
147
 
@@ -151,9 +107,9 @@ function synved_option_page_cb( $id, $name, $item ) {
151
  /**
152
  * Add option page.
153
  *
154
- * @param $id
155
- * @param $name
156
- * @param $item
157
  *
158
  * @return false|string|null
159
  */
@@ -165,7 +121,7 @@ function synved_option_page_add( $id, $name, $item ) {
165
 
166
  $type = synved_option_item_type( $item );
167
 
168
- if ( $type == 'options-page' ) {
169
  $label = synved_option_item_label( $item ) ?? $name;
170
  $parent = synved_option_item_parent( $item );
171
  $role = synved_option_item_role( $item );
1
  <?php
2
+ /**
3
+ * Option page.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
  /**
9
  * Option page default values.
10
  *
11
+ * @param string $id ID string.
12
  *
13
+ * @return array Page default value array.
14
  */
15
  function synved_option_page_default( $id ) {
16
+ return array(
17
+ 'name' => 'page_settings',
18
+ 'type' => 'options-page',
19
+ 'label' => synved_option_label_from_id( $id ),
20
+ );
21
  }
22
 
23
  /**
24
  * Option page slug.
25
  *
26
+ * @param string $id ID string.
27
+ * @param string $name Name string.
28
+ * @param array $item Item array.
29
  *
30
  * @return mixed|null
31
  */
32
  function synved_option_page_slug( $id, $name, $item = null ) {
33
+ if ( true === empty( $item ) ) {
34
  $item = synved_option_item( $id, $name );
35
  }
36
 
50
  /**
51
  * Option page link.
52
  *
53
+ * @param string $id ID string.
54
+ * @param string $name Name string.
55
+ * @param array $item Item array.
56
  *
57
  * @return string|null
58
  */
59
  function synved_option_page_link_url( $id, $name, $item = null ) {
60
+ if ( true === empty( $item ) ) {
61
  $item = synved_option_item( $id, $name );
62
  }
63
 
75
  /**
76
  * Option page callback function.
77
  *
78
+ * @param string $id ID string.
79
+ * @param string $name Name string.
80
+ * @param array $item Item array.
81
  *
82
  * @return void
83
  */
84
  function synved_option_page_cb( $id, $name, $item ) {
85
+ $role = synved_option_item_role( $item );
86
+
87
+ if ( false === current_user_can( $role ) ) {
88
+ wp_die(
89
+ esc_html(
90
+ __(
91
+ 'You do not have sufficient permissions to access this page.',
92
+ 'synved-option'
93
+ )
94
+ )
95
+ );
 
 
 
 
 
 
 
 
 
 
96
  }
97
 
98
  ob_start();
99
  ?>
100
+ <div id="social-media-feather-app"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  <?php
102
  $html = ob_get_clean();
103
 
107
  /**
108
  * Add option page.
109
  *
110
+ * @param string $id ID string.
111
+ * @param string $name Name string.
112
+ * @param array $item Item array.
113
  *
114
  * @return false|string|null
115
  */
121
 
122
  $type = synved_option_item_type( $item );
123
 
124
+ if ( 'options-page' === $type ) {
125
  $label = synved_option_item_label( $item ) ?? $name;
126
  $parent = synved_option_item_parent( $item );
127
  $role = synved_option_item_role( $item );
synved-option/synved-option-render.php CHANGED
@@ -1,49 +1,73 @@
1
  <?php
2
-
3
- function synved_option_render_field_name($id, $name)
4
- {
5
- $out_name = synved_option_name_default($id) . '[' . $name . ']';
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  return $out_name;
8
  }
9
 
10
- function synved_option_render_field_id($id, $name)
11
- {
12
- $out_id = synved_option_name_default($id) . '_' . $name;
13
-
14
- return $out_id;
 
 
 
 
 
15
  }
16
 
17
- function synved_option_render_item($id, $name, $item = null, $render = false, $params = null, $context = null)
18
- {
19
- if ($item == null)
20
- {
21
- $item = synved_option_item($id, $name);
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
- if ($item == null)
25
- {
26
  return null;
27
  }
28
 
29
- $value = synved_option_get($id, $name);
30
- $type = synved_option_item_type($item);
31
- $style = synved_option_item_style($item);
32
- $label = synved_option_item_label($item);
33
- $tip = synved_option_item_tip($item);
34
- $hint = synved_option_item_hint($item);
35
- $default = synved_option_item_default($item);
36
- $set = synved_option_item_set($item);
37
  $set_is_linear = false;
38
 
39
- if ($set != null)
40
- {
41
  $set_is_linear = true;
42
 
43
- foreach ($set as $set_it)
44
- {
45
- if (count($set_it) > 1)
46
- {
47
  $set_is_linear = false;
48
 
49
  break;
@@ -51,174 +75,152 @@ function synved_option_render_item($id, $name, $item = null, $render = false, $p
51
  }
52
  }
53
 
54
- $out_name = synved_option_render_field_name($id, $name);
55
- $out_id = synved_option_render_field_id($id, $name);
56
- $out = null;
57
 
58
- if (isset($params['output_name']))
59
- {
60
  $out_name = $params['output_name'];
61
  }
62
 
63
- if (isset($params['output_id']))
64
- {
65
  $out_id = $params['output_id'];
66
  }
67
 
68
- if (isset($params['tip']))
69
- {
70
  $tip = $params['tip'];
71
  }
72
 
73
- if (isset($params['default']))
74
- {
75
  $default = $params['default'];
76
  }
77
 
78
- if (isset($params['value']))
79
- {
80
  $value = $params['value'];
81
  }
82
 
83
- $new_value = $value;
84
- $error_list = synved_option_item_validate_value($id, $name, $value, $new_value, $item);
85
 
86
- if ($new_value != $value && ($context == null || $context == 'settings'))
87
- {
88
- synved_option_set($id, $name, $new_value);
89
 
90
- $value = synved_option_get($id, $name);
91
  }
92
 
93
- if ($error_list != null)
94
- {
95
- foreach ($error_list as $error)
96
- {
97
  $out .= '<div id="message" class="error"><p>For "<i>' . $label . '</i>": ' . $error['message'] . '</p></div>';
98
  }
99
  }
100
 
101
- if ($set_is_linear)
102
- {
103
  $out .= '<select name="' . $out_name . '" id="' . $out_id . '">';
104
 
105
- // XXX exception...remove at some point
106
- if (isset($params['set_before']))
107
- {
108
  $set_before = $params['set_before'];
109
 
110
- $set = array_merge($set_before, $set);
111
  }
112
 
113
- foreach ($set as $set_it)
114
- {
115
- $set_it_keys = array_keys($set_it);
116
- $selected = $set_it_keys[0] == $value ? ' selected="selected"' : null;
117
 
118
- $out .= '<option value="' . $set_it_keys[0] . '"' . $selected . '>' . $set_it[$set_it_keys[0]] . '</option>';
 
 
 
119
  }
120
 
121
  $out .= '</select>';
122
- }
123
- else
124
- {
125
  $placeholder = null;
126
 
127
- if ($hint != null)
128
- {
129
- $placeholder = ' placeholder="' . esc_attr($hint) . '"';
130
  }
131
 
132
- switch ($type)
133
- {
134
  case 'boolean':
135
- {
136
- $checked = $value == true ? ' checked="checked"' : null;
137
-
138
  $out .= '<fieldset><legend class="screen-reader-text"><span>'
139
- . esc_attr($label)
140
- . '</span></legend><label for="'
141
- . esc_attr($out_id)
142
- . '"><input type="hidden" name="'
143
- . esc_attr($out_name)
144
- . '" value="0" /><input name="'
145
- . esc_attr($out_name)
146
- . '" id="'
147
- . esc_attr($out_id)
148
- . '" type="checkbox" value="1" class="code" '
149
- . $checked
150
- . $placeholder
151
- . ' /> '
152
- . '</label>&nbsp;&nbsp;<span class="description" style="vertical-align:middle;">'
153
- . esc_html($tip)
154
- . '</span></fieldset>';
155
 
156
  break;
157
- }
158
  case 'text':
159
  case 'style':
160
  case 'script':
161
  case 'image':
162
  case 'video':
163
  case 'media':
164
- {
165
- $atts = array('name' => $out_name, 'type' => 'text', 'id' => $out_id, 'value' => $value, 'class' => 'regular-text');
 
 
 
 
 
166
  $att_style = array();
167
- $content = null;
168
- $tag = 'input';
169
- $extended = false;
170
-
171
- if ($style != null)
172
- {
173
- if (in_array('wide', $style))
174
- {
175
  $atts['class'] = 'wide-text';
176
  }
177
 
178
- if (in_array('extend', $style))
179
- {
180
  $extended = true;
181
  }
182
  }
183
 
184
- if (in_array($type, array('style', 'script')))
185
- {
186
  $extended = true;
187
 
188
- $att_style['width'] = '450px';
189
  $att_style['height'] = '250px';
190
  }
191
 
192
- if ($extended)
193
- {
194
  $tag = 'textarea';
195
 
196
- if (isset($atts['value']))
197
- {
198
  $content = $atts['value'];
199
 
200
- unset($atts['value']);
201
  }
202
 
203
- if ($content == null)
204
- {
205
  $content = '';
206
  }
207
 
208
- unset($atts['type']);
209
  }
210
 
211
- if ($hint != null)
212
- {
213
  $atts['placeholder'] = $hint;
214
  }
215
 
216
- if ($att_style != null)
217
- {
218
  $att_css = null;
219
 
220
- foreach ($att_style as $style_name => $style_value)
221
- {
222
  $att_css .= $style_name . ':' . $style_value . ';';
223
  }
224
 
@@ -227,145 +229,116 @@ function synved_option_render_item($id, $name, $item = null, $render = false, $p
227
 
228
  $out .= '<' . $tag;
229
 
230
- foreach ($atts as $att_name => $att_value)
231
- {
232
- $out .= ' ' . $att_name . '="' . esc_attr($att_value) . '"';
233
  }
234
 
235
- if ($content !== null)
236
- {
237
- $out .= '>' . esc_html($content) . '</' . $tag . '>';
238
- }
239
- else
240
- {
241
  $out .= ' />';
242
  }
243
 
244
- if (in_array($type, array('image', 'video', 'media')))
245
- {
246
- $out .= '<input type="hidden" name="' . esc_attr(synved_option_render_field_name($id, $name . '_info_')) . '" value="' . esc_attr($type) . '" />';
247
- $out .= '&nbsp;&nbsp;<input type="button" class="synved-option-upload-button" value="' . esc_attr(__('Select File', 'synved-option')) . '"' . $placeholder . ' />';
248
  }
249
 
250
  break;
251
- }
252
  case 'color':
253
- {
254
  $out .= '<div style="position:relative; float: left;">';
255
  $out .= '<input name="'
256
- . esc_attr( $out_name )
257
- . '" id="'
258
- . esc_attr( $out_id )
259
- . '" type="text" value="'
260
- . esc_attr( $value )
261
- . '" class="code medium-text color-input"'
262
- . $placeholder
263
- . ' />';
264
  $out .= '<div class="synved-option-color-input-picker" style="background:white;border:solid 1px #ccc;display:none;position:absolute;top:100%;left:0;z-index:10000;"></div>';
265
  $out .= '</div>';
266
 
267
  break;
268
- }
269
  case 'integer':
270
  case 'decimal':
271
- {
272
  $out .= '<input name="'
273
- . esc_attr($out_name)
274
- . '" id="'
275
- . esc_attr($out_id)
276
- . '" type="text" value="'
277
- . esc_attr($value)
278
- . '" class="code small-text"'
279
- . $placeholder . ' />';
280
  break;
281
- }
282
  case 'user':
283
  case 'author':
284
  case 'category':
285
  case 'page':
286
- {
287
  $args = array(
288
- 'echo' => false, 'name' => $out_name, 'id' => $name, 'selected' => $value,
289
- 'show_option_all' => __('Every', 'synved-option') . ' ' . ucfirst($type)
 
 
 
290
  );
291
 
292
  $drop_out = null;
293
 
294
- switch ($type)
295
- {
296
  case 'author':
297
- {
298
  $args['who'] = 'author';
299
- }
300
  case 'user':
301
- {
302
- $drop_out = wp_dropdown_users($args);
303
-
304
  break;
305
- }
306
  case 'category':
307
- {
308
- $drop_out = wp_dropdown_categories($args);
309
-
310
  break;
311
- }
312
  case 'page':
313
- {
314
- $args['show_option_no_change'] = $args['show_option_all'];
315
-
316
- $drop_out = wp_dropdown_pages($args);
317
 
 
318
  break;
319
- }
320
  }
321
 
322
  $out .= $drop_out;
323
 
324
  break;
325
- }
326
  case 'tag-list':
327
- {
328
  $out .= '<input name="'
329
- . esc_attr($out_name)
330
- . '" id="'
331
- . esc_attr($out_id)
332
- . '" type="text" value="'
333
- . esc_attr($value)
334
- . '" class="regular-text synved-option-tag-selector"'
335
- . $placeholder
336
- . ' />';
337
 
338
  break;
339
- }
340
- case 'addon':
341
- {
342
- if (function_exists('synved_option_render_type_addon'))
343
- {
344
- $out .= synved_option_render_type_addon($id, $name, $item, $out_name, array('out_id' => $out_id, 'label' => $label));
345
- }
346
-
347
- break;
348
- }
349
  }
350
 
351
- if ( $hint != null ) {
352
- $out .= ' <span class="snvdopt"><a class="button synved-option-reset-button" title="' . __( 'Set value to default hinted background value',
353
- 'synved-option' ) . '" style="display: inline-block; padding: 0; vertical-align: middle; cursor: pointer;"><span class="ui-icon ui-icon-arrowrefresh-1-w"> </span></a></span>';
 
 
354
  }
355
  }
356
 
357
- $item_render = synved_option_item_render($item);
358
 
359
- if ( $item_render != null ) {
360
  try {
361
- $params = [
362
  'output_name' => $out_name,
363
  'output_id' => $out_id,
364
  'output' => $out,
365
  'set' => $set,
366
  'label' => $label,
367
- ];
368
- $new_out = $item_render->Invoke( [ $value, $params, $name, $id, $item ] );
369
  } catch ( Exception $ex ) {
370
  $new_out = '';
371
  }
@@ -376,18 +349,15 @@ function synved_option_render_item($id, $name, $item = null, $render = false, $p
376
  }
377
 
378
  if ( false === empty( $out ) ) {
379
- if ( $tip != null && $type != 'boolean' ) {
380
  $tip_class = ' description-' . $type;
381
- $out .= '&nbsp;&nbsp;<span class="description' . $tip_class . '">' . $tip . '</span>';
382
  }
383
 
384
- // Escape our output.
385
- $out = wp_kses( $out, synved_get_allowed_html_array() );
386
-
387
  if ( $render ) {
388
- echo $out;
389
  } else {
390
- return $out;
391
  }
392
  }
393
 
1
  <?php
2
+ /**
3
+ * Option render.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Render field name.
10
+ *
11
+ * @param string $id ID string.
12
+ * @param string $name Name string.
13
+ *
14
+ * @return string
15
+ */
16
+ function synved_option_render_field_name( $id, $name ) {
17
+ $out_name = synved_option_name_default( $id ) . '[' . $name . ']';
18
 
19
  return $out_name;
20
  }
21
 
22
+ /**
23
+ * Render field ID.
24
+ *
25
+ * @param string $id ID string.
26
+ * @param string $name Name string.
27
+ *
28
+ * @return string
29
+ */
30
+ function synved_option_render_field_id( $id, $name ) {
31
+ return synved_option_name_default( $id ) . '_' . $name;
32
  }
33
 
34
+ /**
35
+ * Render item.
36
+ *
37
+ * @param string $id ID string.
38
+ * @param string $name Name string.
39
+ * @param array|null $item Item array.
40
+ * @param bool $render Should we render? True if yes, false if no (default = no).
41
+ * @param array|null $params Parameter array.
42
+ * @param string|null $context Context string.
43
+ *
44
+ * @return string|null
45
+ */
46
+ function synved_option_render_item( $id, $name, $item = null, $render = false, $params = null, $context = null ) {
47
+ if ( true === empty( $item ) ) {
48
+ $item = synved_option_item( $id, $name );
49
  }
50
 
51
+ // If item is still empty, return null.
52
+ if ( true === empty( $item ) ) {
53
  return null;
54
  }
55
 
56
+ $value = synved_option_get( $id, $name );
57
+ $type = synved_option_item_type( $item );
58
+ $style = synved_option_item_style( $item );
59
+ $label = synved_option_item_label( $item );
60
+ $tip = synved_option_item_tip( $item );
61
+ $hint = synved_option_item_hint( $item );
62
+ $default = synved_option_item_default( $item );
63
+ $set = synved_option_item_set( $item );
64
  $set_is_linear = false;
65
 
66
+ if ( false === empty( $set ) ) {
 
67
  $set_is_linear = true;
68
 
69
+ foreach ( $set as $set_it ) {
70
+ if ( count( $set_it ) > 1 ) {
 
 
71
  $set_is_linear = false;
72
 
73
  break;
75
  }
76
  }
77
 
78
+ $out_name = synved_option_render_field_name( $id, $name );
79
+ $out_id = synved_option_render_field_id( $id, $name );
80
+ $out = null;
81
 
82
+ if ( isset( $params['output_name'] ) ) {
 
83
  $out_name = $params['output_name'];
84
  }
85
 
86
+ if ( isset( $params['output_id'] ) ) {
 
87
  $out_id = $params['output_id'];
88
  }
89
 
90
+ if ( isset( $params['tip'] ) ) {
 
91
  $tip = $params['tip'];
92
  }
93
 
94
+ if ( isset( $params['default'] ) ) {
 
95
  $default = $params['default'];
96
  }
97
 
98
+ if ( isset( $params['value'] ) ) {
 
99
  $value = $params['value'];
100
  }
101
 
102
+ $new_value = $value;
103
+ $error_list = synved_option_item_validate_value( $id, $name, $value, $new_value, $item );
104
 
105
+ if ( $new_value !== $value && ( true === empty( $context ) || 'settings' === $context ) ) {
106
+ synved_option_set( $id, $name, $new_value );
 
107
 
108
+ $value = synved_option_get( $id, $name );
109
  }
110
 
111
+ if ( false === empty( $error_list ) ) {
112
+ foreach ( $error_list as $error ) {
 
 
113
  $out .= '<div id="message" class="error"><p>For "<i>' . $label . '</i>": ' . $error['message'] . '</p></div>';
114
  }
115
  }
116
 
117
+ if ( true === $set_is_linear ) {
 
118
  $out .= '<select name="' . $out_name . '" id="' . $out_id . '">';
119
 
120
+ // TODO: Exception: remove at some point.
121
+ if ( true === isset( $params['set_before'] ) ) {
 
122
  $set_before = $params['set_before'];
123
 
124
+ $set = array_merge( $set_before, $set );
125
  }
126
 
127
+ foreach ( $set as $set_it ) {
128
+ $set_it_keys = array_keys( $set_it );
 
 
129
 
130
+ $out .= '<option value="' . esc_attr( $set_it_keys[0] ) . '" '
131
+ . selected( $value === $set_it_keys[0], true, false ) . '>'
132
+ . esc_html( $set_it[ $set_it_keys[0] ] )
133
+ . '</option>';
134
  }
135
 
136
  $out .= '</select>';
137
+ } else {
 
 
138
  $placeholder = null;
139
 
140
+ if ( false === empty( $hint ) ) {
141
+ $placeholder = ' placeholder="' . esc_attr( $hint ) . '"';
 
142
  }
143
 
144
+ switch ( $type ) {
 
145
  case 'boolean':
 
 
 
146
  $out .= '<fieldset><legend class="screen-reader-text"><span>'
147
+ . esc_attr( $label )
148
+ . '</span></legend><label for="'
149
+ . esc_attr( $out_id )
150
+ . '"><input type="hidden" name="'
151
+ . esc_attr( $out_name )
152
+ . '" value="0" /><input name="'
153
+ . esc_attr( $out_name )
154
+ . '" id="'
155
+ . esc_attr( $out_id )
156
+ . '" type="checkbox" value="1" class="code" '
157
+ . checked( true === $value, true, false )
158
+ . $placeholder
159
+ . ' /> '
160
+ . '</label>&nbsp;&nbsp;<span class="description" style="vertical-align:middle;">'
161
+ . esc_html( $tip )
162
+ . '</span></fieldset>';
163
 
164
  break;
 
165
  case 'text':
166
  case 'style':
167
  case 'script':
168
  case 'image':
169
  case 'video':
170
  case 'media':
171
+ $atts = array(
172
+ 'name' => $out_name,
173
+ 'type' => 'text',
174
+ 'id' => $out_id,
175
+ 'value' => $value,
176
+ 'class' => 'regular-text',
177
+ );
178
  $att_style = array();
179
+ $content = null;
180
+ $tag = 'input';
181
+ $extended = false;
182
+
183
+ if ( false === empty( $style ) ) {
184
+ if ( true === in_array( 'wide', $style, true ) ) {
 
 
185
  $atts['class'] = 'wide-text';
186
  }
187
 
188
+ if ( true === in_array( 'extend', $style, true ) ) {
 
189
  $extended = true;
190
  }
191
  }
192
 
193
+ if ( true === in_array( $type, array( 'style', 'script' ), true ) ) {
 
194
  $extended = true;
195
 
196
+ $att_style['width'] = '450px';
197
  $att_style['height'] = '250px';
198
  }
199
 
200
+ if ( true === $extended ) {
 
201
  $tag = 'textarea';
202
 
203
+ if ( true === isset( $atts['value'] ) ) {
 
204
  $content = $atts['value'];
205
 
206
+ unset( $atts['value'] );
207
  }
208
 
209
+ if ( true === empty( $content ) ) {
 
210
  $content = '';
211
  }
212
 
213
+ unset( $atts['type'] );
214
  }
215
 
216
+ if ( false === empty( $hint ) ) {
 
217
  $atts['placeholder'] = $hint;
218
  }
219
 
220
+ if ( false === empty( $att_style ) ) {
 
221
  $att_css = null;
222
 
223
+ foreach ( $att_style as $style_name => $style_value ) {
 
224
  $att_css .= $style_name . ':' . $style_value . ';';
225
  }
226
 
229
 
230
  $out .= '<' . $tag;
231
 
232
+ foreach ( $atts as $att_name => $att_value ) {
233
+ $out .= ' ' . $att_name . '="' . esc_attr( $att_value ) . '"';
 
234
  }
235
 
236
+ if ( false === empty( $content ) ) {
237
+ $out .= '>' . esc_html( $content ) . '</' . $tag . '>';
238
+ } else {
 
 
 
239
  $out .= ' />';
240
  }
241
 
242
+ if ( true === in_array( $type, array( 'image', 'video', 'media' ), true ) ) {
243
+ $out .= '<input type="hidden" name="' . esc_attr( synved_option_render_field_name( $id, $name . '_info_' ) ) . '" value="' . esc_attr( $type ) . '" />';
244
+ $out .= '&nbsp;&nbsp;<input type="button" class="synved-option-upload-button" value="' . esc_attr( __( 'Select File', 'synved-option' ) ) . '"' . $placeholder . ' />';
 
245
  }
246
 
247
  break;
 
248
  case 'color':
 
249
  $out .= '<div style="position:relative; float: left;">';
250
  $out .= '<input name="'
251
+ . esc_attr( $out_name )
252
+ . '" id="'
253
+ . esc_attr( $out_id )
254
+ . '" type="text" value="'
255
+ . esc_attr( $value )
256
+ . '" class="code medium-text color-input"'
257
+ . $placeholder
258
+ . ' />';
259
  $out .= '<div class="synved-option-color-input-picker" style="background:white;border:solid 1px #ccc;display:none;position:absolute;top:100%;left:0;z-index:10000;"></div>';
260
  $out .= '</div>';
261
 
262
  break;
 
263
  case 'integer':
264
  case 'decimal':
 
265
  $out .= '<input name="'
266
+ . esc_attr( $out_name )
267
+ . '" id="'
268
+ . esc_attr( $out_id )
269
+ . '" type="text" value="'
270
+ . esc_attr( $value )
271
+ . '" class="code small-text"'
272
+ . $placeholder . ' />';
273
  break;
 
274
  case 'user':
275
  case 'author':
276
  case 'category':
277
  case 'page':
 
278
  $args = array(
279
+ 'echo' => false,
280
+ 'name' => esc_attr( $out_name ),
281
+ 'id' => esc_attr( $name ),
282
+ 'selected' => esc_attr( $value ),
283
+ 'show_option_all' => __( 'Every', 'synved-option' ) . ' ' . ucfirst( $type ),
284
  );
285
 
286
  $drop_out = null;
287
 
288
+ switch ( $type ) {
 
289
  case 'author':
 
290
  $args['who'] = 'author';
291
+ // no break.
292
  case 'user':
293
+ $drop_out = wp_dropdown_users( $args );
 
 
294
  break;
 
295
  case 'category':
296
+ $drop_out = wp_dropdown_categories( $args );
 
 
297
  break;
 
298
  case 'page':
299
+ $args['show_option_no_change'] = esc_attr( $args['show_option_all'] );
 
 
 
300
 
301
+ $drop_out = wp_dropdown_pages( $args ); // phpcs:ignore
302
  break;
 
303
  }
304
 
305
  $out .= $drop_out;
306
 
307
  break;
 
308
  case 'tag-list':
 
309
  $out .= '<input name="'
310
+ . esc_attr( $out_name )
311
+ . '" id="'
312
+ . esc_attr( $out_id )
313
+ . '" type="text" value="'
314
+ . esc_attr( $value )
315
+ . '" class="regular-text synved-option-tag-selector"'
316
+ . $placeholder
317
+ . ' />';
318
 
319
  break;
 
 
 
 
 
 
 
 
 
 
320
  }
321
 
322
+ if ( false === empty( $hint ) ) {
323
+ $out .= ' <span class="snvdopt"><a class="button synved-option-reset-button" title="' . __(
324
+ 'Set value to default hinted background value',
325
+ 'synved-option'
326
+ ) . '" style="display: inline-block; padding: 0; vertical-align: middle; cursor: pointer;"><span class="ui-icon ui-icon-arrowrefresh-1-w"> </span></a></span>';
327
  }
328
  }
329
 
330
+ $item_render = synved_option_item_render( $item );
331
 
332
+ if ( false === empty( $item_render ) ) {
333
  try {
334
+ $params = array(
335
  'output_name' => $out_name,
336
  'output_id' => $out_id,
337
  'output' => $out,
338
  'set' => $set,
339
  'label' => $label,
340
+ );
341
+ $new_out = $item_render->invoke( array( $value, $params, $name, $id, $item ) );
342
  } catch ( Exception $ex ) {
343
  $new_out = '';
344
  }
349
  }
350
 
351
  if ( false === empty( $out ) ) {
352
+ if ( false === empty( $tip ) && 'boolean' !== $type ) {
353
  $tip_class = ' description-' . $type;
354
+ $out .= '&nbsp;&nbsp;<span class="description' . $tip_class . '">' . $tip . '</span>';
355
  }
356
 
 
 
 
357
  if ( $render ) {
358
+ echo wp_kses( $out, synved_get_allowed_html_array() );
359
  } else {
360
+ return wp_kses( $out, synved_get_allowed_html_array() );
361
  }
362
  }
363
 
synved-option/synved-option-section.php CHANGED
@@ -1,17 +1,37 @@
1
  <?php
 
 
 
 
 
2
 
3
- function synved_option_section_default_name($id, $page)
4
- {
 
 
 
 
 
 
 
5
  return $page . '_section_general';
6
  }
7
 
8
- function synved_option_section_default($id, $page)
9
- {
10
- $section = synved_option_section_default_name($id, $page);
 
 
 
 
 
 
 
11
 
12
- return ['name' => $section,
13
- 'type' => 'options-section',
14
- 'label' => __('General Settings', 'synved-option'),
15
- 'tip' => __('General Settings for', 'synved-option') . ' ' . synved_option_label_from_id($id),
16
- ];
 
17
  }
1
  <?php
2
+ /**
3
+ * Option section helpers.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ /**
9
+ * Section default name.
10
+ *
11
+ * @param string $id ID string.
12
+ * @param string $page Page string.
13
+ *
14
+ * @return string
15
+ */
16
+ function synved_option_section_default_name( $id, $page ) {
17
  return $page . '_section_general';
18
  }
19
 
20
+ /**
21
+ * Section defaults.
22
+ *
23
+ * @param string $id ID string.
24
+ * @param string $page Page string.
25
+ *
26
+ * @return array
27
+ */
28
+ function synved_option_section_default( $id, $page ) {
29
+ $section = synved_option_section_default_name( $id, $page );
30
 
31
+ return array(
32
+ 'name' => $section,
33
+ 'type' => 'options-section',
34
+ 'label' => __( 'General Settings', 'synved-option' ),
35
+ 'tip' => __( 'General Settings for', 'synved-option' ) . ' ' . synved_option_label_from_id( $id ),
36
+ );
37
  }
synved-option/synved-option-setting.php CHANGED
@@ -1,14 +1,21 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
- * @param $post
5
  *
6
- * @return array|mixed
 
 
7
  */
8
- function synved_option_setting_sanitize_item_callback($post) {
9
- if (is_array($post)) {
10
- foreach ($post as $item_key => &$item) {
11
- switch ($item_key) {
12
  case 'rss_follow_link':
13
  case 'youtube_follow_link':
14
  case 'vimeo_follow_link':
@@ -26,7 +33,7 @@ function synved_option_setting_sanitize_item_callback($post) {
26
  case 'linkedin_share_link':
27
  case 'tumblr_follow_link':
28
  case 'tumblr_share_link':
29
- $item = esc_url($item);
30
  break;
31
  case 'automatic_append_postfix':
32
  case 'automatic_append_separator':
@@ -37,16 +44,16 @@ function synved_option_setting_sanitize_item_callback($post) {
37
  case 'automatic_share_prefix':
38
  case 'custom_style':
39
  case 'share_prefix_markup':
40
- $item = str_replace('alert(', 'alert\(', $item);
41
- $item = wp_kses_post($item);
42
  break;
43
  case 'automatic_share_position':
44
  case 'automatic_follow_position':
45
  case 'share_message_default':
46
- $item = esc_html($item);
47
  break;
48
  case 'fb_app_id':
49
- $item = preg_replace('/[^a-zA-Z0-9]+/', '', $item);
50
  break;
51
  case 'automatic_follow':
52
  case 'automatic_follow_before_share':
@@ -60,10 +67,10 @@ function synved_option_setting_sanitize_item_callback($post) {
60
  case 'share_full_url':
61
  case 'shortcode_widgets':
62
  case 'use_shortlinks':
63
- $item = filter_var($item, FILTER_SANITIZE_NUMBER_INT);
64
  break;
65
  default:
66
- $item = filter_var($item, FILTER_SANITIZE_STRING);
67
  break;
68
  }
69
  }
@@ -72,13 +79,18 @@ function synved_option_setting_sanitize_item_callback($post) {
72
  return $post;
73
  }
74
 
75
- function synved_option_setting_sanitize_cb($id, $values)
76
- {
77
- if ($values != null && is_array($values))
78
- {
79
- foreach ($values as $name => $value)
80
- {
81
- $values[$name] = synved_option_item_sanitize_value($id, $name, $values[$name]);
 
 
 
 
 
82
  }
83
 
84
  return $values;
@@ -87,7 +99,15 @@ function synved_option_setting_sanitize_cb($id, $values)
87
  return array();
88
  }
89
 
90
- function synved_option_setting_cb($id, $name, $item)
91
- {
92
- return synved_option_render_item($id, $name, $item, true);
 
 
 
 
 
 
 
 
93
  }
1
  <?php
2
+ /**
3
+ * Option settings.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
  /**
9
+ * Synved option sanitize item callback helper.
10
  *
11
+ * @param array $post Post object array.
12
+ *
13
+ * @return array|mixed Sanitized object array.
14
  */
15
+ function synved_option_setting_sanitize_item_callback( $post ) {
16
+ if ( true === is_array( $post ) ) {
17
+ foreach ( $post as $item_key => &$item ) {
18
+ switch ( $item_key ) {
19
  case 'rss_follow_link':
20
  case 'youtube_follow_link':
21
  case 'vimeo_follow_link':
33
  case 'linkedin_share_link':
34
  case 'tumblr_follow_link':
35
  case 'tumblr_share_link':
36
+ $item = esc_url( $item );
37
  break;
38
  case 'automatic_append_postfix':
39
  case 'automatic_append_separator':
44
  case 'automatic_share_prefix':
45
  case 'custom_style':
46
  case 'share_prefix_markup':
47
+ $item = str_replace( 'alert(', 'alert\(', $item );
48
+ $item = wp_kses_post( $item );
49
  break;
50
  case 'automatic_share_position':
51
  case 'automatic_follow_position':
52
  case 'share_message_default':
53
+ $item = esc_html( $item );
54
  break;
55
  case 'fb_app_id':
56
+ $item = preg_replace( '/[^a-zA-Z0-9]+/', '', $item );
57
  break;
58
  case 'automatic_follow':
59
  case 'automatic_follow_before_share':
67
  case 'share_full_url':
68
  case 'shortcode_widgets':
69
  case 'use_shortlinks':
70
+ $item = filter_var( $item, FILTER_SANITIZE_NUMBER_INT );
71
  break;
72
  default:
73
+ $item = filter_var( $item, FILTER_SANITIZE_STRING );
74
  break;
75
  }
76
  }
79
  return $post;
80
  }
81
 
82
+ /**
83
+ * Option settings sanitizer callback.
84
+ *
85
+ * @param string $id Item ID string.
86
+ * @param array $values Values array.
87
+ *
88
+ * @return array
89
+ */
90
+ function synved_option_setting_sanitize_cb( $id, $values ) {
91
+ if ( false === empty( $values ) && true === is_array( $values ) ) {
92
+ foreach ( $values as $name => $value ) {
93
+ $values[ $name ] = synved_option_item_sanitize_value( $id, $name, $values[ $name ] );
94
  }
95
 
96
  return $values;
99
  return array();
100
  }
101
 
102
+ /**
103
+ * Option settings callback.
104
+ *
105
+ * @param string $id Item ID string.
106
+ * @param string $name Item name string.
107
+ * @param string $item Item value.
108
+ *
109
+ * @return string|null
110
+ */
111
+ function synved_option_setting_cb( $id, $name, $item ) {
112
+ return synved_option_render_item( $id, $name, $item, true );
113
  }
synved-option/synved-option.php CHANGED
@@ -1,20 +1,9 @@
1
  <?php
2
- /*
3
- Module Name: Synved Option
4
- Description: Easily add options to your themes or plugins with as little or as much coding as you want. Just create an array of your options, the rest is automated. If you need extra flexibility you can then use the powerful API provided to achieve any level of customization.
5
- Author: Synved
6
- Version: 1.4.8
7
- Author URI: http://synved.com/
8
- License: GPLv2
9
-
10
- LEGAL STATEMENTS
11
-
12
- NO WARRANTY
13
- All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
14
-
15
- NO LIABILITY
16
- In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
17
- */
18
 
19
  define( 'SYNVED_OPTION_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
20
 
@@ -23,213 +12,70 @@ require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-page.php';
23
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-section.php';
24
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-render.php';
25
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-setting.php';
26
- require_once SYNVED_OPTION_PLUGIN_PATH . 'inc/SynvedOptionCallback.php';
27
 
28
- $synved_option = [];
29
- $synved_option_list = [];
30
 
31
- function synved_option_callback($callback, $default = null, $callback_parameters = null)
32
- {
 
 
 
 
 
 
 
 
33
  $object = null;
34
- $func = $callback;
35
 
36
- if (is_array($callback))
37
- {
38
  $object = $callback[0];
39
- $func = $callback[1];
40
  }
41
 
42
- return new SynvedOptionCallback($func, $object, $default, $callback_parameters);
43
- }
44
-
45
- function synved_option_callback_create($callback_code, $callback_parameters = null)
46
- {
47
- if ($callback_parameters === null)
48
- {
49
- $callback_parameters = array(
50
- 'value' => array(),
51
- 'item' => array('default' => null),
52
- 'name' => array('default' => null),
53
- 'id' => array('default' => null)
54
- );
55
- }
56
- else if (!is_array($callback_parameters))
57
- {
58
- $parameters = explode(',', $callback_parameters);
59
- $callback_parameters = array();
60
-
61
- foreach ($parameters as $param)
62
- {
63
- $param = trim($param);
64
- $param_info = preg_split('/\\s+/', $param, -1, PREG_SPLIT_NO_EMPTY);
65
-
66
- if (count($param_info) > 1)
67
- {
68
- if ($param_info[1] == '=')
69
- {
70
- array_unshift($param_info, null);
71
- }
72
-
73
- $param_type = $param_info[0];
74
- $param_name = ltrim($param_info[1], '$');
75
- $param_manifest = array('type' => $param_type);
76
-
77
- if (count($param_info) > 2)
78
- {
79
- if ($param_info[2] == '=' && isset($param_info[3]))
80
- {
81
- $param_default = trim($param_info[3]);
82
-
83
- if ($param_default == 'null')
84
- {
85
- $param_default = null;
86
- }
87
- else if (in_array($param_default[0], array('\'', '"')))
88
- {
89
- $param_default = trim($param_default, '"\'');
90
- }
91
- else if (strpos($param_default, 'array()') === 0)
92
- {
93
- $param_default = array();
94
- }
95
- else if (strpos($param_default, 'array(') === 0)
96
- {
97
- // No array support
98
- $param_default = null;
99
- }
100
- else if (is_string($param_default))
101
- {
102
- // int or double (float)
103
- if (((string)((int) $param_default)) == $param_default)
104
- {
105
- $param_default = (int) $param_default;
106
- }
107
- else
108
- {
109
- $param_default = (double) $param_default;
110
- }
111
- }
112
-
113
- $param_manifest['default'] = $param_default;
114
- }
115
- }
116
-
117
- $callback_parameters[$param_name] = $param_manifest;
118
- }
119
- else
120
- {
121
- $param_name = ltrim($param_info[0], '$');
122
-
123
- $callback_parameters[$param_name] = array();
124
- }
125
- }
126
- }
127
-
128
- $callback_code = trim($callback_code);
129
- $callback = null;
130
-
131
- if ($callback_code != null)
132
- {
133
- if (substr($callback_code, -1) != ';')
134
- {
135
- $callback_code .= ';';
136
- }
137
-
138
- if (strpos($callback_code, 'return') === false)
139
- {
140
- $result = preg_split('/(?:([\'"])([^\\1]*\\1))|(;)/i', $callback_code, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
141
- $count = count($result);
142
- $partial = null;
143
- $string = null;
144
- $lines = array();
145
-
146
- for ($i = 0; $i < $count; $i++)
147
- {
148
- $split = $result[$i];
149
-
150
- if ($string != null)
151
- {
152
- $partial .= $string . $split;
153
- $string = null;
154
- }
155
- else if ($split == ';')
156
- {
157
- $split = $partial;
158
- $partial = null;
159
- }
160
- else if ($split == '\'')
161
- {
162
- $string = $split;
163
- }
164
- else
165
- {
166
- $partial .= $split;
167
- }
168
-
169
- if ($split != null && $partial == null)
170
- {
171
- $lines[] = $split;
172
- }
173
- }
174
-
175
- $count = count($lines);
176
- $lines[$count - 1] = 'return ' . $lines[$count - 1];
177
-
178
- $callback_code = implode(';', $lines) . ';';
179
- }
180
-
181
- $function_params = null;
182
-
183
- foreach ($callback_parameters as $param_name => $callback_param)
184
- {
185
- $param_type = isset($callback_param['type']) ? $callback_param['type'] : null;
186
- $param_default = isset($callback_param['default']) ? $callback_param['default'] : null;
187
-
188
- if ($function_params != null)
189
- {
190
- $function_params .= ', ';
191
- }
192
-
193
- if ($param_type != null)
194
- {
195
- $function_params .= $param_type;
196
- }
197
-
198
- $function_params .= '$' . $param_name;
199
-
200
- if ($param_default != null)
201
- {
202
- $function_params .= ' = ' . $param_default;
203
- }
204
- }
205
-
206
- $callback = function($function_params) { $callback_code; };
207
-
208
- return synved_option_callback($callback, null, $callback_parameters);
209
- }
210
-
211
- return null;
212
  }
213
 
214
- function synved_option_register($id, array $options)
215
- {
 
 
 
 
 
 
 
216
  global $synved_option_list;
217
 
218
- $synved_option_list[$id] = array('options' => $options, 'items' => array(), 'names' => array(), 'groups' => array(), 'pages' => array(), 'sections' => array(), 'outputs' => array());
 
 
 
 
 
 
 
 
219
  }
220
 
221
- function synved_option_item_list($id)
222
- {
 
 
 
 
 
 
223
  global $synved_option_list;
224
 
225
- if (isset($synved_option_list[$id]))
226
- {
227
- $list = !empty($synved_option_list[$id]['items'])?$synved_option_list[$id]['items']:null;
228
 
229
- if ($list == null)
230
- {
231
- $list = synved_option_prepare_list($id);
232
- $synved_option_list[$id]['items'] = $list;
233
  }
234
 
235
  return $list;
@@ -238,76 +84,80 @@ function synved_option_item_list($id)
238
  return null;
239
  }
240
 
241
- function synved_option_prepare_list($id)
242
- {
 
 
 
 
 
 
243
  global $synved_option_list;
244
 
245
- if (isset($synved_option_list[$id]))
246
- {
247
- $options = !empty($synved_option_list[$id]['options'])?$synved_option_list[$id]['options']:array();
248
- $options = apply_filters('synved_option_init_list', $options, $id);
249
- $options = apply_filters('synved_option_init_list_' . $id, $options, $id);
250
 
251
- $final_list = array();
252
- $default_page = null;
253
  $default_section = null;
254
 
255
- foreach ($options as $name => $item)
256
- {
257
- $type = synved_option_item_type($item);
258
 
259
- if ($type == 'options-page')
260
- {
261
- $item = synved_option_prepare_list_item($id, null, null, $name, $item);
262
 
263
- if ($item != null)
264
- {
265
- $final_list[$name] = $item;
266
  }
267
- }
268
- else
269
- {
270
- if ($default_page == null)
271
- {
272
- $default_page = synved_option_page_default($id);
273
- $default_page = synved_option_prepare_list_item($id, null, null, $default_page['name'], $default_page);
274
-
275
- $final_list[$default_page['name']] = &$default_page;
 
 
 
276
  }
277
 
278
- if ($type == 'options-section')
279
- {
280
- $item = synved_option_prepare_list_item($id, $default_page['name'], null, $name, $item);
281
 
282
- if ($item != null)
283
- {
284
- $default_page['sections'][$name] = $item;
285
  }
286
- }
287
- else
288
- {
289
- if ($default_section == null)
290
- {
291
- $default_section = synved_option_section_default($id, $default_page['name']);
292
- $default_section = synved_option_prepare_list_item($id, $default_page['name'], null, $default_section['name'], $default_section);
293
-
294
- $default_page['sections'][$default_section['name']] = &$default_section;
 
 
 
295
  }
296
 
297
- $default_section['settings'][$name] = $item;
298
  }
299
  }
300
  }
301
 
302
- if ($default_page != null)
303
- {
304
  $item = $default_page;
305
  $name = $item['name'];
306
- $item = synved_option_prepare_list_item($id, null, null, $name, $item);
307
 
308
- if ($item != null)
309
- {
310
- $final_list[$name] = $item;
311
  }
312
  }
313
 
@@ -317,152 +167,188 @@ function synved_option_prepare_list($id)
317
  return null;
318
  }
319
 
320
- function synved_option_prepare_list_item($id, $page, $section, $name, array $item)
321
- {
 
 
 
 
 
 
 
 
 
 
322
  global $synved_option_list;
323
 
324
- $type = synved_option_item_type($item);
325
- $sections = isset($item['sections']) ? $item['sections'] : null;
326
- $settings = isset($item['settings']) ? $item['settings'] : null;
327
 
328
- $item['_synved_option_id'] = $id;
329
  $item['_synved_option_name'] = $name;
330
 
331
- if ($type == 'options-page')
332
- {
333
- if ($sections != null)
334
- {
335
  $list = $sections;
336
 
337
- foreach ($list as $child_name => $child_item)
338
- {
339
- $child_item = synved_option_prepare_list_item($id, $name, null, $child_name, $child_item);
340
 
341
- if ($child_item != null)
342
- {
343
- $list[$child_name] = $child_item;
344
  }
345
  }
346
 
347
  $item['sections'] = $list;
348
  }
349
 
350
- $synved_option_list[$id]['pages'][$name] = $item;
351
- }
352
- else if ($type == 'options-section')
353
- {
354
- if ($settings != null)
355
- {
356
  $list = $settings;
357
 
358
- foreach ($list as $child_name => $child_item)
359
- {
360
- $child_item = synved_option_prepare_list_item($id, $page, $name, $child_name, $child_item);
361
 
362
- if ($child_item != null)
363
- {
364
- $list[$child_name] = $child_item;
365
  }
366
  }
367
 
368
  $item['settings'] = $list;
369
  }
370
 
371
- $synved_option_list[$id]['sections'][$name] = $item;
372
- }
373
- else if (in_array($type, array('style', 'script')))
374
- {
375
- $synved_option_list[$id]['outputs'][$name] = $item;
376
  }
377
 
378
  return $item;
379
  }
380
 
381
- function synved_option_value_list($id)
382
- {
 
 
 
 
 
 
383
  global $synved_option_list;
384
 
385
- if (!isset($synved_option_list[$id]['values']) || $synved_option_list[$id]['values'] == null)
386
- {
387
- $options = get_option(synved_option_name_default($id));
388
 
389
- if ($options != null && is_array($options))
390
- {
391
- $synved_option_list[$id]['values'] = $options;
392
- }
393
- else
394
- {
395
  return array();
396
  }
397
  }
398
 
399
- return $synved_option_list[$id]['values'];
400
  }
401
 
402
- function synved_option_get($id, $name, $default = null)
403
- {
404
- $options = synved_option_value_list($id);
405
- $value = isset($options[$name]) ? $options[$name] : null;
406
- $item = synved_option_item($id, $name);
 
 
 
 
 
 
 
 
407
 
408
- if (!isset($options[$name]) && $default !== null)
409
- {
410
  $value = $default;
411
  }
412
 
413
- if ($item != null)
414
- {
415
- $value = synved_option_item_sanitize_value($id, $name, $value, $item);
416
- }
417
- else if ($default !== null)
418
- {
419
  $value = $default;
420
  }
421
 
422
  return $value;
423
  }
424
 
425
- function synved_option_set($id, $name, $value)
426
- {
 
 
 
 
 
 
 
 
427
  global $synved_option_list;
428
 
429
- $options_name = synved_option_name_default($id);
430
- $options = get_option($options_name);
431
 
432
- $options[$name] = synved_option_item_sanitize_value($id, $name, $value);
433
- update_option($options_name, $options);
434
 
435
- unset($synved_option_list[$id]['values']);
436
  }
437
 
438
- function synved_option_label_from_id($id)
439
- {
440
- return ucwords(str_replace('_', ' ', $id));
 
 
 
 
 
 
441
  }
442
 
443
- function synved_option_name_default($id)
444
- {
 
 
 
 
 
 
445
  global $synved_option_list;
446
 
447
  $name = $id . '_settings';
448
 
449
- if (!isset($synved_option_list[$id]['names'][$name]))
450
- {
451
- $synved_option_list[$id]['names'][$name] = array('type' => 'name', 'label' => synved_option_label_from_id($id));
 
 
452
  }
453
 
454
  return $name;
455
  }
456
 
457
- function synved_option_group_default($id)
458
- {
 
 
 
 
 
 
459
  global $synved_option_list;
460
 
461
  $group = $id . '_settings_group';
462
 
463
- if (!isset($synved_option_list[$id]['groups'][$group]))
464
- {
465
- $synved_option_list[$id]['groups'][$group] = array('type' => 'group', 'label' => synved_option_label_from_id($id));
 
 
466
  }
467
 
468
  return $group;
@@ -474,116 +360,135 @@ function synved_option_group_default($id)
474
  * @return array
475
  */
476
  function synved_get_allowed_html_array() {
477
- return [
478
- 'a' => [
479
- 'class' => [],
480
- 'href' => [],
481
- 'style' => [],
482
- 'target' => [],
483
- 'title' => [],
484
- ],
485
- 'b' => [],
486
- 'br' => [],
487
- 'div' => [
488
- 'class' => [],
489
- 'id' => [],
490
- 'style' => [],
491
- ],
492
- 'fieldset' => [],
493
- 'form' => [
494
- 'action' => [],
495
- 'method' => [],
496
- ],
497
- 'h1' => [],
498
- 'h2' => [],
499
- 'h3' => [],
500
- 'img' => [
501
- 'src' => [],
502
- 'style' => [],
503
- ],
504
- 'input' => [
505
- 'class' => [],
506
- 'checked' => [],
507
- 'id' => [],
508
- 'name' => [],
509
- 'size' => [],
510
- 'placeholder' => [],
511
- 'type' => [],
512
- 'value' => [],
513
- ],
514
- 'label' => [
515
- 'class' => [],
516
- 'for' => [],
517
- 'title' => [],
518
- ],
519
- 'legend' => [
520
- 'class' => [],
521
- ],
522
- 'option' => [
523
- 'selected' => [],
524
- 'value' => [],
525
- ],
526
- 'p' => [
527
- 'class' => [],
528
- 'style' => [],
529
- ],
530
- 'script' => [
531
- 'type' => [],
532
- ],
533
- 'select' => [
534
- 'id' => [],
535
- 'name' => [],
536
- 'multiple' => [],
537
- ],
538
- 'span' => [
539
- 'class' => [],
540
- 'style' => [],
541
- ],
542
- 'table' => [
543
- 'class' => [],
544
- 'role' => [],
545
- ],
546
- 'td' => [],
547
- 'tr' => [],
548
- 'th' => [
549
- 'scope' => [],
550
- ],
551
- ];
 
 
 
 
 
 
 
 
 
552
  }
553
 
554
- function synved_option_wp_handle_setting($id, $page, $section, $name, $item)
555
- {
556
- $type = synved_option_item_type($item);
557
- $label = synved_option_item_label($item);
558
- $sections = isset($item['sections']) ? $item['sections'] : null;
559
- $settings = isset($item['settings']) ? $item['settings'] : null;
560
-
561
- if ($type == 'options-page') {
562
- if ($sections != null) {
563
- $page_slug = synved_option_page_slug($id, $name, $item);
564
-
565
- foreach ($sections as $child_name => $child_item) {
566
- synved_option_wp_handle_setting($id, $page_slug, null, $child_name, $child_item);
 
 
 
 
 
 
 
 
 
 
567
  }
568
  }
569
- } elseif ($type == 'options-section') {
570
  add_settings_section(
571
  $name,
572
  $label,
573
- function () use ($name, $id) {
574
- $item = synved_option_item_find($id, $name);
575
- $tip = synved_option_item_tip($item);
576
 
577
- if ($tip != null) {
578
- echo '<p>' . esc_html( $tip ) . '</p>';
579
  }
580
  },
581
  $page
582
  );
583
 
584
- if ($settings != null) {
585
- foreach ($settings as $child_name => $child_item) {
586
- synved_option_wp_handle_setting($id, $page, $name, $child_name, $child_item);
587
  }
588
  }
589
  } else {
@@ -591,71 +496,82 @@ function synved_option_wp_handle_setting($id, $page, $section, $name, $item)
591
  $name,
592
  $label,
593
  'synved_option_call_array',
594
- $page, $section,
595
- ['synved_option_setting_cb', [$id, $name, $item]]
 
596
  );
597
  }
598
  }
599
 
600
- function synved_option_addon_installed($id, $name, $item = null)
601
- {
602
- $item = synved_option_item($id, $name);
603
-
604
- if ($item != null)
605
- {
606
- return synved_option_item_addon_is_installed($item);
607
- }
608
-
609
- return false;
610
- }
611
-
612
- function synved_option_include_module_addon_list($module_id, $filter = null)
613
- {
614
  global $synved_option;
615
 
616
- $synved_option['module-addon-list'][] = array('module-id' => $module_id, 'filter' => $filter);
 
 
 
617
  }
618
 
619
- function synved_option_init()
620
- {
 
 
 
 
621
  global $synved_option_list;
622
 
623
- if ($synved_option_list != null) {
624
- foreach ($synved_option_list as $id => $list) {
625
- $items = synved_option_item_list($id);
626
  }
627
  }
628
 
629
- $action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
630
 
631
- if (false === empty($action) && 'synved_option' === $action) {
632
  ob_start();
633
  }
634
  }
635
 
636
- function synved_option_call_array($args)
637
- {
638
- call_user_func_array($args[0], $args[1]);
 
 
 
 
 
 
639
  }
640
 
641
- function synved_option_path_uri($path = null)
642
- {
643
- $uri = plugins_url('/synved-options') . '/synved-option';
 
 
 
 
 
 
644
 
645
- if (function_exists('synved_plugout_module_uri_get'))
646
- {
647
- $mod_uri = synved_plugout_module_uri_get('synved-option');
648
 
649
- if ($mod_uri != null)
650
- {
651
  $uri = $mod_uri;
652
  }
653
  }
654
 
655
- if ($path != null)
656
- {
657
- if (substr($uri, -1) != '/' && $path[0] != '/')
658
- {
659
  $uri .= '/';
660
  }
661
 
@@ -665,62 +581,61 @@ function synved_option_path_uri($path = null)
665
  return $uri;
666
  }
667
 
668
- function synved_option_print_head_outputs()
669
- {
 
 
 
 
670
  global $synved_option_list;
671
 
672
- foreach ($synved_option_list as $id => $list)
673
- {
674
- $items = synved_option_item_list($id);
 
675
  $outputs = $list['outputs'];
676
 
677
- foreach ($outputs as $name => $item)
678
- {
679
- $type = synved_option_item_type($item);
680
- $mode = synved_option_item_mode($item);
681
 
682
- if (in_array('manual', $mode))
683
- {
684
  continue;
685
  }
686
 
687
- $content = synved_option_get($id, $name);
688
- $tag = null;
689
- $attrs = null;
690
 
691
- if ($type == 'style')
692
- {
693
- $tag = $type;
694
  $attrs['type'] = 'text/css';
695
- }
696
- else if ($type == 'script')
697
- {
698
- $tag = $type;
699
  $attrs['type'] = 'text/javascript';
700
 
701
  $content = '/* <![CDATA[ */' . "\r\n" . $content . "\r\n" . '/* ]]> */';
702
  }
703
 
704
- if ($tag != null)
705
- {
706
- echo "\r\n" . '<' . $tag;
707
 
708
- foreach ($attrs as $attr_name => $attr_value)
709
- {
710
- echo ' ' . $attr_name . '="' . esc_attr($attr_value) . '"';
711
  }
712
 
713
- echo '>';
714
- echo $content;
715
- echo '</' . $tag . '>' . "\r\n";
716
  }
717
  }
718
  }
719
 
720
  $fb_app_id = synved_option_get( 'synved_social', 'fb_app_id' );
721
- if ( $fb_app_id ) {
722
- printf( '<meta property="fb:app_id" content="%s" />', esc_attr( $fb_app_id ) );
723
- echo '<script>
 
724
  window.fbAsyncInit = function() {
725
  FB.init({
726
  appId : ' . esc_attr( $fb_app_id ) . ',
@@ -739,86 +654,115 @@ function synved_option_print_head_outputs()
739
  }(document, \'script\', \'facebook-jssdk\'));
740
  </script>';
741
  }
 
 
742
  }
743
 
744
- function synved_option_wp_after_setup_theme()
745
- {
 
 
 
 
746
  global $synved_option;
747
 
748
- foreach ($synved_option['module-addon-list'] as $module_addon_load)
749
- {
750
  $module_id = $module_addon_load['module-id'];
751
- $filter = $module_addon_load['filter'];
752
 
753
- $addon_list = synved_plugout_module_addon_list($module_id, $filter);
754
 
755
- if ($addon_list != null)
756
- {
757
- foreach ($addon_list as $addon_name => $addon_file)
758
- {
759
- if (file_exists($addon_file))
760
- {
761
- include_once($addon_file);
762
  }
763
  }
764
  }
765
  }
766
  }
767
 
768
- function synved_option_wp_init()
769
- {
 
 
 
 
770
  synved_option_init();
771
 
772
- if (!is_admin())
773
- {
774
- add_action('wp_head', 'synved_option_print_head_outputs');
775
  }
776
  }
777
 
778
- function synved_option_wp_admin_menu()
779
- {
 
 
 
 
780
  synved_option_page_add_cb();
781
  }
782
 
783
- function synved_option_wp_admin_init()
784
- {
 
 
 
 
785
  global $synved_option_list;
786
 
787
- if ($synved_option_list != null)
788
- {
789
- foreach ($synved_option_list as $id => $list)
790
- {
791
- $dbname = synved_option_name_default($id);
792
- $group = synved_option_group_default($id);
793
 
794
- $option_setting_sanitize_cb = synved_option_setting_sanitize_cb($id, $list);
795
  $option_setting_sanitize_cb['sanitize_callback'] = 'synved_option_setting_sanitize_item_callback';
796
 
797
- register_setting($group, $dbname, $option_setting_sanitize_cb);
798
 
799
- $items = synved_option_item_list($id);
800
 
801
- foreach ($items as $name => $item)
802
- {
803
- synved_option_wp_handle_setting($id, null, null, $name, $item);
804
  }
805
  }
806
  }
807
  }
808
 
 
 
 
 
 
 
 
 
 
809
  function synved_option_wp_upgrader_source_selection( $source, $remote_source, $object = null ) {
810
  if ( is_wp_error( $source ) ) {
811
  return $source;
812
  }
813
 
814
- if ( $object != null && $object instanceof Plugin_Upgrader && method_exists( $object, 'check_package' ) ) {
 
 
 
 
815
  $result = $object->check_package( $source );
816
 
817
- if ( is_wp_error( $result ) ) {
818
  $folder_name = basename( $source );
819
- $addon_item = synved_option_item_query( null, [ [ 'type' => 'addon' ], [ 'folder' => $folder_name ] ] );
820
-
821
- if ( $addon_item != null ) {
 
 
 
 
 
 
822
  $id = $addon_item['_synved_option_id'];
823
  $name = $addon_item['_synved_option_name'];
824
  $addon_page = synved_option_item_page( $id, $name );
@@ -826,9 +770,18 @@ function synved_option_wp_upgrader_source_selection( $source, $remote_source, $o
826
  $page_label = synved_option_item_label( $page_item );
827
  $page_url = synved_option_item_page_link_url( $id, $name );
828
 
829
- $source = new WP_Error( 'synved_option_invalid_plugin_is_addon',
830
- sprintf( __( '<b>This addon must be installed through the <a href="%s">%s settings page</a>.</b>' ),
831
- $page_url, $page_label ), '' );
 
 
 
 
 
 
 
 
 
832
  }
833
  }
834
  }
@@ -836,24 +789,32 @@ function synved_option_wp_upgrader_source_selection( $source, $remote_source, $o
836
  return $source;
837
  }
838
 
 
 
 
 
 
 
 
 
839
  function synved_option_wp_upgrader_pre_install( $perform, $extra ) {
840
- if ( ! isset( $extra['plugin'] ) ) {
841
  return $perform;
842
  }
843
 
844
  $upgrade_transfer = get_option( 'synved_option_wp_upgrade_addon_transfer' );
845
 
846
- if ( $upgrade_transfer != null ) {
847
  $upgrade_transfer_time = get_option( 'synved_option_wp_upgrade_addon_transfer_time' );
848
 
849
- if ( $upgrade_transfer_time == null || ( time() - $upgrade_transfer_time > ( 60 * 60 * 1 ) ) ) {
850
  $upgrade_transfer = null;
851
 
852
  update_option( 'synved_option_wp_upgrade_addon_transfer', '' );
853
  }
854
  }
855
 
856
- if ( function_exists( 'synved_plugout_get_module_list' ) ) {
857
  $module_list = synved_plugout_get_module_list();
858
  } else {
859
  global $synved_plugout;
@@ -862,142 +823,154 @@ function synved_option_wp_upgrader_pre_install( $perform, $extra ) {
862
  }
863
 
864
  $plugins_dir = WP_PLUGIN_DIR;
865
- $plugins_dir = rtrim( str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, realpath( $plugins_dir ) ),
866
- DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
 
 
 
 
 
 
867
 
868
  $plugin = $extra['plugin'];
869
- $plugin_dir = rtrim( str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR,
870
- realpath( dirname( $plugins_dir . $plugin ) ) ), DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
 
 
 
 
 
 
871
 
872
  $dir = get_temp_dir();
873
  $name = time();
874
- $dir = rtrim( $dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . wp_unique_filename( $dir,
875
- $name ) . DIRECTORY_SEPARATOR;
876
- $list = [];
 
 
 
877
 
878
  foreach ( $module_list as $module_id ) {
879
  $addon_list = synved_plugout_module_addon_list( $module_id );
880
 
881
- if ( $addon_list != null ) {
882
  foreach ( $addon_list as $addon_name => $addon_file ) {
883
- if ( file_exists( $addon_file ) ) {
884
  $addon_dir = dirname( $addon_file );
885
  $parent_dir = dirname( $addon_dir );
886
 
887
- // clean names for comparison
888
- $addon_dir = rtrim( str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, realpath( $addon_dir ) ),
889
- DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
890
- $parent_dir = rtrim( str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, realpath( $parent_dir ) ),
891
- DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
892
-
893
- if ( strtolower( $parent_dir ) != strtolower( $plugins_dir ) && strpos( strtolower( $addon_dir ),
894
- strtolower( $plugin_dir ) ) !== false ) {
895
- $path = $dir;
896
- $diff = substr( $addon_dir, strlen( $plugins_dir ) );
 
 
 
 
 
 
 
897
  $path .= $diff;
898
 
899
  wp_mkdir_p( $path );
900
 
901
  copy_dir( $addon_dir, $path );
902
 
903
- $list[] = [ 'original' => $addon_dir, 'temporary' => $path ];
 
 
 
904
  }
905
  }
906
  }
907
  }
908
  }
909
 
910
- if ( $list != null ) {
911
- update_option( 'synved_option_wp_upgrade_addon_transfer', [ 'directory' => $dir, 'list' => $list ] );
 
 
 
 
 
 
912
  update_option( 'synved_option_wp_upgrade_addon_transfer_time', time() );
913
  }
914
 
915
  return $perform;
916
  }
917
 
918
- function synved_option_wp_upgrader_post_install($perform, $extra, $result = null)
919
- {
920
- $upgrade_transfer = get_option('synved_option_wp_upgrade_addon_transfer');
 
 
 
 
 
 
 
 
921
 
922
- if ($upgrade_transfer != null)
923
- {
924
  $list = $upgrade_transfer['list'];
925
 
926
- foreach ($list as $upgrade_item)
927
- {
928
- $original = $upgrade_item['original'];
929
  $temporary = $upgrade_item['temporary'];
930
 
931
- wp_mkdir_p($original);
932
 
933
- copy_dir($temporary, $original);
934
  }
935
 
936
  global $wp_filesystem;
937
 
938
- if ($wp_filesystem != null)
939
- {
940
  $directory = $upgrade_transfer['directory'];
941
 
942
- $wp_filesystem->delete($directory, true);
943
  }
944
 
945
- update_option('synved_option_wp_upgrade_addon_transfer', '');
946
  }
947
 
948
  return $perform;
949
  }
950
 
951
- function synved_option_wp_plugin_action_links($links, $file)
952
- {
953
- global $synved_option_list;
954
-
955
- if ($synved_option_list != null)
956
- {
957
- foreach ($synved_option_list as $id => $list)
958
- {
959
- $items = synved_option_item_list($id);
960
- $pages = $synved_option_list[$id]['pages'];
961
-
962
- foreach ($pages as $name => $page)
963
- {
964
- $link_label = synved_option_item_property($page, 'link-label');
965
- $link_target = synved_option_item_property($page, 'link-target');
966
- $link_url = synved_option_page_link_url($id, $name, $page);
967
-
968
- if ($link_label == null)
969
- {
970
- $link_label = __('Settings');
971
- }
972
-
973
- if ($file == $link_target)
974
- {
975
- $links[] = '<a href="' . $link_url . '">' . $link_label . '</a>';
976
- }
977
- }
978
- }
979
- }
980
-
981
- return $links;
982
- }
983
-
984
- function synved_option_admin_enqueue_scripts()
985
- {
986
  $uri = synved_option_path_uri();
987
- $dir = plugin_dir_path(__FILE__);
988
 
989
- wp_register_style('synved-option-jquery-ui', $uri . '/jqueryUI/css/snvdopt/jquery-ui-1.9.2.custom.min.css', false, '1.9.2');
 
 
 
 
 
990
  wp_register_style(
991
  'synved-option-admin',
992
  $uri . '/style/admin.css',
993
- [ 'wp-jquery-ui-dialog', 'synved-option-jquery-ui' ],
994
  filemtime( $dir . '/style/admin.css' )
995
  );
996
 
997
  wp_register_script(
998
  'synved-option-script-custom',
999
  $uri . '/script/custom.js',
1000
- [
1001
  'jquery',
1002
  'suggest',
1003
  'media-upload',
@@ -1006,35 +979,37 @@ function synved_option_admin_enqueue_scripts()
1006
  'jquery-ui-progressbar',
1007
  'jquery-ui-dialog',
1008
  'wp-util',
1009
- ],
1010
- filemtime($dir . '/script/custom.js')
 
1011
  );
1012
 
1013
- wp_localize_script( 'synved-option-script-custom', 'SynvedOptionVars', [
1014
- 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
1015
- 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
1016
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1017
- 'synvedSecurity' => wp_create_nonce( 'synved-option-submit-nonce' ),
1018
- ] );
 
 
 
 
 
 
1019
 
1020
- $page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
1021
 
1022
  $enqueue = false;
1023
 
1024
  global $synved_option_list;
1025
 
1026
- if ($synved_option_list != null)
1027
- {
1028
- foreach ($synved_option_list as $id => $list)
1029
- {
1030
- if (isset($list['pages']) && $list['pages'] != null)
1031
- {
1032
  $page_list = $list['pages'];
1033
 
1034
- foreach ($page_list as $name => $page_object)
1035
- {
1036
- if ($page == synved_option_page_slug($id, $name))
1037
- {
1038
  $enqueue = true;
1039
 
1040
  break;
@@ -1044,100 +1019,42 @@ function synved_option_admin_enqueue_scripts()
1044
  }
1045
  }
1046
 
1047
- if ($enqueue)
1048
- {
1049
- wp_enqueue_style('thickbox');
1050
- wp_enqueue_style('farbtastic');
1051
- wp_enqueue_style('wp-pointer');
1052
- wp_enqueue_style('synved-option-jquery-ui');
1053
- wp_enqueue_style('synved-option-admin');
1054
-
1055
- wp_enqueue_script('plupload-all');
1056
- wp_enqueue_script('media-upload');
1057
- wp_enqueue_script('suggest');
1058
- wp_enqueue_script('thickbox');
1059
- wp_enqueue_script('farbtastic');
1060
- wp_enqueue_script('synved-option-script-custom');
1061
  }
1062
  }
1063
 
1064
- function synved_option_ajax()
1065
- {
1066
- check_ajax_referer('synved-option-submit-nonce', 'synvedSecurity');
1067
-
1068
- $post = filter_input_array(INPUT_POST, [
1069
- 'synvedAction' => FILTER_SANITIZE_STRING,
1070
- 'synvedParams' => FILTER_SANITIZE_STRING,
1071
- ]);
1072
-
1073
- if (true === empty($post['synvedAction'])) {
1074
- return;
1075
- }
1076
-
1077
- $action = $post['synvedAction'];
1078
- $params = false === empty($post['synvedParams']) ? $post['synvedParams'] : null;
1079
- $response = null;
1080
-
1081
- if (is_string($params)) {
1082
- $parms = json_decode($params, true);
1083
-
1084
- if ($parms == null) {
1085
- $parms = json_decode(stripslashes($params), true);
1086
- }
1087
-
1088
- $params = $parms;
1089
- }
1090
-
1091
- switch ($action) {
1092
- case 'install-addon':
1093
- {
1094
- if (current_user_can('upload_files') && current_user_can('install_plugins')) {
1095
- if (function_exists('synved_option_ajax_type_addon')) {
1096
- $response = synved_option_ajax_type_addon($action, $params);
1097
- }
1098
- }
1099
-
1100
- break;
1101
- }
1102
- }
1103
-
1104
- while (ob_get_level() > 0) {
1105
- ob_end_clean();
1106
- }
1107
 
1108
- if ($response != null) {
1109
- $response = json_encode($response);
1110
-
1111
- header('Content-Type: application/json');
 
1112
 
1113
- echo $response;
1114
- } else {
1115
- header('HTTP/1.1 403 Forbidden');
1116
  }
 
1117
 
1118
- exit();
1119
- }
1120
-
1121
- add_action('after_setup_theme', 'synved_option_wp_after_setup_theme');
1122
- add_action('init', 'synved_option_wp_init');
1123
- add_filter('upgrader_source_selection', 'synved_option_wp_upgrader_source_selection', 9, 3);
1124
- add_filter('upgrader_pre_install', 'synved_option_wp_upgrader_pre_install', 6, 2);
1125
- add_filter('upgrader_post_install', 'synved_option_wp_upgrader_post_install', 10, 3);
1126
- add_filter('plugin_action_links', 'synved_option_wp_plugin_action_links', 10, 2);
1127
 
1128
- // Add 'display' to safe style list.
1129
- add_filter( 'safe_style_css', function( $styles ) {
1130
- $styles[] = 'display';
1131
- return $styles;
1132
- } );
1133
-
1134
-
1135
- if (is_admin())
1136
- {
1137
- add_action('admin_init', 'synved_option_wp_admin_init');
1138
- add_action('admin_menu', 'synved_option_wp_admin_menu');
1139
- add_action('admin_enqueue_scripts', 'synved_option_admin_enqueue_scripts');
1140
- add_action('wp_ajax_synved_option', 'synved_option_ajax');
1141
  }
1142
 
1143
- synved_option_include_module_addon_list('synved-option');
1
  <?php
2
+ /**
3
+ * Option callback class.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  define( 'SYNVED_OPTION_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
9
 
12
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-section.php';
13
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-render.php';
14
  require_once SYNVED_OPTION_PLUGIN_PATH . 'synved-option-setting.php';
15
+ require_once SYNVED_OPTION_PLUGIN_PATH . 'inc/class-synvedoptioncallback.php';
16
 
17
+ $synved_option = array();
18
+ $synved_option_list = array();
19
 
20
+ /**
21
+ * Option callback.
22
+ *
23
+ * @param callable $callback Callable callback fucntion.
24
+ * @param mixed|null $default Default value.
25
+ * @param array|null $callback_parameters Callback paremeters.
26
+ *
27
+ * @return SynvedOptionCallback
28
+ */
29
+ function synved_option_callback( $callback, $default = null, $callback_parameters = null ) {
30
  $object = null;
31
+ $func = $callback;
32
 
33
+ if ( is_array( $callback ) ) {
 
34
  $object = $callback[0];
35
+ $func = $callback[1];
36
  }
37
 
38
+ return new SynvedOptionCallback( $func, $object, $default, $callback_parameters );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
+ /**
42
+ * Register option.
43
+ *
44
+ * @param string $id ID string.
45
+ * @param array $options Options array.
46
+ *
47
+ * @return void
48
+ */
49
+ function synved_option_register( $id, array $options ) {
50
  global $synved_option_list;
51
 
52
+ $synved_option_list[ $id ] = array(
53
+ 'options' => $options,
54
+ 'items' => array(),
55
+ 'names' => array(),
56
+ 'groups' => array(),
57
+ 'pages' => array(),
58
+ 'sections' => array(),
59
+ 'outputs' => array(),
60
+ );
61
  }
62
 
63
+ /**
64
+ * Option item list.
65
+ *
66
+ * @param string $id ID string.
67
+ *
68
+ * @return array|mixed|null
69
+ */
70
+ function synved_option_item_list( $id ) {
71
  global $synved_option_list;
72
 
73
+ if ( true === isset( $synved_option_list[ $id ] ) ) {
74
+ $list = false === empty( $synved_option_list[ $id ]['items'] ) ? $synved_option_list[ $id ]['items'] : null;
 
75
 
76
+ if ( true === empty( $list ) ) {
77
+ $list = synved_option_prepare_list( $id );
78
+ $synved_option_list[ $id ]['items'] = $list;
 
79
  }
80
 
81
  return $list;
84
  return null;
85
  }
86
 
87
+ /**
88
+ * Prepare option list.
89
+ *
90
+ * @param string $id ID string.
91
+ *
92
+ * @return array|null
93
+ */
94
+ function synved_option_prepare_list( $id ) {
95
  global $synved_option_list;
96
 
97
+ if ( true === isset( $synved_option_list[ $id ] ) ) {
98
+ $options = false === empty( $synved_option_list[ $id ]['options'] ) ? $synved_option_list[ $id ]['options'] : array();
99
+ $options = apply_filters( 'synved_option_init_list', $options, $id );
100
+ $options = apply_filters( 'synved_option_init_list_' . $id, $options, $id );
 
101
 
102
+ $final_list = array();
103
+ $default_page = null;
104
  $default_section = null;
105
 
106
+ foreach ( $options as $name => $item ) {
107
+ $type = synved_option_item_type( $item );
 
108
 
109
+ if ( 'options-page' === $type ) {
110
+ $item = synved_option_prepare_list_item( $id, null, null, $name, $item );
 
111
 
112
+ if ( false === empty( $item ) ) {
113
+ $final_list[ $name ] = $item;
 
114
  }
115
+ } else {
116
+ if ( true === empty( $default_page ) ) {
117
+ $default_page = synved_option_page_default( $id );
118
+ $default_page = synved_option_prepare_list_item(
119
+ $id,
120
+ null,
121
+ null,
122
+ $default_page['name'],
123
+ $default_page
124
+ );
125
+
126
+ $final_list[ $default_page['name'] ] = &$default_page;
127
  }
128
 
129
+ if ( 'options-section' === $type ) {
130
+ $item = synved_option_prepare_list_item( $id, $default_page['name'], null, $name, $item );
 
131
 
132
+ if ( false === empty( $item ) ) {
133
+ $default_page['sections'][ $name ] = $item;
 
134
  }
135
+ } else {
136
+ if ( true === empty( $default_section ) ) {
137
+ $default_section = synved_option_section_default( $id, $default_page['name'] );
138
+ $default_section = synved_option_prepare_list_item(
139
+ $id,
140
+ $default_page['name'],
141
+ null,
142
+ $default_section['name'],
143
+ $default_section
144
+ );
145
+
146
+ $default_page['sections'][ $default_section['name'] ] = &$default_section;
147
  }
148
 
149
+ $default_section['settings'][ $name ] = $item;
150
  }
151
  }
152
  }
153
 
154
+ if ( false === empty( $default_page ) ) {
 
155
  $item = $default_page;
156
  $name = $item['name'];
157
+ $item = synved_option_prepare_list_item( $id, null, null, $name, $item );
158
 
159
+ if ( false === empty( $item ) ) {
160
+ $final_list[ $name ] = $item;
 
161
  }
162
  }
163
 
167
  return null;
168
  }
169
 
170
+ /**
171
+ * Prepare option list item.
172
+ *
173
+ * @param string $id ID string.
174
+ * @param string $page Page sring.
175
+ * @param string $section Section string.
176
+ * @param string $name Name string.
177
+ * @param array $item Item array.
178
+ *
179
+ * @return array
180
+ */
181
+ function synved_option_prepare_list_item( $id, $page, $section, $name, array $item ) {
182
  global $synved_option_list;
183
 
184
+ $type = synved_option_item_type( $item );
185
+ $sections = isset( $item['sections'] ) ? $item['sections'] : null;
186
+ $settings = isset( $item['settings'] ) ? $item['settings'] : null;
187
 
188
+ $item['_synved_option_id'] = $id;
189
  $item['_synved_option_name'] = $name;
190
 
191
+ if ( 'options-page' === $type ) {
192
+ if ( false === empty( $sections ) ) {
 
 
193
  $list = $sections;
194
 
195
+ foreach ( $list as $child_name => $child_item ) {
196
+ $child_item = synved_option_prepare_list_item( $id, $name, null, $child_name, $child_item );
 
197
 
198
+ if ( false === empty( $child_item ) ) {
199
+ $list[ $child_name ] = $child_item;
 
200
  }
201
  }
202
 
203
  $item['sections'] = $list;
204
  }
205
 
206
+ $synved_option_list[ $id ]['pages'][ $name ] = $item;
207
+ } elseif ( 'options-section' === $type ) {
208
+ if ( false === empty( $settings ) ) {
 
 
 
209
  $list = $settings;
210
 
211
+ foreach ( $list as $child_name => $child_item ) {
212
+ $child_item = synved_option_prepare_list_item( $id, $page, $name, $child_name, $child_item );
 
213
 
214
+ if ( false === empty( $child_item ) ) {
215
+ $list[ $child_name ] = $child_item;
 
216
  }
217
  }
218
 
219
  $item['settings'] = $list;
220
  }
221
 
222
+ $synved_option_list[ $id ]['sections'][ $name ] = $item;
223
+ } elseif ( true === in_array( $type, array( 'style', 'script' ), true ) ) {
224
+ $synved_option_list[ $id ]['outputs'][ $name ] = $item;
 
 
225
  }
226
 
227
  return $item;
228
  }
229
 
230
+ /**
231
+ * Option value list for ID.
232
+ *
233
+ * @param string $id ID string.
234
+ *
235
+ * @return array|mixed
236
+ */
237
+ function synved_option_value_list( $id ) {
238
  global $synved_option_list;
239
 
240
+ if ( false === isset( $synved_option_list[ $id ]['values'] )
241
+ || null === $synved_option_list[ $id ]['values'] ) {
242
+ $options = get_option( synved_option_name_default( $id ) );
243
 
244
+ if ( false === is_null( $options ) && true === is_array( $options ) ) {
245
+ $synved_option_list[ $id ]['values'] = $options;
246
+ } else {
 
 
 
247
  return array();
248
  }
249
  }
250
 
251
+ return $synved_option_list[ $id ]['values'];
252
  }
253
 
254
+ /**
255
+ * Option get.
256
+ *
257
+ * @param string $id ID string.
258
+ * @param string $name Name string.
259
+ * @param string $default Default value string.
260
+ *
261
+ * @return mixed
262
+ */
263
+ function synved_option_get( $id, $name, $default = null ) {
264
+ $options = synved_option_value_list( $id );
265
+ $value = true === isset( $options[ $name ] ) ? $options[ $name ] : null;
266
+ $item = synved_option_item( $id, $name );
267
 
268
+ if ( false === isset( $options[ $name ] ) && null !== $default ) {
 
269
  $value = $default;
270
  }
271
 
272
+ if ( false === empty( $item ) ) {
273
+ $value = synved_option_item_sanitize_value( $id, $name, $value, $item );
274
+ } elseif ( false === empty( $default ) ) {
 
 
 
275
  $value = $default;
276
  }
277
 
278
  return $value;
279
  }
280
 
281
+ /**
282
+ * Option set.
283
+ *
284
+ * @param string $id ID string.
285
+ * @param string $name Name string.
286
+ * @param string $value Value string.
287
+ *
288
+ * @return void
289
+ */
290
+ function synved_option_set( $id, $name, $value ) {
291
  global $synved_option_list;
292
 
293
+ $options_name = synved_option_name_default( $id );
294
+ $options = get_option( $options_name );
295
 
296
+ $options[ $name ] = synved_option_item_sanitize_value( $id, $name, $value );
297
+ update_option( $options_name, $options );
298
 
299
+ unset( $synved_option_list[ $id ]['values'] );
300
  }
301
 
302
+ /**
303
+ * Option label from ID.
304
+ *
305
+ * @param string $id ID string.
306
+ *
307
+ * @return string
308
+ */
309
+ function synved_option_label_from_id( $id ) {
310
+ return ucwords( str_replace( '_', ' ', $id ) );
311
  }
312
 
313
+ /**
314
+ * Option name default.
315
+ *
316
+ * @param string $id ID string.
317
+ *
318
+ * @return string
319
+ */
320
+ function synved_option_name_default( $id ) {
321
  global $synved_option_list;
322
 
323
  $name = $id . '_settings';
324
 
325
+ if ( false === isset( $synved_option_list[ $id ]['names'][ $name ] ) ) {
326
+ $synved_option_list[ $id ]['names'][ $name ] = array(
327
+ 'type' => 'name',
328
+ 'label' => synved_option_label_from_id( $id ),
329
+ );
330
  }
331
 
332
  return $name;
333
  }
334
 
335
+ /**
336
+ * Option group default.
337
+ *
338
+ * @param string $id ID string.
339
+ *
340
+ * @return string
341
+ */
342
+ function synved_option_group_default( $id ) {
343
  global $synved_option_list;
344
 
345
  $group = $id . '_settings_group';
346
 
347
+ if ( false === isset( $synved_option_list[ $id ]['groups'][ $group ] ) ) {
348
+ $synved_option_list[ $id ]['groups'][ $group ] = array(
349
+ 'type' => 'group',
350
+ 'label' => synved_option_label_from_id( $id ),
351
+ );
352
  }
353
 
354
  return $group;
360
  * @return array
361
  */
362
  function synved_get_allowed_html_array() {
363
+ return array(
364
+ 'a' => array(
365
+ 'class' => array(),
366
+ 'href' => array(),
367
+ 'style' => array(),
368
+ 'target' => array(),
369
+ 'title' => array(),
370
+ ),
371
+ 'b' => array(),
372
+ 'br' => array(),
373
+ 'div' => array(
374
+ 'class' => array(),
375
+ 'id' => array(),
376
+ 'style' => array(),
377
+ ),
378
+ 'fieldset' => array(),
379
+ 'form' => array(
380
+ 'action' => array(),
381
+ 'method' => array(),
382
+ ),
383
+ 'h1' => array(),
384
+ 'h2' => array(),
385
+ 'h3' => array(),
386
+ 'img' => array(
387
+ 'src' => array(),
388
+ 'style' => array(),
389
+ ),
390
+ 'input' => array(
391
+ 'class' => array(),
392
+ 'checked' => array(),
393
+ 'id' => array(),
394
+ 'name' => array(),
395
+ 'size' => array(),
396
+ 'placeholder' => array(),
397
+ 'type' => array(),
398
+ 'value' => array(),
399
+ ),
400
+ 'label' => array(
401
+ 'class' => array(),
402
+ 'for' => array(),
403
+ 'title' => array(),
404
+ ),
405
+ 'legend' => array(
406
+ 'class' => array(),
407
+ ),
408
+ 'meta' => array(
409
+ 'content' => array(),
410
+ 'property' => array(),
411
+ ),
412
+ 'option' => array(
413
+ 'selected' => array(),
414
+ 'value' => array(),
415
+ ),
416
+ 'p' => array(
417
+ 'align' => array(),
418
+ 'class' => array(),
419
+ 'style' => array(),
420
+ ),
421
+ 'script' => array(
422
+ 'type' => array(),
423
+ ),
424
+ 'select' => array(
425
+ 'id' => array(),
426
+ 'name' => array(),
427
+ 'multiple' => array(),
428
+ ),
429
+ 'span' => array(
430
+ 'class' => array(),
431
+ 'style' => array(),
432
+ ),
433
+ 'strong' => array(),
434
+ 'style' => array(
435
+ 'type' => array(),
436
+ ),
437
+ 'table' => array(
438
+ 'class' => array(),
439
+ 'role' => array(),
440
+ ),
441
+ 'td' => array(),
442
+ 'tr' => array(),
443
+ 'th' => array(
444
+ 'scope' => array(),
445
+ ),
446
+ );
447
  }
448
 
449
+ /**
450
+ * WP Handle Setting.
451
+ *
452
+ * @param string $id ID string.
453
+ * @param string $page Page string.
454
+ * @param string $section Section string.
455
+ * @param string $name Name string.
456
+ * @param array $item Item array.
457
+ *
458
+ * @return void
459
+ */
460
+ function synved_option_wp_handle_setting( $id, $page, $section, $name, $item ) {
461
+ $type = synved_option_item_type( $item );
462
+ $label = synved_option_item_label( $item );
463
+ $sections = true === isset( $item['sections'] ) ? $item['sections'] : null;
464
+ $settings = true === isset( $item['settings'] ) ? $item['settings'] : null;
465
+
466
+ if ( 'options-page' === $type ) {
467
+ if ( false === empty( $sections ) ) {
468
+ $page_slug = synved_option_page_slug( $id, $name, $item );
469
+
470
+ foreach ( $sections as $child_name => $child_item ) {
471
+ synved_option_wp_handle_setting( $id, $page_slug, null, $child_name, $child_item );
472
  }
473
  }
474
+ } elseif ( 'options-section' === $type ) {
475
  add_settings_section(
476
  $name,
477
  $label,
478
+ function () use ( $name, $id ) {
479
+ $item = synved_option_item_find( $id, $name );
480
+ $tip = synved_option_item_tip( $item );
481
 
482
+ if ( false === empty( $tip ) ) {
483
+ echo wp_kses( '<p>' . esc_html( $tip ) . '</p>', synved_get_allowed_html_array() );
484
  }
485
  },
486
  $page
487
  );
488
 
489
+ if ( false === empty( $settings ) ) {
490
+ foreach ( $settings as $child_name => $child_item ) {
491
+ synved_option_wp_handle_setting( $id, $page, $name, $child_name, $child_item );
492
  }
493
  }
494
  } else {
496
  $name,
497
  $label,
498
  'synved_option_call_array',
499
+ $page,
500
+ $section,
501
+ array( 'synved_option_setting_cb', array( $id, $name, $item ) )
502
  );
503
  }
504
  }
505
 
506
+ /**
507
+ * Include module addon list.
508
+ *
509
+ * @param string $module_id Module ID.
510
+ * @param string|null $filter Filter to run.
511
+ *
512
+ * @return void
513
+ */
514
+ function synved_option_include_module_addon_list( $module_id, $filter = null ) {
 
 
 
 
 
515
  global $synved_option;
516
 
517
+ $synved_option['module-addon-list'][] = array(
518
+ 'module-id' => $module_id,
519
+ 'filter' => $filter,
520
+ );
521
  }
522
 
523
+ /**
524
+ * Option init.
525
+ *
526
+ * @return void
527
+ */
528
+ function synved_option_init() {
529
  global $synved_option_list;
530
 
531
+ if ( false === empty( $synved_option_list ) ) {
532
+ foreach ( $synved_option_list as $id => $list ) {
533
+ $items = synved_option_item_list( $id );
534
  }
535
  }
536
 
537
+ $action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
538
 
539
+ if ( false === empty( $action ) && 'synved_option' === $action ) {
540
  ob_start();
541
  }
542
  }
543
 
544
+ /**
545
+ * Call array.
546
+ *
547
+ * @param array $args Arguments array.
548
+ *
549
+ * @return void
550
+ */
551
+ function synved_option_call_array( $args ) {
552
+ call_user_func_array( $args[0], $args[1] );
553
  }
554
 
555
+ /**
556
+ * Option path URI.
557
+ *
558
+ * @param string|null $path Path string.
559
+ *
560
+ * @return string
561
+ */
562
+ function synved_option_path_uri( $path = null ) {
563
+ $uri = plugins_url( '/synved-options' ) . '/synved-option';
564
 
565
+ if ( function_exists( 'synved_plugout_module_uri_get' ) ) {
566
+ $mod_uri = synved_plugout_module_uri_get( 'synved-option' );
 
567
 
568
+ if ( false === empty( $mod_uri ) ) {
 
569
  $uri = $mod_uri;
570
  }
571
  }
572
 
573
+ if ( false === empty( $path ) ) {
574
+ if ( '/' !== substr( $uri, - 1 ) && '/' !== $path[0] ) {
 
 
575
  $uri .= '/';
576
  }
577
 
581
  return $uri;
582
  }
583
 
584
+ /**
585
+ * Print head outputs.
586
+ *
587
+ * @return void
588
+ */
589
+ function synved_option_print_head_outputs() {
590
  global $synved_option_list;
591
 
592
+ $output = '';
593
+
594
+ foreach ( $synved_option_list as $id => $list ) {
595
+ $items = synved_option_item_list( $id );
596
  $outputs = $list['outputs'];
597
 
598
+ foreach ( $outputs as $name => $item ) {
599
+ $type = synved_option_item_type( $item );
600
+ $mode = synved_option_item_mode( $item );
 
601
 
602
+ if ( true === in_array( 'manual', $mode, true ) ) {
 
603
  continue;
604
  }
605
 
606
+ $content = synved_option_get( $id, $name );
607
+ $tag = null;
608
+ $attrs = null;
609
 
610
+ if ( 'style' === $type ) {
611
+ $tag = $type;
 
612
  $attrs['type'] = 'text/css';
613
+ } elseif ( 'script' === $type ) {
614
+ $tag = $type;
 
 
615
  $attrs['type'] = 'text/javascript';
616
 
617
  $content = '/* <![CDATA[ */' . "\r\n" . $content . "\r\n" . '/* ]]> */';
618
  }
619
 
620
+ if ( false === empty( $tag ) ) {
621
+ $output .= "\r\n" . '<' . $tag;
 
622
 
623
+ foreach ( $attrs as $attr_name => $attr_value ) {
624
+ $output .= ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
 
625
  }
626
 
627
+ $output .= '>';
628
+ $output .= $content;
629
+ $output .= '</' . $tag . '>' . "\r\n";
630
  }
631
  }
632
  }
633
 
634
  $fb_app_id = synved_option_get( 'synved_social', 'fb_app_id' );
635
+
636
+ if ( false === empty( $fb_app_id ) ) {
637
+ $output .= sprintf( '<meta property="fb:app_id" content="%s" />', esc_attr( $fb_app_id ) );
638
+ $output .= '<script>
639
  window.fbAsyncInit = function() {
640
  FB.init({
641
  appId : ' . esc_attr( $fb_app_id ) . ',
654
  }(document, \'script\', \'facebook-jssdk\'));
655
  </script>';
656
  }
657
+
658
+ echo wp_kses( $output, synved_get_allowed_html_array() );
659
  }
660
 
661
+ /**
662
+ * After setup theme.
663
+ *
664
+ * @return void
665
+ */
666
+ function synved_option_wp_after_setup_theme() {
667
  global $synved_option;
668
 
669
+ foreach ( $synved_option['module-addon-list'] as $module_addon_load ) {
 
670
  $module_id = $module_addon_load['module-id'];
671
+ $filter = $module_addon_load['filter'];
672
 
673
+ $addon_list = synved_plugout_module_addon_list( $module_id, $filter );
674
 
675
+ if ( false === empty( $addon_list ) ) {
676
+ foreach ( $addon_list as $addon_name => $addon_file ) {
677
+ if ( true === file_exists( $addon_file ) ) {
678
+ include_once $addon_file;
 
 
 
679
  }
680
  }
681
  }
682
  }
683
  }
684
 
685
+ /**
686
+ * WP Init.
687
+ *
688
+ * @return void
689
+ */
690
+ function synved_option_wp_init() {
691
  synved_option_init();
692
 
693
+ if ( false === is_admin() ) {
694
+ add_action( 'wp_head', 'synved_option_print_head_outputs' );
 
695
  }
696
  }
697
 
698
+ /**
699
+ * WP Admin Menu.
700
+ *
701
+ * @return void
702
+ */
703
+ function synved_option_wp_admin_menu() {
704
  synved_option_page_add_cb();
705
  }
706
 
707
+ /**
708
+ * WP Admin Init.
709
+ *
710
+ * @return void
711
+ */
712
+ function synved_option_wp_admin_init() {
713
  global $synved_option_list;
714
 
715
+ if ( false === empty( $synved_option_list ) ) {
716
+ foreach ( $synved_option_list as $id => $list ) {
717
+ $dbname = synved_option_name_default( $id );
718
+ $group = synved_option_group_default( $id );
 
 
719
 
720
+ $option_setting_sanitize_cb = synved_option_setting_sanitize_cb( $id, $list );
721
  $option_setting_sanitize_cb['sanitize_callback'] = 'synved_option_setting_sanitize_item_callback';
722
 
723
+ register_setting( $group, $dbname, $option_setting_sanitize_cb );
724
 
725
+ $items = synved_option_item_list( $id );
726
 
727
+ foreach ( $items as $name => $item ) {
728
+ synved_option_wp_handle_setting( $id, null, null, $name, $item );
 
729
  }
730
  }
731
  }
732
  }
733
 
734
+ /**
735
+ * WP Upgrader Source Selection.
736
+ *
737
+ * @param string|WP_Error $source Source string.
738
+ * @param string $remote_source Remote source string.
739
+ * @param Plugin_Upgrader $object Upgrader object.
740
+ *
741
+ * @return mixed|WP_Error
742
+ */
743
  function synved_option_wp_upgrader_source_selection( $source, $remote_source, $object = null ) {
744
  if ( is_wp_error( $source ) ) {
745
  return $source;
746
  }
747
 
748
+ if (
749
+ false === empty( $object )
750
+ && true === $object instanceof Plugin_Upgrader
751
+ && true === method_exists( $object, 'check_package' )
752
+ ) {
753
  $result = $object->check_package( $source );
754
 
755
+ if ( true === is_wp_error( $result ) ) {
756
  $folder_name = basename( $source );
757
+ $addon_item = synved_option_item_query(
758
+ null,
759
+ array(
760
+ array( 'type' => 'addon' ),
761
+ array( 'folder' => $folder_name ),
762
+ )
763
+ );
764
+
765
+ if ( false === empty( $addon_item ) ) {
766
  $id = $addon_item['_synved_option_id'];
767
  $name = $addon_item['_synved_option_name'];
768
  $addon_page = synved_option_item_page( $id, $name );
770
  $page_label = synved_option_item_label( $page_item );
771
  $page_url = synved_option_item_page_link_url( $id, $name );
772
 
773
+ $source = new WP_Error(
774
+ 'synved_option_invalid_plugin_is_addon',
775
+ sprintf(
776
+ /* translators: %1$s is the page URL. %2$s is the page label. */
777
+ __(
778
+ 'This addon must be installed through the <a href="%1$s">%2$s settings page</a>.'
779
+ ),
780
+ $page_url,
781
+ $page_label
782
+ ),
783
+ ''
784
+ );
785
  }
786
  }
787
  }
789
  return $source;
790
  }
791
 
792
+ /**
793
+ * WP Upgrader Pre Install.
794
+ *
795
+ * @param bool|WP_Error $perform Response.
796
+ * @param array $extra Hook extra.
797
+ *
798
+ * @return mixed
799
+ */
800
  function synved_option_wp_upgrader_pre_install( $perform, $extra ) {
801
+ if ( false === isset( $extra['plugin'] ) ) {
802
  return $perform;
803
  }
804
 
805
  $upgrade_transfer = get_option( 'synved_option_wp_upgrade_addon_transfer' );
806
 
807
+ if ( false === empty( $upgrade_transfer ) ) {
808
  $upgrade_transfer_time = get_option( 'synved_option_wp_upgrade_addon_transfer_time' );
809
 
810
+ if ( true === empty( $upgrade_transfer_time ) || ( time() - $upgrade_transfer_time > ( 60 * 60 * 1 ) ) ) {
811
  $upgrade_transfer = null;
812
 
813
  update_option( 'synved_option_wp_upgrade_addon_transfer', '' );
814
  }
815
  }
816
 
817
+ if ( true === function_exists( 'synved_plugout_get_module_list' ) ) {
818
  $module_list = synved_plugout_get_module_list();
819
  } else {
820
  global $synved_plugout;
823
  }
824
 
825
  $plugins_dir = WP_PLUGIN_DIR;
826
+ $plugins_dir = rtrim(
827
+ str_replace(
828
+ array( '\\', '/' ),
829
+ DIRECTORY_SEPARATOR,
830
+ realpath( $plugins_dir )
831
+ ),
832
+ DIRECTORY_SEPARATOR
833
+ ) . DIRECTORY_SEPARATOR;
834
 
835
  $plugin = $extra['plugin'];
836
+ $plugin_dir = rtrim(
837
+ str_replace(
838
+ array( '\\', '/' ),
839
+ DIRECTORY_SEPARATOR,
840
+ realpath( dirname( $plugins_dir . $plugin ) )
841
+ ),
842
+ DIRECTORY_SEPARATOR
843
+ ) . DIRECTORY_SEPARATOR;
844
 
845
  $dir = get_temp_dir();
846
  $name = time();
847
+ $dir = rtrim( $dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . wp_unique_filename(
848
+ $dir,
849
+ $name
850
+ ) . DIRECTORY_SEPARATOR;
851
+
852
+ $list = array();
853
 
854
  foreach ( $module_list as $module_id ) {
855
  $addon_list = synved_plugout_module_addon_list( $module_id );
856
 
857
+ if ( false === empty( $addon_list ) ) {
858
  foreach ( $addon_list as $addon_name => $addon_file ) {
859
+ if ( true === file_exists( $addon_file ) ) {
860
  $addon_dir = dirname( $addon_file );
861
  $parent_dir = dirname( $addon_dir );
862
 
863
+ // Clean names for comparison.
864
+ $addon_dir = rtrim(
865
+ str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, realpath( $addon_dir ) ),
866
+ DIRECTORY_SEPARATOR
867
+ ) . DIRECTORY_SEPARATOR;
868
+
869
+ $parent_dir = rtrim(
870
+ str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, realpath( $parent_dir ) ),
871
+ DIRECTORY_SEPARATOR
872
+ ) . DIRECTORY_SEPARATOR;
873
+
874
+ if (
875
+ strtolower( $parent_dir ) !== strtolower( $plugins_dir )
876
+ && false !== strpos( strtolower( $addon_dir ), strtolower( $plugin_dir ) )
877
+ ) {
878
+ $path = $dir;
879
+ $diff = substr( $addon_dir, strlen( $plugins_dir ) );
880
  $path .= $diff;
881
 
882
  wp_mkdir_p( $path );
883
 
884
  copy_dir( $addon_dir, $path );
885
 
886
+ $list[] = array(
887
+ 'original' => $addon_dir,
888
+ 'temporary' => $path,
889
+ );
890
  }
891
  }
892
  }
893
  }
894
  }
895
 
896
+ if ( false === empty( $list ) ) {
897
+ update_option(
898
+ 'synved_option_wp_upgrade_addon_transfer',
899
+ array(
900
+ 'directory' => $dir,
901
+ 'list' => $list,
902
+ )
903
+ );
904
  update_option( 'synved_option_wp_upgrade_addon_transfer_time', time() );
905
  }
906
 
907
  return $perform;
908
  }
909
 
910
+ /**
911
+ * WP Upgrader Post Install.
912
+ *
913
+ * @param bool|WP_Error $perform Installation response.
914
+ * @param array $extra Extra arguments passed to hooked filters.
915
+ * @param array $result Installation result data.
916
+ *
917
+ * @return mixed
918
+ */
919
+ function synved_option_wp_upgrader_post_install( $perform, $extra, $result = null ) {
920
+ $upgrade_transfer = get_option( 'synved_option_wp_upgrade_addon_transfer' );
921
 
922
+ if ( false === empty( $upgrade_transfer ) ) {
 
923
  $list = $upgrade_transfer['list'];
924
 
925
+ foreach ( $list as $upgrade_item ) {
926
+ $original = $upgrade_item['original'];
 
927
  $temporary = $upgrade_item['temporary'];
928
 
929
+ wp_mkdir_p( $original );
930
 
931
+ copy_dir( $temporary, $original );
932
  }
933
 
934
  global $wp_filesystem;
935
 
936
+ if ( false === empty( $wp_filesystem ) ) {
 
937
  $directory = $upgrade_transfer['directory'];
938
 
939
+ $wp_filesystem->delete( $directory, true );
940
  }
941
 
942
+ update_option( 'synved_option_wp_upgrade_addon_transfer', '' );
943
  }
944
 
945
  return $perform;
946
  }
947
 
948
+ /**
949
+ * Admin enqueue scripts.
950
+ *
951
+ * @return void
952
+ */
953
+ function synved_option_admin_enqueue_scripts() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
954
  $uri = synved_option_path_uri();
955
+ $dir = plugin_dir_path( __FILE__ );
956
 
957
+ wp_register_style(
958
+ 'synved-option-jquery-ui',
959
+ $uri . '/jqueryUI/css/snvdopt/jquery-ui-1.9.2.custom.min.css',
960
+ false,
961
+ '1.9.2'
962
+ );
963
  wp_register_style(
964
  'synved-option-admin',
965
  $uri . '/style/admin.css',
966
+ array( 'wp-jquery-ui-dialog', 'synved-option-jquery-ui' ),
967
  filemtime( $dir . '/style/admin.css' )
968
  );
969
 
970
  wp_register_script(
971
  'synved-option-script-custom',
972
  $uri . '/script/custom.js',
973
+ array(
974
  'jquery',
975
  'suggest',
976
  'media-upload',
979
  'jquery-ui-progressbar',
980
  'jquery-ui-dialog',
981
  'wp-util',
982
+ ),
983
+ filemtime( $dir . '/script/custom.js' ),
984
+ false
985
  );
986
 
987
+ wp_localize_script(
988
+ 'synved-option-script-custom',
989
+ 'SynvedOptionVars',
990
+ array(
991
+ 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
992
+ 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
993
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
994
+ 'synvedSecurity' => wp_create_nonce( 'synved-option-submit-nonce' ),
995
+ 'termsURLAgree' => admin_url( 'options-general.php?page=social-media-feather-settings&accept-terms=yes' ),
996
+ 'termsURLDisagree' => admin_url( 'options-general.php?page=social-media-feather-settings&accept-terms=no' ),
997
+ )
998
+ );
999
 
1000
+ $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
1001
 
1002
  $enqueue = false;
1003
 
1004
  global $synved_option_list;
1005
 
1006
+ if ( false === empty( $synved_option_list ) ) {
1007
+ foreach ( $synved_option_list as $id => $list ) {
1008
+ if ( false === empty( $list['pages'] ) ) {
 
 
 
1009
  $page_list = $list['pages'];
1010
 
1011
+ foreach ( $page_list as $name => $page_object ) {
1012
+ if ( synved_option_page_slug( $id, $name ) === $page ) {
 
 
1013
  $enqueue = true;
1014
 
1015
  break;
1019
  }
1020
  }
1021
 
1022
+ if ( $enqueue ) {
1023
+ wp_enqueue_style( 'thickbox' );
1024
+ wp_enqueue_style( 'farbtastic' );
1025
+ wp_enqueue_style( 'wp-pointer' );
1026
+ wp_enqueue_style( 'synved-option-jquery-ui' );
1027
+ wp_enqueue_style( 'synved-option-admin' );
1028
+
1029
+ wp_enqueue_script( 'plupload-all' );
1030
+ wp_enqueue_script( 'media-upload' );
1031
+ wp_enqueue_script( 'suggest' );
1032
+ wp_enqueue_script( 'thickbox' );
1033
+ wp_enqueue_script( 'farbtastic' );
1034
+ wp_enqueue_script( 'synved-option-script-custom' );
 
1035
  }
1036
  }
1037
 
1038
+ add_action( 'after_setup_theme', 'synved_option_wp_after_setup_theme' );
1039
+ add_action( 'init', 'synved_option_wp_init' );
1040
+ add_filter( 'upgrader_source_selection', 'synved_option_wp_upgrader_source_selection', 9, 3 );
1041
+ add_filter( 'upgrader_pre_install', 'synved_option_wp_upgrader_pre_install', 6, 2 );
1042
+ add_filter( 'upgrader_post_install', 'synved_option_wp_upgrader_post_install', 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1043
 
1044
+ // Add 'display' to safe style list.
1045
+ add_filter(
1046
+ 'safe_style_css',
1047
+ function ( $styles ) {
1048
+ $styles[] = 'display';
1049
 
1050
+ return $styles;
 
 
1051
  }
1052
+ );
1053
 
 
 
 
 
 
 
 
 
 
1054
 
1055
+ if ( is_admin() ) {
1056
+ add_action( 'admin_init', 'synved_option_wp_admin_init' );
1057
+ add_action( 'admin_enqueue_scripts', 'synved_option_admin_enqueue_scripts' );
 
 
 
 
 
 
 
 
 
 
1058
  }
1059
 
1060
+ synved_option_include_module_addon_list( 'synved-option' );
synved-plugout/synved-plugout-core.php CHANGED
@@ -1,62 +1,89 @@
1
  <?php
2
-
3
- const SYNVED_PLUGOUT_LOADED = true;
 
 
 
 
 
 
 
4
  const SYNVED_PLUGOUT_VERSION = 100000002;
5
- const SYNVED_PLUGOUT_VERSION_STRING = '1.0.2';
6
-
7
 
8
  $synved_plugout = array();
9
 
10
-
11
- function synved_plugout_version()
12
- {
 
 
 
13
  return SYNVED_PLUGOUT_VERSION;
14
  }
15
 
16
- function synved_plugout_path_default($path_id)
17
- {
18
- switch ($path_id)
19
- {
 
 
 
 
 
20
  case 'module':
21
- {
22
- return dirname(dirname(__FILE__));
23
- }
24
  }
25
 
26
  return null;
27
  }
28
 
29
- function synved_plugout_path_get($path_id)
30
- {
 
 
 
 
 
 
31
  global $synved_plugout;
32
 
33
- if (isset($synved_plugout['path'][$path_id]))
34
- {
35
- return $synved_plugout['path'][$path_id];
36
  }
37
 
38
- return synved_plugout_path_default($path_id);
39
  }
40
 
41
- function synved_plugout_get_module_list()
42
- {
 
 
 
 
43
  global $synved_plugout;
44
 
45
- return array_keys($synved_plugout['module-list']);
46
  }
47
 
48
- function synved_plugout_module_register($module_id, $module_prefix = null, $module_name = null)
49
- {
 
 
 
 
 
 
 
 
50
  global $synved_plugout;
51
 
52
- if (!isset($synved_plugout['module-list'][$module_id]))
53
- {
54
- $synved_plugout['module-list'][$module_id] = array(
55
- 'id' => $module_id,
56
- 'name' => $module_name,
57
- 'prefix' => $module_prefix,
58
- 'location' => null,
59
- 'callback-list' => array()
60
  );
61
 
62
  return true;
@@ -65,18 +92,26 @@ function synved_plugout_module_register($module_id, $module_prefix = null, $modu
65
  return false;
66
  }
67
 
68
- function synved_plugout_module_path_add($module_id, $type, $path, $meta = null)
69
- {
 
 
 
 
 
 
 
 
 
70
  global $synved_plugout;
71
 
72
- if (isset($synved_plugout['module-list'][$module_id]))
73
- {
74
- $path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $path);
75
 
76
- $path_object = $meta ? $meta : array();
77
  $path_object['path'] = $path;
78
 
79
- $synved_plugout['module-list'][$module_id]['path-list'][$type][] = $path_object;
80
 
81
  return true;
82
  }
@@ -84,36 +119,45 @@ function synved_plugout_module_path_add($module_id, $type, $path, $meta = null)
84
  return false;
85
  }
86
 
87
- function synved_plugout_module_path_get($module_id, $type)
88
- {
89
- $path_list = synved_plugout_module_path_list_get($module_id, $type, 'first');
90
-
91
- if ($path_list != null)
92
- {
 
 
 
 
 
 
93
  return $path_list[0]['path'];
94
  }
95
 
96
  return null;
97
  }
98
 
99
- function synved_plugout_module_path_list_get($module_id, $type, $criteria = null)
100
- {
 
 
 
 
 
 
 
 
101
  global $synved_plugout;
102
 
103
- if (isset($synved_plugout['module-list'][$module_id]))
104
- {
105
- $path_list = $synved_plugout['module-list'][$module_id]['path-list'];
106
 
107
- if ($path_list != null)
108
- {
109
  $return_list = array();
110
 
111
- foreach ($path_list as $path_type => $path_type_list)
112
- {
113
- if ($type == null || $type == $path_type)
114
- {
115
- foreach ($path_type_list as $path_object)
116
- {
117
  $return_item = array();
118
 
119
  $return_item['type'] = $path_type;
@@ -132,34 +176,42 @@ function synved_plugout_module_path_list_get($module_id, $type, $criteria = null
132
  return null;
133
  }
134
 
135
- function synved_plugout_module_get($module_id)
136
- {
 
 
 
 
 
 
137
  global $synved_plugout;
138
 
139
- if (isset($synved_plugout['module-list'][$module_id]))
140
- {
141
- return $synved_plugout['module-list'][$module_id];
142
  }
143
 
144
  return null;
145
  }
146
 
147
- function synved_plugout_module_version($module_id)
148
- {
149
- $module = synved_plugout_module_get($module_id);
150
-
151
- if ($module !== null)
152
- {
153
- $module_cb = isset($module['callback-list']) ? $module['callback-list'] : null;
154
- $version_cb = str_replace('-', '_', $module_id) . '_version';
155
-
156
- if (isset($module_cb['version']))
157
- {
 
 
 
 
158
  $version_cb = $module_cb['version'];
159
  }
160
 
161
- if (is_callable($version_cb))
162
- {
163
  return $version_cb();
164
  }
165
  }
@@ -167,14 +219,18 @@ function synved_plugout_module_version($module_id)
167
  return false;
168
  }
169
 
170
- function synved_plugout_module_location_get($module_id)
171
- {
172
- $module = synved_plugout_module_get($module_id);
173
-
174
- if ($module != null)
175
- {
176
- if (isset($module['location']))
177
- {
 
 
 
 
178
  return $module['location'];
179
  }
180
  }
@@ -182,101 +238,103 @@ function synved_plugout_module_location_get($module_id)
182
  return null;
183
  }
184
 
185
- function synved_plugout_module_directory_get($module_id)
186
- {
187
- $location = synved_plugout_module_location_get($module_id);
188
-
189
- if ($location != null)
190
- {
191
- return dirname($location);
 
 
 
 
 
192
  }
193
 
194
  return null;
195
  }
196
 
197
- function synved_plugout_module_uri_get($module_id)
198
- {
199
- $directory = synved_plugout_module_directory_get($module_id);
200
-
201
- if ($directory != null)
202
- {
203
- $directory = strtolower(str_replace(array('\\', '/'), '/', $directory));
204
- $content_dir = strtolower(str_replace(array('\\', '/'), '/', WP_CONTENT_DIR));
205
- $base_len = strlen($content_dir);
206
-
207
- if (substr($directory, 0, $base_len) == $content_dir)
208
- {
209
- return content_url(substr($directory, $base_len));
 
 
 
 
210
  }
211
  }
212
 
213
  return null;
214
  }
215
 
216
- function synved_plugout_module_import($module_id)
217
- {
 
 
 
 
 
 
218
  // This is needed because on activation the plugin's code is included *after* the theme code.
219
- $request_uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING);
220
- $action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
221
 
222
- if (false !== strpos($request_uri, '/plugins.php?') && 'activate' === $action) {
223
  return false;
224
  }
225
 
226
  global $synved_plugout;
227
 
228
- if (isset($synved_plugout['module-list'][$module_id]))
229
- {
230
- $lib_path = synved_plugout_module_path_get($module_id, 'library');
231
- $core_path = synved_plugout_module_path_get($module_id, 'core');
232
 
233
- if ($lib_path == null)
234
- {
235
- if ($core_path == null)
236
- {
237
- $module_path = synved_plugout_path_get('module');
238
 
239
- if (substr($module_path, -1) != DIRECTORY_SEPARATOR)
240
- {
241
  $module_path .= DIRECTORY_SEPARATOR;
242
  }
243
 
244
  $core_path = $module_path . $module_id;
245
  }
246
 
247
- if (is_dir($core_path))
248
- {
249
- if (substr($core_path, -1) != DIRECTORY_SEPARATOR)
250
- {
251
  $core_path .= DIRECTORY_SEPARATOR;
252
  }
253
 
254
  $lib_path = $core_path . $module_id;
255
 
256
- if (file_exists($lib_path . '.php'))
257
- {
258
  $lib_path .= '.php';
259
- }
260
- else if (file_exists($lib_path . '.inc.php'))
261
- {
262
  $lib_path .= '.inc.php';
263
- }
264
- else
265
- {
266
  $lib_path = null;
267
  }
268
  }
269
  }
270
 
271
- if ($lib_path != null && file_exists($lib_path))
272
- {
273
- $version = synved_plugout_module_version($module_id);
274
 
275
- if ($version === false)
276
- {
277
- $synved_plugout['module-list'][$module_id]['location'] = $lib_path;
278
 
279
- include_once($lib_path);
280
  }
281
 
282
  return true;
@@ -286,41 +344,41 @@ function synved_plugout_module_import($module_id)
286
  return false;
287
  }
288
 
289
- function synved_plugout_module_addon_scan_path($path, $filter = null)
290
- {
291
- if ($filter == null)
292
- {
 
 
 
 
 
 
293
  $filter = '*';
294
  }
295
 
296
- $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
297
 
298
- if (substr($path, -1) != DIRECTORY_SEPARATOR)
299
- {
300
  $path .= DIRECTORY_SEPARATOR;
301
  }
302
 
303
- if (is_dir($path))
304
- {
305
- $list = glob($path . '*', GLOB_ONLYDIR);
306
- $addon_list = array();
307
- $filter_regex = '/' . str_replace(array('*'), array('.*'), $filter) . '/';
308
-
309
- if ($list != null)
310
- {
311
- foreach ($list as $addon_dir)
312
- {
313
- $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $addon_dir);
314
- $path = rtrim($path, DIRECTORY_SEPARATOR);
315
- $base = basename($addon_dir);
316
-
317
- if (preg_match($filter_regex, $base))
318
- {
319
  $filename = $addon_dir . DIRECTORY_SEPARATOR . $base . '.php';
320
 
321
- if (file_exists($filename))
322
- {
323
- $addon_list[$base] = $filename;
324
  }
325
  }
326
  }
@@ -330,43 +388,46 @@ function synved_plugout_module_addon_scan_path($path, $filter = null)
330
  }
331
  }
332
 
333
- function synved_plugout_module_addon_list($module_id, $filter = null)
334
- {
 
 
 
 
 
 
 
335
  $addon_list = array();
336
- $path_list = synved_plugout_module_path_list_get($module_id, 'addon');
337
-
338
- if ($path_list != null)
339
- {
340
- foreach ($path_list as $path_item)
341
- {
342
- $path = $path_item['path'];
343
- $extra_list = synved_plugout_module_addon_scan_path($path, $filter);
344
-
345
- if ($extra_list != null)
346
- {
347
- $addon_list = array_merge($addon_list, $extra_list);
348
  }
349
  }
350
  }
351
 
352
- $path_list = synved_plugout_module_path_list_get($module_id, 'addon-file');
353
 
354
- if ($path_list != null)
355
- {
356
- foreach ($path_list as $path_item)
357
- {
358
- $path = $path_item['path'];
359
  $extra_list = null;
360
 
361
- if (file_exists($path) && strtolower(substr($path, -4)) == '.php')
362
- {
363
- $addon_name = isset($path_item['path']['meta']['addon-name']) ? $path_item['path']['meta']['addon-name'] : basename($path, '.php');
364
- $extra_list = array($addon_name => $path);
 
 
365
  }
366
 
367
- if ($extra_list != null)
368
- {
369
- $addon_list = array_merge($addon_list, $extra_list);
370
  }
371
  }
372
  }
1
  <?php
2
+ /**
3
+ * Core plugout file.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Plugout version.
10
+ */
11
  const SYNVED_PLUGOUT_VERSION = 100000002;
 
 
12
 
13
  $synved_plugout = array();
14
 
15
+ /**
16
+ * Plugout version.
17
+ *
18
+ * @return int
19
+ */
20
+ function synved_plugout_version() {
21
  return SYNVED_PLUGOUT_VERSION;
22
  }
23
 
24
+ /**
25
+ * Plugout path default.
26
+ *
27
+ * @param string $path_id Path ID string.
28
+ *
29
+ * @return string|null
30
+ */
31
+ function synved_plugout_path_default( $path_id ) {
32
+ switch ( $path_id ) {
33
  case 'module':
34
+ return dirname( dirname( __FILE__ ) );
 
 
35
  }
36
 
37
  return null;
38
  }
39
 
40
+ /**
41
+ * Plugout path get.
42
+ *
43
+ * @param string $path_id Path ID string.
44
+ *
45
+ * @return mixed|string|null
46
+ */
47
+ function synved_plugout_path_get( $path_id ) {
48
  global $synved_plugout;
49
 
50
+ if ( isset( $synved_plugout['path'][ $path_id ] ) ) {
51
+ return $synved_plugout['path'][ $path_id ];
 
52
  }
53
 
54
+ return synved_plugout_path_default( $path_id );
55
  }
56
 
57
+ /**
58
+ * Get module list.
59
+ *
60
+ * @return int[]|string[]
61
+ */
62
+ function synved_plugout_get_module_list() {
63
  global $synved_plugout;
64
 
65
+ return array_keys( $synved_plugout['module-list'] );
66
  }
67
 
68
+ /**
69
+ * Register module.
70
+ *
71
+ * @param string $module_id Module ID.
72
+ * @param string $module_prefix Module prefix.
73
+ * @param string $module_name Module name.
74
+ *
75
+ * @return bool
76
+ */
77
+ function synved_plugout_module_register( $module_id, $module_prefix = null, $module_name = null ) {
78
  global $synved_plugout;
79
 
80
+ if ( false === isset( $synved_plugout['module-list'][ $module_id ] ) ) {
81
+ $synved_plugout['module-list'][ $module_id ] = array(
82
+ 'id' => $module_id,
83
+ 'name' => $module_name,
84
+ 'prefix' => $module_prefix,
85
+ 'location' => null,
86
+ 'callback-list' => array(),
 
87
  );
88
 
89
  return true;
92
  return false;
93
  }
94
 
95
+ /**
96
+ * Module path add.
97
+ *
98
+ * @param string $module_id Module ID string.
99
+ * @param string $type Type string.
100
+ * @param string $path Path string.
101
+ * @param string|null $meta Meta string.
102
+ *
103
+ * @return bool
104
+ */
105
+ function synved_plugout_module_path_add( $module_id, $type, $path, $meta = null ) {
106
  global $synved_plugout;
107
 
108
+ if ( true === isset( $synved_plugout['module-list'][ $module_id ] ) ) {
109
+ $path = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $path );
 
110
 
111
+ $path_object = $meta ? $meta : array();
112
  $path_object['path'] = $path;
113
 
114
+ $synved_plugout['module-list'][ $module_id ]['path-list'][ $type ][] = $path_object;
115
 
116
  return true;
117
  }
119
  return false;
120
  }
121
 
122
+ /**
123
+ * Path get.
124
+ *
125
+ * @param string $module_id Module ID string.
126
+ * @param string $type Type string.
127
+ *
128
+ * @return mixed|null
129
+ */
130
+ function synved_plugout_module_path_get( $module_id, $type ) {
131
+ $path_list = synved_plugout_module_path_list_get( $module_id, $type, 'first' );
132
+
133
+ if ( false === empty( $path_list ) ) {
134
  return $path_list[0]['path'];
135
  }
136
 
137
  return null;
138
  }
139
 
140
+ /**
141
+ * Path list get.
142
+ *
143
+ * @param string $module_id Module ID string.
144
+ * @param string $type Type string.
145
+ * @param array|null $criteria Criteria array.
146
+ *
147
+ * @return array|null
148
+ */
149
+ function synved_plugout_module_path_list_get( $module_id, $type, $criteria = null ) {
150
  global $synved_plugout;
151
 
152
+ if ( true === isset( $synved_plugout['module-list'][ $module_id ] ) ) {
153
+ $path_list = $synved_plugout['module-list'][ $module_id ]['path-list'];
 
154
 
155
+ if ( false === empty( $path_list ) ) {
 
156
  $return_list = array();
157
 
158
+ foreach ( $path_list as $path_type => $path_type_list ) {
159
+ if ( true === empty( $type ) || $type === $path_type ) {
160
+ foreach ( $path_type_list as $path_object ) {
 
 
 
161
  $return_item = array();
162
 
163
  $return_item['type'] = $path_type;
176
  return null;
177
  }
178
 
179
+ /**
180
+ * Get module.
181
+ *
182
+ * @param string $module_id Module ID string.
183
+ *
184
+ * @return mixed|null
185
+ */
186
+ function synved_plugout_module_get( $module_id ) {
187
  global $synved_plugout;
188
 
189
+ if ( true === isset( $synved_plugout['module-list'][ $module_id ] ) ) {
190
+ return $synved_plugout['module-list'][ $module_id ];
 
191
  }
192
 
193
  return null;
194
  }
195
 
196
+ /**
197
+ * Get module version.
198
+ *
199
+ * @param string $module_id Module ID string.
200
+ *
201
+ * @return mixed
202
+ */
203
+ function synved_plugout_module_version( $module_id ) {
204
+ $module = synved_plugout_module_get( $module_id );
205
+
206
+ if ( false === empty( $module ) ) {
207
+ $module_cb = true === isset( $module['callback-list'] ) ? $module['callback-list'] : null;
208
+ $version_cb = str_replace( '-', '_', $module_id ) . '_version';
209
+
210
+ if ( true === isset( $module_cb['version'] ) ) {
211
  $version_cb = $module_cb['version'];
212
  }
213
 
214
+ if ( true === is_callable( $version_cb ) ) {
 
215
  return $version_cb();
216
  }
217
  }
219
  return false;
220
  }
221
 
222
+ /**
223
+ * Get module location.
224
+ *
225
+ * @param string $module_id Module ID string.
226
+ *
227
+ * @return mixed|null
228
+ */
229
+ function synved_plugout_module_location_get( $module_id ) {
230
+ $module = synved_plugout_module_get( $module_id );
231
+
232
+ if ( false === empty( $module ) ) {
233
+ if ( true === isset( $module['location'] ) ) {
234
  return $module['location'];
235
  }
236
  }
238
  return null;
239
  }
240
 
241
+ /**
242
+ * Get module directory.
243
+ *
244
+ * @param string $module_id Module ID string.
245
+ *
246
+ * @return string|null
247
+ */
248
+ function synved_plugout_module_directory_get( $module_id ) {
249
+ $location = synved_plugout_module_location_get( $module_id );
250
+
251
+ if ( false === empty( $location ) ) {
252
+ return dirname( $location );
253
  }
254
 
255
  return null;
256
  }
257
 
258
+ /**
259
+ * Get module URI.
260
+ *
261
+ * @param string $module_id Module ID string.
262
+ *
263
+ * @return string|null
264
+ */
265
+ function synved_plugout_module_uri_get( $module_id ) {
266
+ $directory = synved_plugout_module_directory_get( $module_id );
267
+
268
+ if ( false === empty( $directory ) ) {
269
+ $directory = strtolower( str_replace( array( '\\', '/' ), '/', $directory ) );
270
+ $content_dir = strtolower( str_replace( array( '\\', '/' ), '/', WP_CONTENT_DIR ) );
271
+ $base_len = strlen( $content_dir );
272
+
273
+ if ( substr( $directory, 0, $base_len ) === $content_dir ) {
274
+ return content_url( substr( $directory, $base_len ) );
275
  }
276
  }
277
 
278
  return null;
279
  }
280
 
281
+ /**
282
+ * Import module.
283
+ *
284
+ * @param string $module_id Module ID string.
285
+ *
286
+ * @return bool
287
+ */
288
+ function synved_plugout_module_import( $module_id ) {
289
  // This is needed because on activation the plugin's code is included *after* the theme code.
290
+ $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
291
+ $action = filter_input( INPUT_GET, 'action', FILTER_SANITIZE_STRING );
292
 
293
+ if ( false !== strpos( $request_uri, '/plugins.php?' ) && 'activate' === $action ) {
294
  return false;
295
  }
296
 
297
  global $synved_plugout;
298
 
299
+ if ( isset( $synved_plugout['module-list'][ $module_id ] ) ) {
300
+ $lib_path = synved_plugout_module_path_get( $module_id, 'library' );
301
+ $core_path = synved_plugout_module_path_get( $module_id, 'core' );
 
302
 
303
+ if ( true === empty( $lib_path ) ) {
304
+ if ( true === empty( $core_path ) ) {
305
+ $module_path = synved_plugout_path_get( 'module' );
 
 
306
 
307
+ if ( substr( $module_path, -1 ) !== DIRECTORY_SEPARATOR ) {
 
308
  $module_path .= DIRECTORY_SEPARATOR;
309
  }
310
 
311
  $core_path = $module_path . $module_id;
312
  }
313
 
314
+ if ( true === is_dir( $core_path ) ) {
315
+ if ( substr( $core_path, -1 ) !== DIRECTORY_SEPARATOR ) {
 
 
316
  $core_path .= DIRECTORY_SEPARATOR;
317
  }
318
 
319
  $lib_path = $core_path . $module_id;
320
 
321
+ if ( true === file_exists( $lib_path . '.php' ) ) {
 
322
  $lib_path .= '.php';
323
+ } elseif ( true === file_exists( $lib_path . '.inc.php' ) ) {
 
 
324
  $lib_path .= '.inc.php';
325
+ } else {
 
 
326
  $lib_path = null;
327
  }
328
  }
329
  }
330
 
331
+ if ( false === empty( $lib_path ) && true === file_exists( $lib_path ) ) {
332
+ $version = synved_plugout_module_version( $module_id );
 
333
 
334
+ if ( false === $version ) {
335
+ $synved_plugout['module-list'][ $module_id ]['location'] = $lib_path;
 
336
 
337
+ include_once $lib_path;
338
  }
339
 
340
  return true;
344
  return false;
345
  }
346
 
347
+ /**
348
+ * Scan addon path.
349
+ *
350
+ * @param string $path Path string.
351
+ * @param string|null $filter Filter string.
352
+ *
353
+ * @return array|void
354
+ */
355
+ function synved_plugout_module_addon_scan_path( $path, $filter = null ) {
356
+ if ( true === empty( $filter ) ) {
357
  $filter = '*';
358
  }
359
 
360
+ $path = str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $path );
361
 
362
+ if ( substr( $path, -1 ) !== DIRECTORY_SEPARATOR ) {
 
363
  $path .= DIRECTORY_SEPARATOR;
364
  }
365
 
366
+ if ( true === is_dir( $path ) ) {
367
+ $list = glob( $path . '*', GLOB_ONLYDIR );
368
+ $addon_list = array();
369
+ $filter_regex = '/' . str_replace( array( '*' ), array( '.*' ), $filter ) . '/';
370
+
371
+ if ( false === empty( $list ) ) {
372
+ foreach ( $list as $addon_dir ) {
373
+ $path = str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $addon_dir );
374
+ $path = rtrim( $path, DIRECTORY_SEPARATOR );
375
+ $base = basename( $addon_dir );
376
+
377
+ if ( false !== preg_match( $filter_regex, $base ) ) {
 
 
 
 
378
  $filename = $addon_dir . DIRECTORY_SEPARATOR . $base . '.php';
379
 
380
+ if ( true === file_exists( $filename ) ) {
381
+ $addon_list[ $base ] = $filename;
 
382
  }
383
  }
384
  }
388
  }
389
  }
390
 
391
+ /**
392
+ * Module addon list.
393
+ *
394
+ * @param string $module_id Module ID string.
395
+ * @param string|null $filter Filter string.
396
+ *
397
+ * @return array
398
+ */
399
+ function synved_plugout_module_addon_list( $module_id, $filter = null ) {
400
  $addon_list = array();
401
+ $path_list = synved_plugout_module_path_list_get( $module_id, 'addon' );
402
+
403
+ if ( true === empty( $path_list ) ) {
404
+ foreach ( $path_list as $path_item ) {
405
+ $path = $path_item['path'];
406
+ $extra_list = synved_plugout_module_addon_scan_path( $path, $filter );
407
+
408
+ if ( false === empty( $extra_list ) ) {
409
+ $addon_list = array_merge( $addon_list, $extra_list );
 
 
 
410
  }
411
  }
412
  }
413
 
414
+ $path_list = synved_plugout_module_path_list_get( $module_id, 'addon-file' );
415
 
416
+ if ( false === empty( $path_list ) ) {
417
+ foreach ( $path_list as $path_item ) {
418
+ $path = $path_item['path'];
 
 
419
  $extra_list = null;
420
 
421
+ if (
422
+ true === file_exists( $path )
423
+ && strtolower( substr( $path, -4 ) ) === '.php'
424
+ ) {
425
+ $addon_name = true === isset( $path_item['path']['meta']['addon-name'] ) ? $path_item['path']['meta']['addon-name'] : basename( $path, '.php' );
426
+ $extra_list = array( $addon_name => $path );
427
  }
428
 
429
+ if ( false === empty( $extra_list ) ) {
430
+ $addon_list = array_merge( $addon_list, $extra_list );
 
431
  }
432
  }
433
  }
synved-plugout/synved-plugout.php CHANGED
@@ -1,27 +1,29 @@
1
  <?php
2
- /*
3
- Module Name: Synved PlugOut
4
- Description: Allows to embed modules/plugins transparently into themes or other plugins without creating conflicts with externally installed plugins
5
- Author: Synved Ltd.
6
- Version: 1.0.2
7
- Author URI: http://www.synved.com/
8
-
9
- LEGAL STATEMENTS
10
-
11
- COPYRIGHT
12
- All documents, text, questions, references, images, audio, programs, source code or other materials whatsoever contained in, or supplied are protected by copyright of the respective copyright holders.
13
-
14
- Except as explicitly allowed under each specific copyright or license, these materials may not be reproduced in whole or in part, in any form or by any means, including photocopy, electronic storage and retrieval, or translation into any other language without the express written consent of the copyright holder.
15
-
16
- NO WARRANTY
17
- All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
18
-
19
- NO LIABILITY
20
- In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
21
- */
 
 
22
 
23
  define( 'SYNVED_PLUGOUT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
24
 
25
- if (!function_exists('synved_plugout_version')) {
26
  include_once SYNVED_PLUGOUT_PLUGIN_PATH . 'synved-plugout-core.php';
27
  }
1
  <?php
2
+ /**
3
+ * Module Name: Synved PlugOut
4
+ * Description: Allows to embed modules/plugins transparently into themes or other plugins without creating conflicts with externally installed plugins
5
+ * Author: Synved Ltd.
6
+ * Version: 1.0.2
7
+ * Author URI: http://www.synved.com/
8
+ *
9
+ * LEGAL STATEMENTS
10
+ *
11
+ * COPYRIGHT
12
+ * All documents, text, questions, references, images, audio, programs, source code or other materials whatsoever contained in, or supplied are protected by copyright of the respective copyright holders.
13
+ *
14
+ * Except as explicitly allowed under each specific copyright or license, these materials may not be reproduced in whole or in part, in any form or by any means, including photocopy, electronic storage and retrieval, or translation into any other language without the express written consent of the copyright holder.
15
+ *
16
+ * NO WARRANTY
17
+ * All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
18
+ *
19
+ * NO LIABILITY
20
+ * In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
21
+ *
22
+ * @package SocialMediaFeather
23
+ */
24
 
25
  define( 'SYNVED_PLUGOUT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
26
 
27
+ if ( false === function_exists( 'synved_plugout_version' ) ) {
28
  include_once SYNVED_PLUGOUT_PLUGIN_PATH . 'synved-plugout-core.php';
29
  }
synved-social/addons/extra-icons/extra-icons.php CHANGED
@@ -1,84 +1,88 @@
1
  <?php
 
 
 
 
 
2
 
3
- if (!function_exists('synved_social_addon_extra_icons_get')) {
4
- function synved_social_addon_extra_icons_version()
5
- {
6
- return 100020002;
7
- }
8
-
9
- function synved_social_addon_extra_icons_get()
10
- {
11
- $addon_dir = '/addons/' . basename(dirname(__FILE__));
12
- $path = synved_social_path($addon_dir);
13
- $uri = synved_social_path_uri($addon_dir);
14
 
15
- $icons = [
16
- 'clearslate' => [
17
- 'label' => __('Clear Slate', 'social-media-feather'),
18
  'image' => $uri . '/image/social/clearslate/preview.png',
19
  'folder' => $addon_dir . '/image/social/clearslate/',
20
  'path' => $path . '/image/social/clearslate/',
21
  'uri' => $uri . '/image/social/clearslate/',
22
  'extra' => true,
23
- ],
24
- 'darkslate' => [
25
- 'label' => __('Dark Slate', 'social-media-feather'),
26
  'image' => $uri . '/image/social/darkslate/preview.png',
27
  'folder' => $addon_dir . '/image/social/darkslate/',
28
  'path' => $path . '/image/social/darkslate/',
29
  'uri' => $uri . '/image/social/darkslate/',
30
  'extra' => true,
31
- ],
32
- 'circle' => [
33
- 'label' => __('Circle', 'social-media-feather'),
34
  'image' => $uri . '/image/social/circle/preview.png',
35
  'folder' => $addon_dir . '/image/social/circle/',
36
  'path' => $path . '/image/social/circle/',
37
  'uri' => $uri . '/image/social/circle/',
38
  'extra' => true,
39
- ],
40
- 'wheel' => [
41
- 'label' => __('Wheel', 'social-media-feather'),
42
  'image' => $uri . '/image/social/wheel/preview.png',
43
  'folder' => $addon_dir . '/image/social/wheel/',
44
  'path' => $path . '/image/social/wheel/',
45
  'uri' => $uri . '/image/social/wheel/',
46
  'extra' => true,
47
- ],
48
- 'flag' => [
49
- 'label' => __('Flag', 'social-media-feather'),
50
  'image' => $uri . '/image/social/flag/preview.png',
51
  'folder' => $addon_dir . '/image/social/flag/',
52
  'path' => $path . '/image/social/flag/',
53
  'uri' => $uri . '/image/social/flag/',
54
  'extra' => true,
55
- ],
56
- 'medal' => [
57
- 'label' => __('Medal', 'social-media-feather'),
58
  'image' => $uri . '/image/social/medal/preview.png',
59
  'folder' => $addon_dir . '/image/social/medal/',
60
  'path' => $path . '/image/social/medal/',
61
  'uri' => $uri . '/image/social/medal/',
62
  'extra' => true,
63
- ],
64
- 'shed' => [
65
- 'label' => __('Shed', 'social-media-feather'),
66
  'image' => $uri . '/image/social/shed/preview.png',
67
  'folder' => $addon_dir . '/image/social/shed/',
68
  'path' => $path . '/image/social/shed/',
69
  'uri' => $uri . '/image/social/shed/',
70
  'extra' => true,
71
- ],
72
- 'balloon' => [
73
- 'label' => __('Balloon', 'social-media-feather'),
74
  'image' => $uri . '/image/social/balloon/preview.png',
75
  'folder' => $addon_dir . '/image/social/balloon/',
76
  'path' => $path . '/image/social/balloon/',
77
  'uri' => $uri . '/image/social/balloon/',
78
  'extra' => true,
79
- ],
80
- ];
81
 
82
- return apply_filters('synved_social_addon_extra_icons_get', $icons);
83
  }
84
  }
1
  <?php
2
+ /**
3
+ * Extra icons loader.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ if ( false === function_exists( 'synved_social_addon_extra_icons_get' ) ) {
9
+ /**
10
+ * Addon extra icons getter.
11
+ *
12
+ * @return array|mixed
13
+ */
14
+ function synved_social_addon_extra_icons_get() {
15
+ $addon_dir = '/addons/' . basename( dirname( __FILE__ ) );
16
+ $path = synved_social_path( $addon_dir );
17
+ $uri = synved_social_path_uri( $addon_dir );
 
18
 
19
+ $icons = array(
20
+ 'clearslate' => array(
21
+ 'label' => __( 'Clear Slate', 'social-media-feather' ),
22
  'image' => $uri . '/image/social/clearslate/preview.png',
23
  'folder' => $addon_dir . '/image/social/clearslate/',
24
  'path' => $path . '/image/social/clearslate/',
25
  'uri' => $uri . '/image/social/clearslate/',
26
  'extra' => true,
27
+ ),
28
+ 'darkslate' => array(
29
+ 'label' => __( 'Dark Slate', 'social-media-feather' ),
30
  'image' => $uri . '/image/social/darkslate/preview.png',
31
  'folder' => $addon_dir . '/image/social/darkslate/',
32
  'path' => $path . '/image/social/darkslate/',
33
  'uri' => $uri . '/image/social/darkslate/',
34
  'extra' => true,
35
+ ),
36
+ 'circle' => array(
37
+ 'label' => __( 'Circle', 'social-media-feather' ),
38
  'image' => $uri . '/image/social/circle/preview.png',
39
  'folder' => $addon_dir . '/image/social/circle/',
40
  'path' => $path . '/image/social/circle/',
41
  'uri' => $uri . '/image/social/circle/',
42
  'extra' => true,
43
+ ),
44
+ 'wheel' => array(
45
+ 'label' => __( 'Wheel', 'social-media-feather' ),
46
  'image' => $uri . '/image/social/wheel/preview.png',
47
  'folder' => $addon_dir . '/image/social/wheel/',
48
  'path' => $path . '/image/social/wheel/',
49
  'uri' => $uri . '/image/social/wheel/',
50
  'extra' => true,
51
+ ),
52
+ 'flag' => array(
53
+ 'label' => __( 'Flag', 'social-media-feather' ),
54
  'image' => $uri . '/image/social/flag/preview.png',
55
  'folder' => $addon_dir . '/image/social/flag/',
56
  'path' => $path . '/image/social/flag/',
57
  'uri' => $uri . '/image/social/flag/',
58
  'extra' => true,
59
+ ),
60
+ 'medal' => array(
61
+ 'label' => __( 'Medal', 'social-media-feather' ),
62
  'image' => $uri . '/image/social/medal/preview.png',
63
  'folder' => $addon_dir . '/image/social/medal/',
64
  'path' => $path . '/image/social/medal/',
65
  'uri' => $uri . '/image/social/medal/',
66
  'extra' => true,
67
+ ),
68
+ 'shed' => array(
69
+ 'label' => __( 'Shed', 'social-media-feather' ),
70
  'image' => $uri . '/image/social/shed/preview.png',
71
  'folder' => $addon_dir . '/image/social/shed/',
72
  'path' => $path . '/image/social/shed/',
73
  'uri' => $uri . '/image/social/shed/',
74
  'extra' => true,
75
+ ),
76
+ 'balloon' => array(
77
+ 'label' => __( 'Balloon', 'social-media-feather' ),
78
  'image' => $uri . '/image/social/balloon/preview.png',
79
  'folder' => $addon_dir . '/image/social/balloon/',
80
  'path' => $path . '/image/social/balloon/',
81
  'uri' => $uri . '/image/social/balloon/',
82
  'extra' => true,
83
+ ),
84
+ );
85
 
86
+ return apply_filters( 'synved_social_addon_extra_icons_get', $icons );
87
  }
88
  }
synved-social/inc/SynvedSocialFollowWidget.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Social Follow Widget.
5
- */
6
- class SynvedSocialFollowWidget extends SynvedSocialWidget {
7
- function __construct() {
8
- parent::__construct( 'synved_social_follow', __( 'Social Media Feather: Follow Us', 'social-media-feather' ) );
9
- }
10
-
11
- /**
12
- * Override defaults.
13
- *
14
- * @return string[]
15
- */
16
- function get_defaults() {
17
- $defaults = parent::get_defaults();
18
-
19
- return array_merge( $defaults, [ 'title' => __( 'Follow Us', 'social-media-feather' ) ] );
20
- }
21
-
22
- /**
23
- * Render social markup.
24
- *
25
- * NOTE: Escaped via wp_kses_post().
26
- *
27
- * @param $params
28
- *
29
- * @return void
30
- */
31
- function render_social_markup( $params = null ) {
32
- echo synved_social_follow_markup( null, null, $params ); // Escaped using wp_kses_post.
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-social/inc/SynvedSocialShareWidget.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Social Share Widget.
5
- */
6
- class SynvedSocialShareWidget extends SynvedSocialWidget {
7
- function __construct() {
8
- parent::__construct( 'synved_social_share', __( 'Social Media Feather: Sharing', 'social-media-feather' ) );
9
- }
10
-
11
- /**
12
- * Override defaults.
13
- *
14
- * @return string[]
15
- */
16
- function get_defaults() {
17
- $defaults = parent::get_defaults();
18
-
19
- return array_merge( $defaults, [ 'title' => __( 'Sharing', 'social-media-feather' ) ] );
20
- }
21
-
22
- /**
23
- * Render social markup.
24
- *
25
- * NOTE: Escaped via wp_kses_post().
26
- *
27
- * @param $params
28
- *
29
- * @return void
30
- */
31
- function render_social_markup( $params = null ) {
32
- echo synved_social_share_markup( null, null, $params ); // Escaped using wp_kses_post.
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-social/inc/SynvedSocialWidget.php DELETED
@@ -1,144 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Social Widget.
5
- */
6
- class SynvedSocialWidget extends WP_Widget {
7
- function __construct( $id_base = false, $name = null, $widget_options = [], $control_options = [] ) {
8
- if ( $name == null ) {
9
- $name = 'Social Media Feather';
10
- }
11
-
12
- parent::__construct( $id_base, $name, $widget_options, $control_options );
13
- }
14
-
15
- function widget( $args, $instance ) {
16
- extract( $args ); /* before/after widget, before/after title (defined by themes). */
17
- extract( $instance );
18
-
19
- ob_start();
20
- echo $before_widget;
21
-
22
- if ( $title != null ) {
23
- echo $before_title . $title . $after_title;
24
- }
25
-
26
- echo '<div>';
27
-
28
- $params = [];
29
- $params['alignment'] = 'none';
30
-
31
- if ( $icon_skin != 'default' ) {
32
- $params['skin'] = $icon_skin;
33
- }
34
-
35
- if ( $icon_size != 'default' ) {
36
- $params['size'] = $icon_size;
37
- }
38
-
39
- if ( $icon_spacing !== null && $icon_spacing !== '' ) {
40
- $params['spacing'] = $icon_spacing;
41
- }
42
-
43
- $this->render_social_markup( $params );
44
-
45
- echo '</div>';
46
- echo $after_widget;
47
-
48
- $html = ob_get_clean();
49
-
50
- echo wp_kses_post( $html );
51
- }
52
-
53
- function get_defaults() {
54
- return [ 'icon_skin' => 'default', 'icon_size' => 'default', 'icon_spacing' => '' ];
55
- }
56
-
57
- function render_social_markup( $params = null ) {
58
- }
59
-
60
- function update( $new_instance, $old_instance ) {
61
- $instance = $old_instance;
62
- $instance['title'] = strip_tags( $new_instance['title'] );
63
- $instance['icon_skin'] = strip_tags( $new_instance['icon_skin'] );
64
- $instance['icon_size'] = strip_tags( $new_instance['icon_size'] );
65
- $instance['icon_spacing'] = strip_tags( $new_instance['icon_spacing'] );
66
-
67
- return $instance;
68
- }
69
-
70
- /**
71
- * Form render.
72
- *
73
- * NOTE: Escaped via wp_kses_post().
74
- *
75
- * @param $instance
76
- *
77
- * @return string|void
78
- */
79
- function form( $instance ) {
80
- $instance = wp_parse_args( (array) $instance, $this->get_defaults() );
81
-
82
- ob_start();
83
- ?>
84
- <p>
85
- <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
86
- <?php echo esc_html__( 'Title', 'social-media-feather' ) ?>:
87
- </label>
88
- <input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
89
- name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>"
90
- value="<?php echo esc_attr( $instance['title'] ); ?>"/>
91
- </p>
92
- <p>
93
- <label for="<?php echo esc_attr( $this->get_field_id( 'icon_skin' ) ); ?>">
94
- <?php echo esc_html__( 'Icon Skin', 'social-media-feather' ); ?>:
95
- </label>
96
- <?php
97
- $params = [
98
- 'tip' => '',
99
- 'output_name' => $this->get_field_name( 'icon_skin' ),
100
- 'value' => $instance['icon_skin'],
101
- 'set_before' => [ [ 'default' => __( 'Use Default' ) ] ],
102
- ];
103
-
104
- $item = synved_option_item( 'synved_social', 'icon_skin' );
105
-
106
- if ( false === empty( $item ) ) {
107
- if ( true === is_object( $item ) ) {
108
- $item = clone $item;
109
- }
110
-
111
- unset( $item['render'] );
112
-
113
- synved_option_render_item( 'synved_social', 'icon_skin', $item, true, $params, 'widget' );
114
- }
115
- ?>
116
- <br/>
117
- <label for="<?php echo esc_attr( $this->get_field_id( 'icon_size' ) ); ?>">
118
- <?php echo esc_html__( 'Icon Size', 'social-media-feather' ); ?>:
119
- </label>
120
- <?php
121
- $params = [
122
- 'tip' => '',
123
- 'output_name' => $this->get_field_name( 'icon_size' ),
124
- 'value' => $instance['icon_size'],
125
- 'set_before' => [ [ 'default' => __( 'Use Default' ) ] ],
126
- ];
127
-
128
- synved_option_render_item( 'synved_social', 'icon_size', null, true, $params, 'widget' );
129
- ?>
130
- <br/>
131
- <label for="<?php echo esc_attr( $this->get_field_id( 'icon_spacing' ) ); ?>">
132
- <?php echo esc_html__( 'Icon Spacing', 'social-media-feather' ); ?>:
133
- </label>
134
- <input type="text" size="3" class="" id="<?php echo esc_attr( $this->get_field_id( 'icon_spacing' ) ); ?>"
135
- name="<?php echo esc_attr( $this->get_field_name( 'icon_spacing' ) ); ?>"
136
- value="<?php echo esc_attr( $instance['icon_spacing'] ); ?>"/>
137
- </p>
138
- <?php
139
-
140
- $form = ob_get_clean();
141
-
142
- echo wp_kses( $form, synved_get_allowed_html_array() );
143
- }
144
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
synved-social/inc/class-synvedsocialfollowwidget.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Follow Widget.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Social Follow Widget Class.
10
+ */
11
+ class SynvedSocialFollowWidget extends SynvedSocialWidget {
12
+ /**
13
+ * Constructor.
14
+ */
15
+ public function __construct() {
16
+ parent::__construct(
17
+ 'synved_social_follow',
18
+ __( 'Social Media Feather: Follow Us', 'social-media-feather' )
19
+ );
20
+ }
21
+
22
+ /**
23
+ * Override defaults.
24
+ *
25
+ * @return string[]
26
+ */
27
+ public function get_defaults() {
28
+ $defaults = parent::get_defaults();
29
+
30
+ return array_merge( $defaults, array( 'title' => __( 'Follow Us', 'social-media-feather' ) ) );
31
+ }
32
+
33
+ /**
34
+ * Render social markup.
35
+ *
36
+ * NOTE: Escaped via wp_kses_post().
37
+ *
38
+ * @param array $params Parameter array.
39
+ *
40
+ * @return void
41
+ */
42
+ public function render_social_markup( $params = null ) {
43
+ // Escaped using wp_kses_post.
44
+ echo synved_social_follow_markup( null, null, $params ); // phpcs:ignore
45
+ }
46
+ }
synved-social/inc/class-synvedsocialsharewidget.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Share Widget.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Social Share Widget Class.
10
+ */
11
+ class SynvedSocialShareWidget extends SynvedSocialWidget {
12
+
13
+ /**
14
+ * Constructor.
15
+ */
16
+ public function __construct() {
17
+ parent::__construct( 'synved_social_share', __( 'Social Media Feather: Sharing', 'social-media-feather' ) );
18
+ }
19
+
20
+ /**
21
+ * Override defaults.
22
+ *
23
+ * @return string[]
24
+ */
25
+ public function get_defaults() {
26
+ $defaults = parent::get_defaults();
27
+
28
+ return array_merge( $defaults, array( 'title' => __( 'Sharing', 'social-media-feather' ) ) );
29
+ }
30
+
31
+ /**
32
+ * Render social markup.
33
+ *
34
+ * NOTE: Escaped via wp_kses_post().
35
+ *
36
+ * @param array $params Parmeter array.
37
+ *
38
+ * @return void
39
+ */
40
+ public function render_social_markup( $params = null ) {
41
+ // Escaped using wp_kses_post.
42
+ echo synved_social_share_markup( null, null, $params ); // phpcs:ignore
43
+ }
44
+ }
synved-social/inc/class-synvedsocialwidget.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Social Widget.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ /**
9
+ * Social Widget Class.
10
+ */
11
+ class SynvedSocialWidget extends WP_Widget {
12
+ /**
13
+ * Constructor.
14
+ *
15
+ * @param string $id_base Optional. Base ID for the widget, lowercase and unique. If left empty,
16
+ * a portion of the widget's PHP class name will be used. Has to be unique.
17
+ * @param string $name Name for the widget displayed on the configuration page.
18
+ * @param array $widget_options Optional. Widget options. See wp_register_sidebar_widget() for
19
+ * information on accepted arguments. Default empty array.
20
+ * @param array $control_options Optional. Widget control options. See wp_register_widget_control() for
21
+ * information on accepted arguments. Default empty array.
22
+ */
23
+ public function __construct(
24
+ $id_base = false,
25
+ $name = null,
26
+ $widget_options = array(),
27
+ $control_options = array()
28
+ ) {
29
+ if ( true === empty( $name ) ) {
30
+ $name = 'Social Media Feather';
31
+ }
32
+
33
+ parent::__construct( $id_base, $name, $widget_options, $control_options );
34
+ }
35
+
36
+ /**
37
+ * Echoes the widget content.
38
+ *
39
+ * Subclasses should override this function to generate their widget code.
40
+ *
41
+ * @param array $args Display arguments including 'before_title', 'after_title',
42
+ * 'before_widget', and 'after_widget'.
43
+ * @param array $instance The settings for the particular instance of the widget.
44
+ */
45
+ public function widget( $args, $instance ) {
46
+ // Intentionally keeping extract() for now.
47
+ extract( $args ); // phpcs:ignore
48
+ extract( $instance ); // phpcs:ignore
49
+
50
+ ob_start();
51
+
52
+ // Escaped in wp_kses_post below.
53
+ echo $before_widget; // phpcs:ignore
54
+
55
+ if ( false === empty( $title ) ) {
56
+
57
+ // Escaped in wp_kses_post below.
58
+ echo $before_title . $title . $after_title; // phpcs:ignore
59
+ }
60
+
61
+ echo '<div>';
62
+
63
+ $params = array();
64
+ $params['alignment'] = 'none';
65
+
66
+ if ( 'default' !== $icon_skin ) {
67
+ $params['skin'] = $icon_skin;
68
+ }
69
+
70
+ if ( 'default' !== $icon_size ) {
71
+ $params['size'] = $icon_size;
72
+ }
73
+
74
+ if ( false === empty( $icon_spacing ) ) {
75
+ $params['spacing'] = $icon_spacing;
76
+ }
77
+
78
+ $this->render_social_markup( $params );
79
+
80
+ echo '</div>';
81
+
82
+ // Escaped in wp_kses_post below.
83
+ echo $after_widget; // phpcs:ignore
84
+
85
+ $html = ob_get_clean();
86
+
87
+ echo wp_kses_post( $html );
88
+ }
89
+
90
+ /**
91
+ * Get default values.
92
+ *
93
+ * @return string[] Values array.
94
+ */
95
+ public function get_defaults() {
96
+ return array(
97
+ 'icon_skin' => 'default',
98
+ 'icon_size' => 'default',
99
+ 'icon_spacing' => '',
100
+ );
101
+ }
102
+
103
+ /**
104
+ * Render social markup.
105
+ *
106
+ * @param array $params Parameters array.
107
+ *
108
+ * @return void
109
+ */
110
+ public function render_social_markup( $params = null ) {
111
+ // Do nothing.
112
+ }
113
+
114
+ /**
115
+ * Update.
116
+ *
117
+ * @param array $new_instance New settings for this instance as input by the user via
118
+ * WP_Widget::form().
119
+ * @param array $old_instance Old settings for this instance.
120
+ *
121
+ * @return array Settings to save or bool false to cancel saving.
122
+ */
123
+ public function update( $new_instance, $old_instance ) {
124
+ $instance = $old_instance;
125
+ $instance['title'] = wp_strip_all_tags( $new_instance['title'] );
126
+ $instance['icon_skin'] = wp_strip_all_tags( $new_instance['icon_skin'] );
127
+ $instance['icon_size'] = wp_strip_all_tags( $new_instance['icon_size'] );
128
+ $instance['icon_spacing'] = wp_strip_all_tags( $new_instance['icon_spacing'] );
129
+
130
+ return $instance;
131
+ }
132
+
133
+ /**
134
+ * Form render.
135
+ *
136
+ * NOTE: Escaped via wp_kses_post().
137
+ *
138
+ * @param array $instance Current settings.
139
+ *
140
+ * @return void
141
+ */
142
+ public function form( $instance ) {
143
+ $instance = wp_parse_args( (array) $instance, $this->get_defaults() );
144
+
145
+ ob_start();
146
+ ?>
147
+ <p>
148
+ <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
149
+ <?php esc_html_e( 'Title', 'social-media-feather' ); ?>:
150
+ </label>
151
+ <input type="text" class="widefat"
152
+ id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
153
+ name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>"
154
+ value="<?php echo esc_attr( $instance['title'] ); ?>"
155
+ />
156
+ </p>
157
+ <p>
158
+ <label for="<?php echo esc_attr( $this->get_field_id( 'icon_skin' ) ); ?>">
159
+ <?php esc_html_e( 'Icon Skin', 'social-media-feather' ); ?>:
160
+ </label>
161
+ <?php
162
+ $params = array(
163
+ 'tip' => '',
164
+ 'output_name' => $this->get_field_name( 'icon_skin' ),
165
+ 'value' => $instance['icon_skin'],
166
+ 'set_before' => array( array( 'default' => __( 'Use Default' ) ) ),
167
+ );
168
+
169
+ $item = synved_option_item( 'synved_social', 'icon_skin' );
170
+
171
+ if ( false === empty( $item ) ) {
172
+ if ( true === is_object( $item ) ) {
173
+ $item = clone $item;
174
+ }
175
+
176
+ unset( $item['render'] );
177
+
178
+ synved_option_render_item( 'synved_social', 'icon_skin', $item, true, $params, 'widget' );
179
+ }
180
+ ?>
181
+ <br/>
182
+ <label for="<?php echo esc_attr( $this->get_field_id( 'icon_size' ) ); ?>">
183
+ <?php esc_html_e( 'Icon Size', 'social-media-feather' ); ?>:
184
+ </label>
185
+ <?php
186
+ $params = array(
187
+ 'tip' => '',
188
+ 'output_name' => $this->get_field_name( 'icon_size' ),
189
+ 'value' => $instance['icon_size'],
190
+ 'set_before' => array( array( 'default' => __( 'Use Default' ) ) ),
191
+ );
192
+
193
+ synved_option_render_item( 'synved_social', 'icon_size', null, true, $params, 'widget' );
194
+ ?>
195
+ <br/>
196
+ <label for="<?php echo esc_attr( $this->get_field_id( 'icon_spacing' ) ); ?>">
197
+ <?php esc_html_e( 'Icon Spacing', 'social-media-feather' ); ?>:
198
+ </label>
199
+ <input type="text" size="3" class="" id="<?php echo esc_attr( $this->get_field_id( 'icon_spacing' ) ); ?>"
200
+ name="<?php echo esc_attr( $this->get_field_name( 'icon_spacing' ) ); ?>"
201
+ value="<?php echo esc_attr( $instance['icon_spacing'] ); ?>"/>
202
+ </p>
203
+ <?php
204
+
205
+ $form = ob_get_clean();
206
+
207
+ echo wp_kses( $form, synved_get_allowed_html_array() );
208
+ }
209
+ }
synved-social/synved-social-setup.php CHANGED
@@ -1,13 +1,23 @@
1
  <?php
 
 
 
 
 
2
 
 
 
 
 
 
3
  function synved_social_provider_settings() {
4
  $share_providers = synved_social_service_provider_list( 'share', true );
5
  $follow_providers = synved_social_service_provider_list( 'follow', true );
6
  $provider_list = array_merge( $share_providers, $follow_providers );
7
- $providers_settings = [];
8
 
9
  foreach ( $provider_list as $provider_name => $provider_item ) {
10
- $provider_label = ucwords( str_replace( [ '-', '_' ], ' ', $provider_name ) );
11
  $display_set = 'none=None';
12
  $display_default = 'none';
13
 
@@ -39,58 +49,111 @@ function synved_social_provider_settings() {
39
  }
40
  }
41
 
42
- $providers_settings = array_merge( $providers_settings,
43
- [
44
- $provider_name . '_display' => [
 
45
  'default' => $display_default,
46
  'style' => 'group',
47
  'set' => $display_set,
48
- 'label' => __( $provider_label . ' Service', 'social-media-feather' ),
49
- 'tip' => __( 'Decides for what types of services ' . $provider_label . ' will be used by default',
50
- 'social-media-feather' ),
51
- ],
52
- ]
 
 
 
 
 
 
 
 
 
 
53
  );
54
 
55
  if ( true === isset( $share_providers[ $provider_name ] ) ) {
56
  $share_item = $share_providers[ $provider_name ];
57
 
58
- $providers_settings = array_merge( $providers_settings,
59
- [
60
- $provider_name . '_share_link' => [
61
- 'label' => __( $provider_label . ' Share Link', 'social-media-feather' ),
62
- 'tip' => __( 'The link used by default for sharing content on ' . $provider_label . '. <b>Note: this generally doesn\'t need to be changed, only change it if you know what you\'re doing.</b>',
63
- 'social-media-feather' ),
 
 
 
 
 
 
 
 
 
 
 
64
  'hint' => $share_item['link'],
65
- ],
66
- $provider_name . '_share_title' => [
67
- 'label' => __( $provider_label . ' Share Title', 'social-media-feather' ),
68
- 'tip' => __( 'The title used by default for the ' . $provider_label . ' share button (a standard one will be used if left empty)',
69
- 'social-media-feather' ),
 
 
 
 
 
 
 
 
 
 
70
  'hint' => $share_item['title'],
71
- ],
72
- ]
73
  );
74
  }
75
 
76
  if ( true === isset( $follow_providers[ $provider_name ] ) ) {
77
  $follow_item = $follow_providers[ $provider_name ];
78
 
79
- $providers_settings = array_merge( $providers_settings,
80
- [
81
- $provider_name . '_follow_link' => [
82
- 'label' => __( $provider_label . ' Follow Link', 'social-media-feather' ),
83
- 'tip' => __( 'The link used by default for following you on ' . $provider_label . '. Change this to point to your own social profile page on ' . $provider_label . '.',
84
- 'social-media-feather' ),
 
 
 
 
 
 
 
 
 
 
 
85
  'hint' => $follow_item['link'],
86
- ],
87
- $provider_name . '_follow_title' => [
88
- 'label' => __( $provider_label . ' Follow Title', 'social-media-feather' ),
89
- 'tip' => __( 'The title used by default for the ' . $provider_label . ' follow button (a standard one will be used if left empty)',
90
- 'social-media-feather' ),
 
 
 
 
 
 
 
 
 
 
91
  'hint' => $follow_item['title'],
92
- ],
93
- ]
94
  );
95
  }
96
  }
@@ -100,282 +163,346 @@ function synved_social_provider_settings() {
100
 
101
  $terms_accepted = synved_option_get( 'synved_social', 'accepted_sharethis_terms' );
102
 
103
- $synved_social_options = [
104
- 'settings' => [
105
  'label' => 'Social Media',
106
  'title' => 'Social Media Feather',
107
  'tip' => synved_option_callback( 'synved_social_page_settings_tip' ),
108
  'link-target' => plugin_basename( synved_plugout_module_path_get( 'synved-social', 'provider' ) ),
109
  'render-fragment' => 'synved_social_page_render_fragment',
110
- 'sections' => [
111
- 'section_general' => [
112
  'label' => __( 'General Settings', 'social-media-feather' ),
113
  'tip' => __( 'Settings affecting the general behaviour of the plugin', 'social-media-feather' ),
114
- 'settings' => [
115
- 'use_shortlinks' => [
116
  'default' => false,
117
  'label' => __( 'Use Shortlinks', 'social-media-feather' ),
118
- 'tip' => __( 'Allows for shortened URLs to be used when sharing content if a shortening plugin is installed',
119
- 'social-media-feather' ),
120
- ],
121
- 'share_full_url' => [
 
 
122
  'default' => false,
123
  'label' => __( 'Share Full URL', 'social-media-feather' ),
124
- 'tip' => __( 'Determines whether to always share the full URL or just the post permalink. You can override this for individual posts by setting the "synved_social_share_full_url" custom field to either "yes" or "no", case sensitive',
125
- 'social-media-feather' ),
126
- ],
127
- 'layout_rtl' => [
 
 
128
  'default' => false,
129
  'label' => __( 'Right To Left Layout', 'social-media-feather' ),
130
- 'tip' => __( 'Check this option if you have a right-to-left site layout and icons show spacing issues',
131
- 'social-media-feather' ),
132
- ],
133
- 'shortcode_widgets' => [
 
 
134
  'default' => true,
135
  'label' => __( 'Shortcodes In Widgets', 'social-media-feather' ),
136
  'tip' => __( 'Allow shortcodes in Text widgets', 'social-media-feather' ),
137
- ],
138
- 'show_credit' => [
139
  'default' => false,
140
  'label' => __( 'Show Credit', 'social-media-feather' ),
141
- 'tip' => __( 'Display a small icon with a link to the Social Media Feather page',
142
- 'social-media-feather' ),
143
- ],
144
- 'share_message_default' => [
 
 
145
  'default' => __( 'Hey check this out', 'social-media-feather' ),
146
  'label' => __( 'Default Message', 'social-media-feather' ),
147
- 'tip' => __( 'Specify the default message to use when sharing content, this is what gets replaced into the %%message%% variable',
148
- 'social-media-feather' ),
149
- ],
150
- 'hide_sharethis_terms' => [
151
- 'default' => false,
152
- 'label' => __( 'Hide Extra Features Prompt', 'social-media-feather' ),
153
- 'tip' => __( 'Don\'t prompt for extra features.', 'social-media-feather' ),
154
- 'hidden' => true,
155
- ],
156
- 'fb_app_id' => [
157
  'default' => '',
158
  'label' => __( 'Facebook App ID', 'social-media-feather' ),
159
- ],
160
- 'accepted_sharethis_terms' => [
161
  'type' => 'custom',
162
  'label' => __( 'Terms of Service', 'social-media-feather' ),
163
- 'tip' => __( 'Accept or decline <a target="_blank" href="https://www.sharethis.com/terms/">ShareThis Terms of Service</a> and <a target="_blank" href="https://www.sharethis.com/privacy/">Privacy Notice</a>',
164
- 'social-media-feather' ),
 
 
165
  'render' => 'synved_social_accept_terms_switch',
166
- ],
167
- ],
168
- ],
169
 
170
- 'section_automatic_display' => [
171
  'label' => __( 'Automatic Display', 'social-media-feather' ),
172
- 'tip' => __( 'Settings affecting automating appending of social buttons to post contents',
173
- 'social-media-feather' ),
174
- 'settings' => [
175
- 'automatic_share' => [
 
 
176
  'default' => false,
177
  'label' => __( 'Display Sharing Buttons', 'social-media-feather' ),
178
- 'tip' => __( 'Tries to automatically append sharing buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_share to "yes", case sensitive)',
179
- 'social-media-feather' ),
180
- ],
181
- 'automatic_share_position' => [
 
 
182
  'default' => 'after_post',
183
  'set' => 'after_post=After Post,before_post=Before Post,after_before_post=After and Before Post',
184
  'label' => __( 'Share Buttons Position', 'social-media-feather' ),
185
- 'tip' => __( 'Select where the sharing buttons should be placed. Note: placing buttons Before Post might not work in all themes.',
186
- 'social-media-feather' ),
187
- ],
188
- 'automatic_share_single' => [
 
 
189
  'default' => false,
190
  'label' => __( 'Sharing Single Posts', 'social-media-feather' ),
191
- 'tip' => __( 'Sharing buttons are only displayed on single posts/pages and not on archive pages like blog/category/tag/author pages',
192
- 'social-media-feather' ),
193
- ],
194
- 'automatic_share_post_types' => [
 
 
195
  'type' => 'custom',
196
  'default' => 'post',
197
- 'set' => synved_option_callback( 'synved_social_automatic_append_post_types_set',
198
- [ 'post', 'page' ] ),
 
 
199
  'label' => __( 'Share Post Types', 'social-media-feather' ),
200
- 'tip' => __( 'Post types for which automatic appending for share buttons should be attempted (CTRL + click to select multiple ones)',
201
- 'social-media-feather' ),
 
 
202
  'render' => 'synved_social_automatic_append_post_types_render',
203
- ],
204
- 'automatic_share_prefix' => [
205
  'default' => '',
206
  'label' => __( 'Share Prefix Markup', 'social-media-feather' ),
207
- 'tip' => __( 'When automatically appending, place this markup before the share buttons markup',
208
- 'social-media-feather' ),
209
- ],
210
- 'automatic_share_postfix' => [
 
 
211
  'default' => '',
212
  'label' => __( 'Share Postfix Markup', 'social-media-feather' ),
213
- 'tip' => __( 'When automatically appending, place this markup after all of the share buttons markup',
214
- 'social-media-feather' ),
215
- ],
216
- 'automatic_follow' => [
217
- 'default' => false,
 
 
218
  'label' => __( 'Display Follow Buttons', 'social-media-feather' ),
219
- 'tip' => __( 'Tries to automatically append follow buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_follow to "yes", case sensitive)',
220
- 'social-media-feather' ),
221
- ],
222
- 'automatic_follow_position' => [
 
 
223
  'default' => 'after_post',
224
  'set' => 'after_post=After Post,before_post=Before Post,after_before_post=After and Before Post',
225
  'label' => __( 'Follow Buttons Position', 'social-media-feather' ),
226
- 'tip' => __( 'Select where the follow buttons should be placed. Note: placing buttons Before Post might not work in all themes.',
227
- 'social-media-feather' ),
228
- ],
229
- 'automatic_follow_single' => [
 
 
230
  'default' => false,
231
  'label' => __( 'Follow Single Posts', 'social-media-feather' ),
232
- 'tip' => __( 'Follow buttons are only displayed on single posts/pages and not on archive pages like blog/category/tag/author pages',
233
- 'social-media-feather' ),
234
- ],
235
- 'automatic_follow_post_types' => [
 
 
236
  'type' => 'custom',
237
  'default' => 'post',
238
- 'set' => synved_option_callback( 'synved_social_automatic_append_post_types_set',
239
- [ 'post', 'page' ] ),
 
 
240
  'label' => __( 'Follow Post Types', 'social-media-feather' ),
241
- 'tip' => __( 'Post types for which automatic appending for follow buttons should be attempted (CTRL + click to select multiple ones)',
242
- 'social-media-feather' ),
 
 
243
  'render' => 'synved_social_automatic_append_post_types_render',
244
- ],
245
- 'automatic_follow_before_share' => [
246
  'default' => false,
247
  'label' => __( 'Follow Before Share', 'social-media-feather' ),
248
- 'tip' => __( 'When automatically appending, place follow buttons before share buttons. Only valid when share and follow buttons positions are the same.',
249
- 'social-media-feather' ),
250
- ],
251
- 'automatic_follow_prefix' => [
 
 
252
  'default' => '',
253
  'label' => __( 'Follow Prefix Markup', 'social-media-feather' ),
254
- 'tip' => __( 'When automatically appending, place this markup before the follow buttons markup',
255
- 'social-media-feather' ),
256
- ],
257
- 'automatic_follow_postfix' => [
 
 
258
  'default' => '',
259
  'label' => __( 'Follow Postfix Markup', 'social-media-feather' ),
260
- 'tip' => __( 'When automatically appending, place this markup after all of the follow buttons markup',
261
- 'social-media-feather' ),
262
- ],
263
- 'automatic_append_prefix' => [
 
 
264
  'default' => '',
265
  'label' => __( 'Prefix Markup', 'social-media-feather' ),
266
- 'tip' => __( 'When automatically appending, place this markup before the buttons markup',
267
- 'social-media-feather' ),
268
- ],
269
- 'automatic_append_separator' => [
 
 
270
  'default' => '<br/>',
271
  'label' => __( 'Separator Markup', 'social-media-feather' ),
272
- 'tip' => __( 'When automatically appending both, use this markup as separator between the set of share buttons and the set of follow buttons. Only valid when share and follow buttons positions are the same.',
273
- 'social-media-feather' ),
274
- ],
275
- 'automatic_append_postfix' => [
 
 
276
  'default' => '',
277
  'label' => __( 'Postfix Markup', 'social-media-feather' ),
278
- 'tip' => __( 'When automatically appending, place this markup after all of the buttons markup',
279
- 'social-media-feather' ),
280
- ],
281
- ],
282
- ],
283
- 'section_customize_look' => [
 
 
284
  'label' => __( 'Customize Look', 'social-media-feather' ),
285
- 'tip' => synved_option_callback( 'synved_social_section_customize_look_tip',
286
- __( 'Customize the look & feel of Social Media Feather', 'social-media-feather' ) ),
287
- 'settings' => [
288
- 'icon_skin' => [
 
 
289
  'default' => 'regular',
290
  'set' => synved_option_callback( 'synved_social_cb_icon_skin_set', 'regular=Regular' ),
291
  'label' => __( 'Icon Skin', 'social-media-feather' ),
292
  'tip' => '',
293
  'render' => 'synved_social_icon_skin_render',
294
- ],
295
- 'icon_size' => [
296
  'default' => 48,
297
  'set' => '16=16x16,24=24x24,32=32x32,48=48x48,64=64x64,96=96x96',
298
  'label' => __( 'Icon Size', 'social-media-feather' ),
299
- 'tip' => __( 'Select the size in pixels for the icons. Note: for high resolution displays like Retina the maximum size is 64x64.',
300
- 'social-media-feather' ),
301
- ],
302
- 'icon_resolution' => [
 
 
303
  'default' => 'single',
304
  'set' => 'single=Single,double=Double',
305
  'label' => __( 'Icon Resolution', 'social-media-feather' ),
306
- 'tip' => __( 'Select what icon resolutions will be used. Single might make the icons slightly blurry on low resolution displays. Double will always look the best but will consume more bandwidth.',
307
- 'social-media-feather' ),
308
- ],
309
- 'icon_spacing' => [
 
 
310
  'default' => 5,
311
  'label' => __( 'Icon Spacing', 'social-media-feather' ),
312
  'tip' => __( 'Select the spacing in pixels between the icons', 'social-media-feather' ),
313
- ],
314
- 'buttons_container' => [
315
  'default' => 'none',
316
  'set' => 'none=None,share=Sharing Buttons,follow=Following Buttons,both=Both',
317
  'label' => __( 'Buttons in Container', 'social-media-feather' ),
318
- 'tip' => __( 'Determines whether or not to wrap the buttons in a container, which will affect how the buttons are rendered, based on the "Buttons Container Type" setting.',
319
- 'social-media-feather' ),
320
- ],
321
- 'buttons_container_type' => [
 
 
322
  'default' => 'basic',
323
  'set' => 'basic=Basic,block=Block',
324
  'label' => __( 'Buttons Container Type', 'social-media-feather' ),
325
- 'tip' => __( '"Basic" should not affect rendering, while "Block" should display the buttons in their own row. <b>Note</b>: selecting "Block" might not look the way you want if you\'re using Prefix or Postfix markup.',
326
- 'social-media-feather' ),
327
- ],
328
- 'buttons_alignment_share' => [
 
 
329
  'default' => 'none',
330
  'set' => 'none=Theme Default,left=Align Left,right=Align Right,center=Align Center',
331
  'label' => __( 'Share Buttons Alignment', 'social-media-feather' ),
332
- 'tip' => __( 'Will attempt at aligning the share buttons accordingly. <strong>Note:</strong> this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes',
333
- 'social-media-feather' ),
334
- ],
335
- 'buttons_alignment_follow' => [
 
 
336
  'default' => 'none',
337
  'set' => 'none=Theme Default,left=Align Left,right=Align Right,center=Align Center',
338
  'label' => __( 'Follow Buttons Alignment', 'social-media-feather' ),
339
- 'tip' => __( 'Will attempt at aligning the follow buttons accordingly. <strong>Note:</strong> this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes',
340
- 'social-media-feather' ),
341
- ],
342
- 'custom_style' => [
 
 
343
  'type' => 'style',
344
  'label' => __( 'Extra Styles', 'social-media-feather' ),
345
- 'tip' => __( 'Any CSS styling code you type in here will be loaded after all of the Social Media Feather styles.',
346
- 'social-media-feather' ),
347
- ],
348
- ],
349
- ],
350
- 'section_service_providers' => [
 
 
351
  'label' => __( 'Service Providers', 'social-media-feather' ),
352
  'tip' => __( 'Customize social sharing and following providers', 'social-media-feather' ),
353
  'settings' => synved_social_provider_settings(),
354
- ],
355
- ],
356
- ],
357
- ];
358
 
359
  synved_option_register( 'synved_social', $synved_social_options );
360
 
361
  synved_option_include_module_addon_list( 'synved-social' );
362
 
 
 
 
 
 
363
  function synved_social_accept_terms_switch() {
364
-
365
  $out = '<label class="synved-switch">
366
- <input id="synved-disable" name="synved_social_settings[accepted_sharethis_terms]"
367
- type="checkbox" value="' . ( synved_social_are_terms_accepted() ? 1 : 0 ) . '">
368
- <div id="synved-slider" class="synved-slider round"></div>
369
- </label>';
370
 
371
- return $out;
372
  }
373
 
374
  /**
375
  * Synved Social Page Settings tip.
376
  *
377
- * @param $tip
378
- * @param $item
379
  *
380
  * @return string
381
  */
@@ -384,7 +511,7 @@ function synved_social_page_settings_tip( $tip, $item ) {
384
 
385
  $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
386
 
387
- if ( preg_match( '/page=synved_social_settings/i', $request_uri ) ) {
388
  $accept_terms = filter_input( INPUT_GET, 'accept-terms', FILTER_SANITIZE_STRING );
389
 
390
  // If terms have just been accepted.
@@ -402,25 +529,52 @@ function synved_social_page_settings_tip( $tip, $item ) {
402
  return $tip;
403
  }
404
 
 
 
 
 
 
 
 
 
 
405
  function synved_social_page_render_fragment( $fragment, $out, $params ) {
406
- if ( $fragment == 'page-submit-tail' ) {
407
  $out .= '<div style="clear:both; margin-top: -12px;"><a target="_blank" href="http://wordpress.org/support/view/plugin-reviews/social-media-feather?rate=5#postform" style="font-size:120%"><b>We need your help!</b> If you like the plugin, you can help us by leaving a 5-stars review! It only takes a minute and it\'s free!</a></div>';
408
  $out .= '<p>By using this plugin you are agreeing to the <a href="https://sharethis.com/terms/" target="_blank">Terms of service</a> and <a href="https://sharethis.com/privacy/" target="_blank">Privacy Policy</a>.</p>';
409
  }
410
 
411
- return $out;
 
 
412
  }
413
 
 
 
 
 
 
 
 
 
414
  function synved_social_section_customize_look_tip( $tip, $item ) {
415
- return $tip;
416
  }
417
 
 
 
 
 
 
 
 
 
418
  function synved_social_cb_icon_skin_set( $set, $item ) {
419
- if ( $set != null && ! is_array( $set ) ) {
420
  $set = synved_option_item_set_parse( $item, $set );
421
  }
422
 
423
- $set = [];
424
  $icons = synved_social_icon_skin_list();
425
 
426
  foreach ( $icons as $icon_name => $icon_meta ) {
@@ -430,6 +584,17 @@ function synved_social_cb_icon_skin_set( $set, $item ) {
430
  return $set;
431
  }
432
 
 
 
 
 
 
 
 
 
 
 
 
433
  function synved_social_icon_skin_render( $value, $params, $id, $name, $item ) {
434
  $uri = synved_social_path_uri();
435
  $icons = synved_social_icon_skin_list();
@@ -444,31 +609,56 @@ function synved_social_icon_skin_render( $value, $params, $id, $name, $item ) {
444
 
445
  foreach ( $set as $set_it ) {
446
  $set_it_keys = array_keys( $set_it );
447
- $selected = $set_it_keys[0] == $value ? ' checked="checked"' : null;
448
  $img_src = '';
449
 
450
  if ( isset( $icons[ $set_it_keys[0] ] ) ) {
451
  $img_src = $icons[ $set_it_keys[0] ]['image'];
452
  }
453
 
454
- $disabled = disabled( ! $sharethis_terms_agree && ! empty( $icons[ $set_it_keys[0] ]['extra'] ), true, false );
 
 
 
 
 
455
 
456
- $out .= '<div style="text-align:center; width:260px; float:left; margin-right:20px; margin-bottom: 15px;"><label title="Use skin=&quot;' . esc_attr( $set_it_keys[0] ) . '&quot; in shortcodes"><img src="' . esc_url( $img_src ) . '" style="border:solid 1px #bbb" /><p><input type="radio" name="' . esc_attr( $out_name ) . '" value="' . esc_attr( $set_it_keys[0] ) . '"' . $selected . ' ' . $disabled . '/> ' . $set_it[ $set_it_keys[0] ] . '</p></label></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
458
 
459
  $out .= '</div>';
460
 
461
- return $out;
462
  }
463
 
464
-
 
 
 
 
 
 
 
465
  function synved_social_automatic_append_post_types_set( $set, $item ) {
466
- if ( $set != null && ! is_array( $set ) ) {
467
  $set = synved_option_item_set_parse( $item, $set );
468
  }
469
 
470
- $set = [];
471
- $types = get_post_types( [ 'public' => true ] );
472
 
473
  foreach ( $types as $type_name ) {
474
  $set[][ $type_name ] = $type_name;
@@ -477,15 +667,26 @@ function synved_social_automatic_append_post_types_set( $set, $item ) {
477
  return $set;
478
  }
479
 
 
 
 
 
 
 
 
 
 
 
 
480
  function synved_social_automatic_append_post_types_render( $value, $params, $id, $name, $item ) {
481
  $uri = synved_social_path_uri();
482
  $icons = synved_social_icon_skin_list();
483
 
484
- if ( ! is_array( $value ) ) {
485
- if ( $value != null ) {
486
- $value = [ $value ];
487
  } else {
488
- $value = [];
489
  }
490
  }
491
 
@@ -497,45 +698,64 @@ function synved_social_automatic_append_post_types_render( $value, $params, $id,
497
 
498
  foreach ( $set as $set_it ) {
499
  $set_it_keys = array_keys( $set_it );
500
- $selected = in_array( $set_it_keys[0], $value ) ? ' selected="selected"' : null;
501
 
502
- $out .= '<option value="' . esc_attr( $set_it_keys[0] ) . '"' . $selected . '>' . $set_it[ $set_it_keys[0] ] . '</option>';
 
 
 
 
 
 
503
  }
504
 
505
  $out .= '</select>';
506
 
507
- return $out;
508
  }
509
 
 
 
 
 
 
 
 
510
  function synved_social_path( $path = null ) {
511
  $root = dirname( __FILE__ );
512
 
513
- if ( $root != null ) {
514
- if ( substr( $root, - 1 ) != '/' && isset( $path ) && $path[0] != '/' ) {
515
  $root .= '/';
516
  }
517
 
518
  $root .= $path;
519
  }
520
 
521
- $root = str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, $root );
522
 
523
  return $root;
524
  }
525
 
 
 
 
 
 
 
 
526
  function synved_social_path_uri( $path = null ) {
527
  $uri = plugins_url( '/social-media-feather' ) . '/synved-social';
528
 
529
  if ( function_exists( 'synved_plugout_module_uri_get' ) ) {
530
  $mod_uri = synved_plugout_module_uri_get( 'synved-social' );
531
 
532
- if ( $mod_uri != null ) {
533
  $uri = $mod_uri;
534
  }
535
  }
536
 
537
- if ( $path != null ) {
538
- if ( substr( $uri, - 1 ) != '/' && $path[0] != '/' ) {
539
  $uri .= '/';
540
  }
541
 
@@ -545,6 +765,14 @@ function synved_social_path_uri( $path = null ) {
545
  return $uri;
546
  }
547
 
 
 
 
 
 
 
 
 
548
  function synved_social_wp_script_loader_tag( $tag, $handle ) {
549
  if ( 'feather-sharethis' === $handle ) {
550
  return str_replace( '<script', '<script id=\'st_insights_js\'', $tag );
@@ -553,26 +781,6 @@ function synved_social_wp_script_loader_tag( $tag, $handle ) {
553
  return $tag;
554
  }
555
 
556
- function synved_social_enqueue_scripts() {
557
- if ( true === synved_social_are_terms_accepted() ) {
558
- if ( true === is_ssl() ) {
559
- $st_insights = 'https://ws.sharethis.com/button/st_insights.js';
560
- } else {
561
- $st_insights = 'http://w.sharethis.com/button/st_insights.js';
562
- }
563
-
564
- $url = add_query_arg(
565
- [
566
- 'publisher' => 'eba0f3ba-f9ab-408c-bc68-c28af5afe749',
567
- 'product' => 'feather',
568
- ], $st_insights );
569
-
570
- wp_enqueue_script( 'feather-sharethis', $url, null, null );
571
-
572
- add_filter( 'script_loader_tag', 'synved_social_wp_script_loader_tag', 10, 2 );
573
- }
574
- }
575
-
576
  /**
577
  * Are terms accepted?
578
  *
@@ -582,49 +790,6 @@ function synved_social_are_terms_accepted() {
582
  return synved_option_get( 'synved_social', 'accepted_sharethis_terms', false );
583
  }
584
 
585
- /**
586
- * Print Styles.
587
- *
588
- * @return void
589
- */
590
- function synved_social_print_styles() {
591
- ob_start();
592
-
593
- echo <<<HEAD_STYLE
594
- <style>
595
- .synved-social-resolution-single {
596
- display: inline-block;
597
- }
598
- .synved-social-resolution-normal {
599
- display: inline-block;
600
- }
601
- .synved-social-resolution-hidef {
602
- display: none;
603
- }
604
-
605
- @media only screen and (min--moz-device-pixel-ratio: 2),
606
- only screen and (-o-min-device-pixel-ratio: 2/1),
607
- only screen and (-webkit-min-device-pixel-ratio: 2),
608
- only screen and (min-device-pixel-ratio: 2),
609
- only screen and (min-resolution: 2dppx),
610
- only screen and (min-resolution: 192dpi) {
611
- .synved-social-resolution-normal {
612
- display: none;
613
- }
614
- .synved-social-resolution-hidef {
615
- display: inline-block;
616
- }
617
- }
618
- </style>
619
- HEAD_STYLE;
620
-
621
- $styles = ob_get_clean();
622
-
623
- echo wp_kses( $styles, [
624
- 'style' => [],
625
- ] );
626
- }
627
-
628
  /**
629
  * Admin enqueue scripts for Social.
630
  *
@@ -637,18 +802,32 @@ function synved_social_admin_enqueue_scripts() {
637
  wp_enqueue_script(
638
  'synved-option-script-custom',
639
  $uri . '/script/custom.js',
640
- [
641
  'jquery',
642
- ],
643
- filemtime( $dir . '/script/custom.js' )
 
644
  );
645
  }
646
 
 
 
 
 
 
647
  function synved_social_register_widgets() {
648
  register_widget( 'SynvedSocialShareWidget' );
649
  register_widget( 'SynvedSocialFollowWidget' );
650
  }
651
 
 
 
 
 
 
 
 
 
652
  function synved_social_wp_the_content( $content, $id = null ) {
653
  $exclude = false;
654
  $exclude_share = false;
@@ -659,62 +838,76 @@ function synved_social_wp_the_content( $content, $id = null ) {
659
  $separator_after = null;
660
  $separator_before = null;
661
 
662
- if ( $id == null ) {
663
  $id = get_the_ID();
664
 
665
- if ( $id == null ) {
666
  global $post;
667
 
668
  $id = $post->ID;
669
  }
670
  }
671
 
672
- if ( $id != null ) {
673
- $exclude = get_post_meta( $id, 'synved_social_exclude', true ) == 'yes' ? true : false;
674
- $exclude_share = get_post_meta( $id, 'synved_social_exclude_share', true ) == 'yes' ? true : false;
675
- $exclude_follow = get_post_meta( $id, 'synved_social_exclude_follow', true ) == 'yes' ? true : false;
676
-
677
- if ( ! $exclude_share && synved_option_get( 'synved_social', 'automatic_share_single' ) ) {
678
- $exclude_share = ! ( is_singular( synved_option_get( 'synved_social',
679
- 'automatic_share_post_types' ) ) && ( is_single( $id ) || is_page( $id ) ) );
 
 
 
 
 
 
680
  }
681
 
682
- if ( ! $exclude_follow && synved_option_get( 'synved_social', 'automatic_follow_single' ) ) {
683
- $exclude_follow = ! ( is_singular( synved_option_get( 'synved_social',
684
- 'automatic_follow_post_types' ) ) && ( is_single( $id ) || is_page( $id ) ) );
 
 
 
 
 
 
685
  }
686
  }
687
 
688
- if ( $exclude == false ) {
689
- if ( $exclude_share == false && synved_option_get( 'synved_social', 'automatic_share' ) ) {
 
 
690
  $post_type = get_post_type();
691
  $type_list = synved_option_get( 'synved_social', 'automatic_share_post_types' );
692
 
693
  if ( true === is_string( $type_list ) ) {
694
- $type_list = [ $type_list ];
695
  }
696
 
697
- if ( in_array( $post_type, $type_list ) ) {
698
  $position = synved_option_get( 'synved_social', 'automatic_share_position' );
699
- $position_before = in_array( $position, [ 'before_post', 'after_before_post' ] );
700
- $position_after = in_array( $position, [ 'after_post', 'after_before_post' ] );
701
  $prefix = synved_option_get( 'synved_social', 'automatic_share_prefix' );
702
  $postfix = synved_option_get( 'synved_social', 'automatic_share_postfix' );
703
 
704
  if ( $position_after ) {
705
  $markup = synved_social_share_markup();
706
 
707
- if ( trim( $markup ) != null ) {
708
  $markup = $prefix . $markup . $postfix;
709
 
710
  $extra_after .= $markup;
711
  }
712
  }
713
 
714
- if ( $position_before ) {
715
  $markup = synved_social_share_markup();
716
 
717
- if ( trim( $markup ) != null ) {
718
  $markup = $prefix . $markup . $postfix;
719
 
720
  $extra_before .= $markup;
@@ -725,32 +918,38 @@ function synved_social_wp_the_content( $content, $id = null ) {
725
 
726
  $separator = synved_option_get( 'synved_social', 'automatic_append_separator' );
727
 
728
- if ( $extra_after != null ) {
729
  $separator_after = $separator;
730
  }
731
 
732
- if ( $extra_before != null ) {
733
  $separator_before = $separator;
734
  }
735
 
736
- if ( $exclude_follow == false && synved_option_get( 'synved_social', 'automatic_follow' ) ) {
 
 
737
  $post_type = get_post_type();
738
- $type_list = synved_option_get( 'synved_social', 'automatic_follow_post_types' );
739
 
740
- if ( in_array( $post_type, $type_list ) ) {
 
 
 
 
741
  $position = synved_option_get( 'synved_social', 'automatic_follow_position' );
742
- $position_before = in_array( $position, [ 'before_post', 'after_before_post' ] );
743
- $position_after = in_array( $position, [ 'after_post', 'after_before_post' ] );
744
  $prefix = synved_option_get( 'synved_social', 'automatic_follow_prefix' );
745
  $postfix = synved_option_get( 'synved_social', 'automatic_follow_postfix' );
746
 
747
- if ( $position_after ) {
748
  $markup = synved_social_follow_markup();
749
 
750
- if ( trim( $markup ) != null ) {
751
  $markup = $prefix . $markup . $postfix;
752
 
753
- if ( synved_option_get( 'synved_social', 'automatic_follow_before_share' ) ) {
754
  $extra_after = $markup . $separator_after . $extra_after;
755
  } else {
756
  $extra_after .= $separator_after . $markup;
@@ -761,10 +960,10 @@ function synved_social_wp_the_content( $content, $id = null ) {
761
  if ( $position_before ) {
762
  $markup = synved_social_follow_markup();
763
 
764
- if ( trim( $markup ) != null ) {
765
  $markup = $prefix . $markup . $postfix;
766
 
767
- if ( synved_option_get( 'synved_social', 'automatic_follow_before_share' ) ) {
768
  $extra_before = $markup . $separator_before . $extra_before;
769
  } else {
770
  $extra_before .= $separator_before . $markup;
@@ -777,11 +976,11 @@ function synved_social_wp_the_content( $content, $id = null ) {
777
  $prefix = synved_option_get( 'synved_social', 'automatic_append_prefix' );
778
  $postfix = synved_option_get( 'synved_social', 'automatic_append_postfix' );
779
 
780
- if ( $extra_after != null ) {
781
  $content .= $prefix . $extra_after . $postfix;
782
  }
783
 
784
- if ( $extra_before != null ) {
785
  $content = $prefix . $extra_before . $postfix . $content;
786
  }
787
  }
@@ -792,27 +991,26 @@ function synved_social_wp_the_content( $content, $id = null ) {
792
  /**
793
  * Renders ShareThis Terms of Service alert.
794
  *
795
- * @param bool $render_html
796
- * @param bool $isDismissible
797
  *
798
  * @return string
799
  */
800
- function synved_social_sharethis_terms_notice( $render_html = true, $isDismissible = true ) {
801
- $out = '<div id="sharethis_terms_notice" class="notice-warning notice ' . ( ! empty( $isDismissible ) ? 'is-dismissible' : '' ) . '">
802
  <p>
803
  To get the most out of Social Media Feather and to help enable its continued development,
804
  please read the <a href="//sharethis.com/terms" target="_blank">ShareThis Terms of Service</a> and <a href="//sharethis.com/privacy" target="_blank">Privacy Notice</a>,
805
- then <a href="' . admin_url( 'options-general.php?page=synved_social_settings&accept-terms=yes' ) . '">click here to accept the terms</a>.
806
  </p>
807
  </div>
808
  ';
809
 
810
  if ( $render_html ) {
811
- echo $out;
812
  } else {
813
- return $out;
814
  }
815
-
816
  }
817
 
818
  /**
@@ -822,31 +1020,40 @@ function synved_social_sharethis_terms_notice_callback_admin_notice_wrapper() {
822
  synved_social_sharethis_terms_notice( true, true );
823
  }
824
 
825
- // Hides the terms agreement at user's request.
 
 
 
 
826
  function synved_social_admin_hide_callback() {
827
  synved_option_set( 'synved_social', 'hide_sharethis_terms', true );
828
  }
829
 
 
 
 
 
 
830
  function synved_social_init() {
831
  $priority = defined( 'SHORTCODE_PRIORITY' ) ? SHORTCODE_PRIORITY : 11;
832
 
833
- if ( synved_option_get( 'synved_social', 'shortcode_widgets' ) ) {
834
  remove_filter( 'widget_text', 'do_shortcode', $priority );
835
  add_filter( 'widget_text', 'do_shortcode', $priority );
836
  }
837
 
838
- if ( function_exists( 'synved_shortcode_add' ) ) {
839
  synved_shortcode_add( 'feather_share', 'synved_social_share_shortcode' );
840
  synved_shortcode_add( 'feather_follow', 'synved_social_follow_shortcode' );
841
 
842
  $size_set = '16,24,32,48,64,96';
843
  $size_item = synved_option_item( 'synved_social', 'icon_size' );
844
 
845
- if ( $size_item != null ) {
846
  $item_set = synved_option_item_set( $size_item );
847
 
848
- if ( $item_set != null ) {
849
- $set_items = [];
850
 
851
  foreach ( $item_set as $set_item ) {
852
  $item_keys = array_keys( $set_item );
@@ -861,37 +1068,64 @@ function synved_social_init() {
861
  $providers_share = array_keys( synved_social_service_provider_list( 'share' ) );
862
  $providers_follow = array_keys( synved_social_service_provider_list( 'follow' ) );
863
 
864
- $providers_params = [
865
- 'show' => __( 'Specify a comma-separated list of %1$s providers to show and their order, possible values are %2$s',
866
- 'social-media-feather' ),
867
- 'hide' => __( 'Specify a comma-separated list of %1$s providers to hide, possible values are %2$s',
868
- 'social-media-feather' ),
869
- ];
 
 
 
 
 
 
870
 
871
- $common_params = [
872
  'skin' => __( 'Specify which skin to use for the icons', 'social-media-feather' ),
873
- 'size' => sprintf( __( 'Specify the size for the icons, possible values are %s',
874
- 'social-media-feather' ), $size_set ),
875
- 'spacing' => __( 'Determines how much blank space there will be between the buttons, in pixels',
876
- 'social-media-feather' ),
 
 
 
 
 
 
 
 
877
  'container' => __( 'Determines whether to wrap the buttons in a container', 'social-media-feather' ),
878
- 'container_type' => sprintf( __( 'Determines what type of container to use, possible values are %1$s',
879
- 'social-media-feather' ), 'basic, block' ),
880
- 'class' => __( 'Select additional CSS classes for the buttons, separated by spaces',
881
- 'social-media-feather' ),
882
- ];
883
-
884
- $share_params = [
885
- 'url' => __( 'URL to use for the sharing buttons, default is the current post URL',
886
- 'social-media-feather' ),
887
- 'title' => __( 'Title to use for the sharing buttons, default is the current post title',
888
- 'social-media-feather' ),
889
- 'message' => __( 'Message to use when sharing content, replaced into the %%message%% variable',
890
- 'social-media-feather' ),
891
- ];
892
-
893
- $follow_params = [
894
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
895
 
896
  $share_params = array_merge( $common_params, $share_params );
897
  $follow_params = array_merge( $common_params, $follow_params );
@@ -901,16 +1135,29 @@ function synved_social_init() {
901
  $follow_params[ $param_name ] = sprintf( $param_value, 'follow', implode( ', ', $providers_follow ) );
902
  }
903
 
904
- synved_shortcode_item_help_set( 'feather_share', [
905
- 'tip' => __( 'Creates a list of buttons for social sharing as selected in the Social Media options',
906
- 'social-media-feather' ),
907
- 'parameters' => $share_params,
908
- ] );
909
- synved_shortcode_item_help_set( 'feather_follow', [
910
- 'tip' => __( 'Creates a list of buttons for social following as selected in the Social Media options',
911
- 'social-media-feather' ),
912
- 'parameters' => $follow_params,
913
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
914
  } else {
915
  add_shortcode( 'feather_share', 'synved_social_share_shortcode' );
916
  add_shortcode( 'synved_feather_share', 'synved_social_share_shortcode' );
@@ -918,33 +1165,31 @@ function synved_social_init() {
918
  add_shortcode( 'synved_feather_follow', 'synved_social_follow_shortcode' );
919
  }
920
 
921
- if ( ! is_admin() ) {
922
- add_action( 'wp_enqueue_scripts', 'synved_social_enqueue_scripts' );
923
- add_action( 'wp_head', 'synved_social_print_styles' );
924
- }
925
-
926
- if ( synved_option_get( 'synved_social', 'automatic_share' ) || synved_option_get( 'synved_social',
927
- 'automatic_follow' ) ) {
928
  add_filter( 'the_content', 'synved_social_wp_the_content', 10, 2 );
929
  }
930
 
931
- if ( is_admin() ) {
932
- if ( current_user_can( 'manage_options' ) ) {
933
  $accept_terms = filter_input( INPUT_GET, 'accept-terms', FILTER_SANITIZE_STRING );
934
 
935
  if ( false === empty( $accept_terms ) ) {
936
  synved_option_set( 'synved_social', 'accepted_sharethis_terms', ( 'yes' === $accept_terms ) );
937
- wp_redirect( admin_url( 'options-general.php?page=synved_social_settings' ) );
 
938
  }
939
  }
940
 
941
  $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
942
 
943
- $canShowShareThisAlert = ! synved_option_get( 'synved_social',
944
- 'accepted_sharethis_terms' ) &&
945
- ! synved_option_get( 'synved_social', 'hide_sharethis_terms' ) &&
946
- ! preg_match( '/page=synved_social_settings/i', $request_uri );
947
- if ( $canShowShareThisAlert ) {
 
948
  add_action( 'admin_notices', 'synved_social_sharethis_terms_notice_callback_admin_notice_wrapper' );
949
  add_action( 'wp_ajax_feather_hide_terms', 'synved_social_admin_hide_callback' );
950
  }
@@ -955,6 +1200,6 @@ add_action( 'init', 'synved_social_init' );
955
 
956
  add_action( 'widgets_init', 'synved_social_register_widgets' );
957
 
958
- if ( is_admin() ) {
959
  add_action( 'admin_enqueue_scripts', 'synved_social_admin_enqueue_scripts' );
960
  }
1
  <?php
2
+ /**
3
+ * Setup.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
 
8
+ /**
9
+ * Social Provider Settings.
10
+ *
11
+ * @return array
12
+ */
13
  function synved_social_provider_settings() {
14
  $share_providers = synved_social_service_provider_list( 'share', true );
15
  $follow_providers = synved_social_service_provider_list( 'follow', true );
16
  $provider_list = array_merge( $share_providers, $follow_providers );
17
+ $providers_settings = array();
18
 
19
  foreach ( $provider_list as $provider_name => $provider_item ) {
20
+ $provider_label = ucwords( str_replace( array( '-', '_' ), ' ', $provider_name ) );
21
  $display_set = 'none=None';
22
  $display_default = 'none';
23
 
49
  }
50
  }
51
 
52
+ $providers_settings = array_merge(
53
+ $providers_settings,
54
+ array(
55
+ $provider_name . '_display' => array(
56
  'default' => $display_default,
57
  'style' => 'group',
58
  'set' => $display_set,
59
+ 'label' => sprintf(
60
+ /* translators: %s is the Provider Label. */
61
+ __( '%s Service', 'social-media-feather' ),
62
+ $provider_label
63
+ ),
64
+ 'tip' => sprintf(
65
+ /* translators: %s is the Provider Label. */
66
+ __(
67
+ 'Decides for what types of services %s will be used by default',
68
+ 'social-media-feather'
69
+ ),
70
+ $provider_label
71
+ ),
72
+ ),
73
+ )
74
  );
75
 
76
  if ( true === isset( $share_providers[ $provider_name ] ) ) {
77
  $share_item = $share_providers[ $provider_name ];
78
 
79
+ $providers_settings = array_merge(
80
+ $providers_settings,
81
+ array(
82
+ $provider_name . '_share_link' => array(
83
+ 'label' => sprintf(
84
+ /* translators: %s is the Provider Label. */
85
+ __( '%s Share Link', 'social-media-feather' ),
86
+ $provider_label
87
+ ),
88
+ 'tip' => sprintf(
89
+ /* translators: %s is the Provider Label. */
90
+ __(
91
+ 'The link used by default for sharing content on %s. <b>Note: this generally doesn\'t need to be changed, only change it if you know what you\'re doing.</b>',
92
+ 'social-media-feather'
93
+ ),
94
+ $provider_label
95
+ ),
96
  'hint' => $share_item['link'],
97
+ ),
98
+ $provider_name . '_share_title' => array(
99
+ 'label' => sprintf(
100
+ /* translators: %s is the Provider Label. */
101
+ __( '%s Share Title', 'social-media-feather' ),
102
+ $provider_label
103
+ ),
104
+ 'tip' => sprintf(
105
+ /* translators: %s is the Provider Label. */
106
+ __(
107
+ 'The title used by default for the %s share button (a standard one will be used if left empty)',
108
+ 'social-media-feather'
109
+ ),
110
+ $provider_label
111
+ ),
112
  'hint' => $share_item['title'],
113
+ ),
114
+ )
115
  );
116
  }
117
 
118
  if ( true === isset( $follow_providers[ $provider_name ] ) ) {
119
  $follow_item = $follow_providers[ $provider_name ];
120
 
121
+ $providers_settings = array_merge(
122
+ $providers_settings,
123
+ array(
124
+ $provider_name . '_follow_link' => array(
125
+ 'label' => sprintf(
126
+ /* translators: %s is the Provider Label. */
127
+ __( '%s Follow Link', 'social-media-feather' ),
128
+ $provider_label
129
+ ),
130
+ 'tip' => sprintf(
131
+ /* translators: %1$s is the Provider Label. */
132
+ __(
133
+ 'The link used by default for following you on %1$s. Change this to point to your own social profile page on %1$s.',
134
+ 'social-media-feather'
135
+ ),
136
+ $provider_label
137
+ ),
138
  'hint' => $follow_item['link'],
139
+ ),
140
+ $provider_name . '_follow_title' => array(
141
+ 'label' => sprintf(
142
+ /* translators: %1$s is the Provider Label. */
143
+ __( '%s Follow Title', 'social-media-feather' ),
144
+ $provider_label
145
+ ),
146
+ 'tip' => sprintf(
147
+ /* translators: %1$s is the Provider Label. */
148
+ __(
149
+ 'The title used by default for the %s follow button (a standard one will be used if left empty)',
150
+ 'social-media-feather'
151
+ ),
152
+ $provider_label
153
+ ),
154
  'hint' => $follow_item['title'],
155
+ ),
156
+ )
157
  );
158
  }
159
  }
163
 
164
  $terms_accepted = synved_option_get( 'synved_social', 'accepted_sharethis_terms' );
165
 
166
+ $synved_social_options = array(
167
+ 'settings' => array(
168
  'label' => 'Social Media',
169
  'title' => 'Social Media Feather',
170
  'tip' => synved_option_callback( 'synved_social_page_settings_tip' ),
171
  'link-target' => plugin_basename( synved_plugout_module_path_get( 'synved-social', 'provider' ) ),
172
  'render-fragment' => 'synved_social_page_render_fragment',
173
+ 'sections' => array(
174
+ 'section_general' => array(
175
  'label' => __( 'General Settings', 'social-media-feather' ),
176
  'tip' => __( 'Settings affecting the general behaviour of the plugin', 'social-media-feather' ),
177
+ 'settings' => array(
178
+ 'use_shortlinks' => array(
179
  'default' => false,
180
  'label' => __( 'Use Shortlinks', 'social-media-feather' ),
181
+ 'tip' => __(
182
+ 'Allows for shortened URLs to be used when sharing content if a shortening plugin is installed',
183
+ 'social-media-feather'
184
+ ),
185
+ ),
186
+ 'share_full_url' => array(
187
  'default' => false,
188
  'label' => __( 'Share Full URL', 'social-media-feather' ),
189
+ 'tip' => __(
190
+ 'Determines whether to always share the full URL or just the post permalink. You can override this for individual posts by setting the "synved_social_share_full_url" custom field to either "yes" or "no", case sensitive',
191
+ 'social-media-feather'
192
+ ),
193
+ ),
194
+ 'layout_rtl' => array(
195
  'default' => false,
196
  'label' => __( 'Right To Left Layout', 'social-media-feather' ),
197
+ 'tip' => __(
198
+ 'Check this option if you have a right-to-left site layout and icons show spacing issues',
199
+ 'social-media-feather'
200
+ ),
201
+ ),
202
+ 'shortcode_widgets' => array(
203
  'default' => true,
204
  'label' => __( 'Shortcodes In Widgets', 'social-media-feather' ),
205
  'tip' => __( 'Allow shortcodes in Text widgets', 'social-media-feather' ),
206
+ ),
207
+ 'show_credit' => array(
208
  'default' => false,
209
  'label' => __( 'Show Credit', 'social-media-feather' ),
210
+ 'tip' => __(
211
+ 'Display a small icon with a link to the Social Media Feather page',
212
+ 'social-media-feather'
213
+ ),
214
+ ),
215
+ 'share_message_default' => array(
216
  'default' => __( 'Hey check this out', 'social-media-feather' ),
217
  'label' => __( 'Default Message', 'social-media-feather' ),
218
+ 'tip' => __(
219
+ 'Specify the default message to use when sharing content, this is what gets replaced into the %%message%% variable',
220
+ 'social-media-feather'
221
+ ),
222
+ ),
223
+ 'fb_app_id' => array(
 
 
 
 
224
  'default' => '',
225
  'label' => __( 'Facebook App ID', 'social-media-feather' ),
226
+ ),
227
+ 'accepted_sharethis_terms' => array(
228
  'type' => 'custom',
229
  'label' => __( 'Terms of Service', 'social-media-feather' ),
230
+ 'tip' => __(
231
+ 'Accept or decline <a target="_blank" href="https://www.sharethis.com/terms/">ShareThis Terms of Service</a> and <a target="_blank" href="https://www.sharethis.com/privacy/">Privacy Notice</a>',
232
+ 'social-media-feather'
233
+ ),
234
  'render' => 'synved_social_accept_terms_switch',
235
+ ),
236
+ ),
237
+ ),
238
 
239
+ 'section_automatic_display' => array(
240
  'label' => __( 'Automatic Display', 'social-media-feather' ),
241
+ 'tip' => __(
242
+ 'Settings affecting automating appending of social buttons to post contents',
243
+ 'social-media-feather'
244
+ ),
245
+ 'settings' => array(
246
+ 'automatic_share' => array(
247
  'default' => false,
248
  'label' => __( 'Display Sharing Buttons', 'social-media-feather' ),
249
+ 'tip' => __(
250
+ 'Tries to automatically append sharing buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_share to "yes", case sensitive)',
251
+ 'social-media-feather'
252
+ ),
253
+ ),
254
+ 'automatic_share_position' => array(
255
  'default' => 'after_post',
256
  'set' => 'after_post=After Post,before_post=Before Post,after_before_post=After and Before Post',
257
  'label' => __( 'Share Buttons Position', 'social-media-feather' ),
258
+ 'tip' => __(
259
+ 'Select where the sharing buttons should be placed. Note: placing buttons Before Post might not work in all themes.',
260
+ 'social-media-feather'
261
+ ),
262
+ ),
263
+ 'automatic_share_single' => array(
264
  'default' => false,
265
  'label' => __( 'Sharing Single Posts', 'social-media-feather' ),
266
+ 'tip' => __(
267
+ 'Sharing buttons are only displayed on single posts/pages and not on archive pages like blog/category/tag/author pages',
268
+ 'social-media-feather'
269
+ ),
270
+ ),
271
+ 'automatic_share_post_types' => array(
272
  'type' => 'custom',
273
  'default' => 'post',
274
+ 'set' => synved_option_callback(
275
+ 'synved_social_automatic_append_post_types_set',
276
+ array( 'post', 'page' )
277
+ ),
278
  'label' => __( 'Share Post Types', 'social-media-feather' ),
279
+ 'tip' => __(
280
+ 'Post types for which automatic appending for share buttons should be attempted (CTRL + click to select multiple ones)',
281
+ 'social-media-feather'
282
+ ),
283
  'render' => 'synved_social_automatic_append_post_types_render',
284
+ ),
285
+ 'automatic_share_prefix' => array(
286
  'default' => '',
287
  'label' => __( 'Share Prefix Markup', 'social-media-feather' ),
288
+ 'tip' => __(
289
+ 'When automatically appending, place this markup before the share buttons markup',
290
+ 'social-media-feather'
291
+ ),
292
+ ),
293
+ 'automatic_share_postfix' => array(
294
  'default' => '',
295
  'label' => __( 'Share Postfix Markup', 'social-media-feather' ),
296
+ 'tip' => __(
297
+ 'When automatically appending, place this markup after all of the share buttons markup',
298
+ 'social-media-feather'
299
+ ),
300
+ ),
301
+ 'automatic_follow' => array(
302
+ 'default' => true,
303
  'label' => __( 'Display Follow Buttons', 'social-media-feather' ),
304
+ 'tip' => __(
305
+ 'Tries to automatically append follow buttons to your posts (disable for specific posts by setting custom field synved_social_exclude or synved_social_exclude_follow to "yes", case sensitive)',
306
+ 'social-media-feather'
307
+ ),
308
+ ),
309
+ 'automatic_follow_position' => array(
310
  'default' => 'after_post',
311
  'set' => 'after_post=After Post,before_post=Before Post,after_before_post=After and Before Post',
312
  'label' => __( 'Follow Buttons Position', 'social-media-feather' ),
313
+ 'tip' => __(
314
+ 'Select where the follow buttons should be placed. Note: placing buttons Before Post might not work in all themes.',
315
+ 'social-media-feather'
316
+ ),
317
+ ),
318
+ 'automatic_follow_single' => array(
319
  'default' => false,
320
  'label' => __( 'Follow Single Posts', 'social-media-feather' ),
321
+ 'tip' => __(
322
+ 'Follow buttons are only displayed on single posts/pages and not on archive pages like blog/category/tag/author pages',
323
+ 'social-media-feather'
324
+ ),
325
+ ),
326
+ 'automatic_follow_post_types' => array(
327
  'type' => 'custom',
328
  'default' => 'post',
329
+ 'set' => synved_option_callback(
330
+ 'synved_social_automatic_append_post_types_set',
331
+ array( 'post', 'page' )
332
+ ),
333
  'label' => __( 'Follow Post Types', 'social-media-feather' ),
334
+ 'tip' => __(
335
+ 'Post types for which automatic appending for follow buttons should be attempted (CTRL + click to select multiple ones)',
336
+ 'social-media-feather'
337
+ ),
338
  'render' => 'synved_social_automatic_append_post_types_render',
339
+ ),
340
+ 'automatic_follow_before_share' => array(
341
  'default' => false,
342
  'label' => __( 'Follow Before Share', 'social-media-feather' ),
343
+ 'tip' => __(
344
+ 'When automatically appending, place follow buttons before share buttons. Only valid when share and follow buttons positions are the same.',
345
+ 'social-media-feather'
346
+ ),
347
+ ),
348
+ 'automatic_follow_prefix' => array(
349
  'default' => '',
350
  'label' => __( 'Follow Prefix Markup', 'social-media-feather' ),
351
+ 'tip' => __(
352
+ 'When automatically appending, place this markup before the follow buttons markup',
353
+ 'social-media-feather'
354
+ ),
355
+ ),
356
+ 'automatic_follow_postfix' => array(
357
  'default' => '',
358
  'label' => __( 'Follow Postfix Markup', 'social-media-feather' ),
359
+ 'tip' => __(
360
+ 'When automatically appending, place this markup after all of the follow buttons markup',
361
+ 'social-media-feather'
362
+ ),
363
+ ),
364
+ 'automatic_append_prefix' => array(
365
  'default' => '',
366
  'label' => __( 'Prefix Markup', 'social-media-feather' ),
367
+ 'tip' => __(
368
+ 'When automatically appending, place this markup before the buttons markup',
369
+ 'social-media-feather'
370
+ ),
371
+ ),
372
+ 'automatic_append_separator' => array(
373
  'default' => '<br/>',
374
  'label' => __( 'Separator Markup', 'social-media-feather' ),
375
+ 'tip' => __(
376
+ 'When automatically appending both, use this markup as separator between the set of share buttons and the set of follow buttons. Only valid when share and follow buttons positions are the same.',
377
+ 'social-media-feather'
378
+ ),
379
+ ),
380
+ 'automatic_append_postfix' => array(
381
  'default' => '',
382
  'label' => __( 'Postfix Markup', 'social-media-feather' ),
383
+ 'tip' => __(
384
+ 'When automatically appending, place this markup after all of the buttons markup',
385
+ 'social-media-feather'
386
+ ),
387
+ ),
388
+ ),
389
+ ),
390
+ 'section_customize_look' => array(
391
  'label' => __( 'Customize Look', 'social-media-feather' ),
392
+ 'tip' => synved_option_callback(
393
+ 'synved_social_section_customize_look_tip',
394
+ __( 'Customize the look & feel of Social Media Feather', 'social-media-feather' )
395
+ ),
396
+ 'settings' => array(
397
+ 'icon_skin' => array(
398
  'default' => 'regular',
399
  'set' => synved_option_callback( 'synved_social_cb_icon_skin_set', 'regular=Regular' ),
400
  'label' => __( 'Icon Skin', 'social-media-feather' ),
401
  'tip' => '',
402
  'render' => 'synved_social_icon_skin_render',
403
+ ),
404
+ 'icon_size' => array(
405
  'default' => 48,
406
  'set' => '16=16x16,24=24x24,32=32x32,48=48x48,64=64x64,96=96x96',
407
  'label' => __( 'Icon Size', 'social-media-feather' ),
408
+ 'tip' => __(
409
+ 'Select the size in pixels for the icons. Note: for high resolution displays like Retina the maximum size is 64x64.',
410
+ 'social-media-feather'
411
+ ),
412
+ ),
413
+ 'icon_resolution' => array(
414
  'default' => 'single',
415
  'set' => 'single=Single,double=Double',
416
  'label' => __( 'Icon Resolution', 'social-media-feather' ),
417
+ 'tip' => __(
418
+ 'Select what icon resolutions will be used. Single might make the icons slightly blurry on low resolution displays. Double will always look the best but will consume more bandwidth.',
419
+ 'social-media-feather'
420
+ ),
421
+ ),
422
+ 'icon_spacing' => array(
423
  'default' => 5,
424
  'label' => __( 'Icon Spacing', 'social-media-feather' ),
425
  'tip' => __( 'Select the spacing in pixels between the icons', 'social-media-feather' ),
426
+ ),
427
+ 'buttons_container' => array(
428
  'default' => 'none',
429
  'set' => 'none=None,share=Sharing Buttons,follow=Following Buttons,both=Both',
430
  'label' => __( 'Buttons in Container', 'social-media-feather' ),
431
+ 'tip' => __(
432
+ 'Determines whether or not to wrap the buttons in a container, which will affect how the buttons are rendered, based on the "Buttons Container Type" setting.',
433
+ 'social-media-feather'
434
+ ),
435
+ ),
436
+ 'buttons_container_type' => array(
437
  'default' => 'basic',
438
  'set' => 'basic=Basic,block=Block',
439
  'label' => __( 'Buttons Container Type', 'social-media-feather' ),
440
+ 'tip' => __(
441
+ '"Basic" should not affect rendering, while "Block" should display the buttons in their own row. <b>Note</b>: selecting "Block" might not look the way you want if you\'re using Prefix or Postfix markup.',
442
+ 'social-media-feather'
443
+ ),
444
+ ),
445
+ 'buttons_alignment_share' => array(
446
  'default' => 'none',
447
  'set' => 'none=Theme Default,left=Align Left,right=Align Right,center=Align Center',
448
  'label' => __( 'Share Buttons Alignment', 'social-media-feather' ),
449
+ 'tip' => __(
450
+ 'Will attempt at aligning the share buttons accordingly. <strong>Note:</strong> this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes',
451
+ 'social-media-feather'
452
+ ),
453
+ ),
454
+ 'buttons_alignment_follow' => array(
455
  'default' => 'none',
456
  'set' => 'none=Theme Default,left=Align Left,right=Align Right,center=Align Center',
457
  'label' => __( 'Follow Buttons Alignment', 'social-media-feather' ),
458
+ 'tip' => __(
459
+ 'Will attempt at aligning the follow buttons accordingly. <strong>Note:</strong> this will enforce "Buttons Container Type" of "Block" and might not work reliably on all themes',
460
+ 'social-media-feather'
461
+ ),
462
+ ),
463
+ 'custom_style' => array(
464
  'type' => 'style',
465
  'label' => __( 'Extra Styles', 'social-media-feather' ),
466
+ 'tip' => __(
467
+ 'Any CSS styling code you type in here will be loaded after all of the Social Media Feather styles.',
468
+ 'social-media-feather'
469
+ ),
470
+ ),
471
+ ),
472
+ ),
473
+ 'section_service_providers' => array(
474
  'label' => __( 'Service Providers', 'social-media-feather' ),
475
  'tip' => __( 'Customize social sharing and following providers', 'social-media-feather' ),
476
  'settings' => synved_social_provider_settings(),
477
+ ),
478
+ ),
479
+ ),
480
+ );
481
 
482
  synved_option_register( 'synved_social', $synved_social_options );
483
 
484
  synved_option_include_module_addon_list( 'synved-social' );
485
 
486
+ /**
487
+ * Accept terms switch.
488
+ *
489
+ * @return string
490
+ */
491
  function synved_social_accept_terms_switch() {
 
492
  $out = '<label class="synved-switch">
493
+ <input id="synved-disable" name="synved_social_settings[accepted_sharethis_terms]"
494
+ type="checkbox" value="' . esc_attr( true === synved_social_are_terms_accepted() ? 1 : 0 ) . '">
495
+ <div id="synved-slider" class="synved-slider round"></div>
496
+ </label>';
497
 
498
+ return wp_kses( $out, synved_get_allowed_html_array() );
499
  }
500
 
501
  /**
502
  * Synved Social Page Settings tip.
503
  *
504
+ * @param string $tip Tip string.
505
+ * @param array $item Item array.
506
  *
507
  * @return string
508
  */
511
 
512
  $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
513
 
514
+ if ( preg_match( '/page=social-media-feather-settings/i', $request_uri ) ) {
515
  $accept_terms = filter_input( INPUT_GET, 'accept-terms', FILTER_SANITIZE_STRING );
516
 
517
  // If terms have just been accepted.
529
  return $tip;
530
  }
531
 
532
+ /**
533
+ * Render fragment.
534
+ *
535
+ * @param string $fragment Fragment string.
536
+ * @param string $out Out string.
537
+ * @param array $params Parameter array.
538
+ *
539
+ * @return mixed|string
540
+ */
541
  function synved_social_page_render_fragment( $fragment, $out, $params ) {
542
+ if ( 'page-submit-tail' === $fragment ) {
543
  $out .= '<div style="clear:both; margin-top: -12px;"><a target="_blank" href="http://wordpress.org/support/view/plugin-reviews/social-media-feather?rate=5#postform" style="font-size:120%"><b>We need your help!</b> If you like the plugin, you can help us by leaving a 5-stars review! It only takes a minute and it\'s free!</a></div>';
544
  $out .= '<p>By using this plugin you are agreeing to the <a href="https://sharethis.com/terms/" target="_blank">Terms of service</a> and <a href="https://sharethis.com/privacy/" target="_blank">Privacy Policy</a>.</p>';
545
  }
546
 
547
+ $out .= '<div id="social-media-feather-app"></div>';
548
+
549
+ return wp_kses( $out, synved_get_allowed_html_array() );
550
  }
551
 
552
+ /**
553
+ * Customize look tip.
554
+ *
555
+ * @param string $tip Tip string.
556
+ * @param array $item Item array.
557
+ *
558
+ * @return mixed
559
+ */
560
  function synved_social_section_customize_look_tip( $tip, $item ) {
561
+ return wp_kses( $tip, synved_get_allowed_html_array() );
562
  }
563
 
564
+ /**
565
+ * Icon skin set callback.
566
+ *
567
+ * @param array|null $set Set array.
568
+ * @param array $item Item array.
569
+ *
570
+ * @return array
571
+ */
572
  function synved_social_cb_icon_skin_set( $set, $item ) {
573
+ if ( false === empty( $set ) && false === is_array( $set ) ) {
574
  $set = synved_option_item_set_parse( $item, $set );
575
  }
576
 
577
+ $set = array();
578
  $icons = synved_social_icon_skin_list();
579
 
580
  foreach ( $icons as $icon_name => $icon_meta ) {
584
  return $set;
585
  }
586
 
587
+ /**
588
+ * Icon skin render.
589
+ *
590
+ * @param string $value Value string.
591
+ * @param array $params Parameter array.
592
+ * @param string $id ID string.
593
+ * @param string $name Name string.
594
+ * @param array $item Item array.
595
+ *
596
+ * @return string
597
+ */
598
  function synved_social_icon_skin_render( $value, $params, $id, $name, $item ) {
599
  $uri = synved_social_path_uri();
600
  $icons = synved_social_icon_skin_list();
609
 
610
  foreach ( $set as $set_it ) {
611
  $set_it_keys = array_keys( $set_it );
 
612
  $img_src = '';
613
 
614
  if ( isset( $icons[ $set_it_keys[0] ] ) ) {
615
  $img_src = $icons[ $set_it_keys[0] ]['image'];
616
  }
617
 
618
+ $disabled = disabled(
619
+ false === $sharethis_terms_agree
620
+ && false === empty( $icons[ $set_it_keys[0] ]['extra'] ),
621
+ true,
622
+ false
623
+ );
624
 
625
+ $out .= '<div style="text-align:center; width:260px; float:left; margin-right:20px; margin-bottom: 15px;">
626
+ <label title="Use skin=&quot;'
627
+ . esc_attr( $set_it_keys[0] )
628
+ . '&quot; in shortcodes"><img src="'
629
+ . esc_url( $img_src )
630
+ . '" style="border:solid 1px #bbb" /><p><input type="radio" name="'
631
+ . esc_attr( $out_name )
632
+ . '" value="'
633
+ . esc_attr( $set_it_keys[0] )
634
+ . '"'
635
+ . checked( $set_it_keys[0] === $value, true, false )
636
+ . ' '
637
+ . $disabled . '/> '
638
+ . esc_html( $set_it[ $set_it_keys[0] ] )
639
+ . '</p></label></div>';
640
  }
641
 
642
  $out .= '</div>';
643
 
644
+ return wp_kses( $out, synved_get_allowed_html_array() );
645
  }
646
 
647
+ /**
648
+ * Automatic append post types set.
649
+ *
650
+ * @param array $set Set array.
651
+ * @param array $item Item array.
652
+ *
653
+ * @return array
654
+ */
655
  function synved_social_automatic_append_post_types_set( $set, $item ) {
656
+ if ( false === empty( $set ) && false === is_array( $set ) ) {
657
  $set = synved_option_item_set_parse( $item, $set );
658
  }
659
 
660
+ $set = array();
661
+ $types = get_post_types( array( 'public' => true ) );
662
 
663
  foreach ( $types as $type_name ) {
664
  $set[][ $type_name ] = $type_name;
667
  return $set;
668
  }
669
 
670
+ /**
671
+ * Automatic append post types render.
672
+ *
673
+ * @param array $value Value array.
674
+ * @param array $params Parameter array.
675
+ * @param string $id ID string.
676
+ * @param string $name Name string.
677
+ * @param array $item Item array.
678
+ *
679
+ * @return string
680
+ */
681
  function synved_social_automatic_append_post_types_render( $value, $params, $id, $name, $item ) {
682
  $uri = synved_social_path_uri();
683
  $icons = synved_social_icon_skin_list();
684
 
685
+ if ( false === is_array( $value ) ) {
686
+ if ( false === empty( $value ) ) {
687
+ $value = array( $value );
688
  } else {
689
+ $value = array();
690
  }
691
  }
692
 
698
 
699
  foreach ( $set as $set_it ) {
700
  $set_it_keys = array_keys( $set_it );
 
701
 
702
+ $out .= '<option value="'
703
+ . esc_attr( $set_it_keys[0] )
704
+ . '"'
705
+ . selected( in_array( $set_it_keys[0], $value, true ), true, false )
706
+ . '>'
707
+ . esc_html( $set_it[ $set_it_keys[0] ] )
708
+ . '</option>';
709
  }
710
 
711
  $out .= '</select>';
712
 
713
+ return wp_kses( $out, synved_get_allowed_html_array() );
714
  }
715
 
716
+ /**
717
+ * Social path.
718
+ *
719
+ * @param string|null $path Path string.
720
+ *
721
+ * @return array|string|string[]
722
+ */
723
  function synved_social_path( $path = null ) {
724
  $root = dirname( __FILE__ );
725
 
726
+ if ( false === empty( $root ) ) {
727
+ if ( '/' !== substr( $root, - 1 ) && true === isset( $path, $path[0] ) && '/' !== $path[0] ) {
728
  $root .= '/';
729
  }
730
 
731
  $root .= $path;
732
  }
733
 
734
+ $root = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $root );
735
 
736
  return $root;
737
  }
738
 
739
+ /**
740
+ * Path URI.
741
+ *
742
+ * @param string|null $path Path string.
743
+ *
744
+ * @return string
745
+ */
746
  function synved_social_path_uri( $path = null ) {
747
  $uri = plugins_url( '/social-media-feather' ) . '/synved-social';
748
 
749
  if ( function_exists( 'synved_plugout_module_uri_get' ) ) {
750
  $mod_uri = synved_plugout_module_uri_get( 'synved-social' );
751
 
752
+ if ( false === empty( $mod_uri ) ) {
753
  $uri = $mod_uri;
754
  }
755
  }
756
 
757
+ if ( false === empty( $path ) ) {
758
+ if ( '/' !== substr( $uri, - 1 ) && '/' !== $path[0] ) {
759
  $uri .= '/';
760
  }
761
 
765
  return $uri;
766
  }
767
 
768
+ /**
769
+ * WP Script Loader Tag.
770
+ *
771
+ * @param string $tag Tag string.
772
+ * @param string $handle Handle string.
773
+ *
774
+ * @return array|mixed|string|string[]
775
+ */
776
  function synved_social_wp_script_loader_tag( $tag, $handle ) {
777
  if ( 'feather-sharethis' === $handle ) {
778
  return str_replace( '<script', '<script id=\'st_insights_js\'', $tag );
781
  return $tag;
782
  }
783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
784
  /**
785
  * Are terms accepted?
786
  *
790
  return synved_option_get( 'synved_social', 'accepted_sharethis_terms', false );
791
  }
792
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  /**
794
  * Admin enqueue scripts for Social.
795
  *
802
  wp_enqueue_script(
803
  'synved-option-script-custom',
804
  $uri . '/script/custom.js',
805
+ array(
806
  'jquery',
807
+ ),
808
+ filemtime( $dir . '/script/custom.js' ),
809
+ false
810
  );
811
  }
812
 
813
+ /**
814
+ * Register widgets.
815
+ *
816
+ * @return void
817
+ */
818
  function synved_social_register_widgets() {
819
  register_widget( 'SynvedSocialShareWidget' );
820
  register_widget( 'SynvedSocialFollowWidget' );
821
  }
822
 
823
+ /**
824
+ * WP: the_content.
825
+ *
826
+ * @param string $content Post content string.
827
+ * @param string|null $id ID string.
828
+ *
829
+ * @return mixed|string
830
+ */
831
  function synved_social_wp_the_content( $content, $id = null ) {
832
  $exclude = false;
833
  $exclude_share = false;
838
  $separator_after = null;
839
  $separator_before = null;
840
 
841
+ if ( true === empty( $id ) ) {
842
  $id = get_the_ID();
843
 
844
+ if ( true === empty( $id ) ) {
845
  global $post;
846
 
847
  $id = $post->ID;
848
  }
849
  }
850
 
851
+ if ( false === empty( $id ) ) {
852
+ $exclude = 'yes' === get_post_meta( $id, 'synved_social_exclude', true );
853
+ $exclude_share = 'yes' === get_post_meta( $id, 'synved_social_exclude_share', true );
854
+ $exclude_follow = 'yes' === get_post_meta( $id, 'synved_social_exclude_follow', true );
855
+
856
+ if ( false === $exclude_share
857
+ && false !== synved_option_get( 'synved_social', 'automatic_share_single', false )
858
+ ) {
859
+ $exclude_share = false === (
860
+ true === is_singular( synved_option_get( 'synved_social', 'automatic_share_post_types' ) )
861
+ && (
862
+ true === is_single( $id ) || true === is_page( $id )
863
+ )
864
+ );
865
  }
866
 
867
+ if ( false === $exclude_follow &&
868
+ false !== synved_option_get( 'synved_social', 'automatic_follow_single', false )
869
+ ) {
870
+ $exclude_follow = false === (
871
+ true === is_singular( synved_option_get( 'synved_social', 'automatic_follow_post_types' ) )
872
+ && (
873
+ true === is_single( $id ) || true === is_page( $id )
874
+ )
875
+ );
876
  }
877
  }
878
 
879
+ if ( false === $exclude ) {
880
+ if ( false === $exclude_share
881
+ && false !== synved_option_get( 'synved_social', 'automatic_share', false )
882
+ ) {
883
  $post_type = get_post_type();
884
  $type_list = synved_option_get( 'synved_social', 'automatic_share_post_types' );
885
 
886
  if ( true === is_string( $type_list ) ) {
887
+ $type_list = array( $type_list );
888
  }
889
 
890
+ if ( true === in_array( $post_type, $type_list, true ) ) {
891
  $position = synved_option_get( 'synved_social', 'automatic_share_position' );
892
+ $position_before = true === in_array( $position, array( 'before_post', 'after_before_post' ), true );
893
+ $position_after = true === in_array( $position, array( 'after_post', 'after_before_post' ), true );
894
  $prefix = synved_option_get( 'synved_social', 'automatic_share_prefix' );
895
  $postfix = synved_option_get( 'synved_social', 'automatic_share_postfix' );
896
 
897
  if ( $position_after ) {
898
  $markup = synved_social_share_markup();
899
 
900
+ if ( false === empty( trim( $markup ) ) ) {
901
  $markup = $prefix . $markup . $postfix;
902
 
903
  $extra_after .= $markup;
904
  }
905
  }
906
 
907
+ if ( true === $position_before ) {
908
  $markup = synved_social_share_markup();
909
 
910
+ if ( false === empty( trim( $markup ) ) ) {
911
  $markup = $prefix . $markup . $postfix;
912
 
913
  $extra_before .= $markup;
918
 
919
  $separator = synved_option_get( 'synved_social', 'automatic_append_separator' );
920
 
921
+ if ( false === empty( $extra_after ) ) {
922
  $separator_after = $separator;
923
  }
924
 
925
+ if ( false === empty( $extra_before ) ) {
926
  $separator_before = $separator;
927
  }
928
 
929
+ if ( false === $exclude_follow
930
+ && false !== synved_option_get( 'synved_social', 'automatic_follow', false )
931
+ ) {
932
  $post_type = get_post_type();
933
+ $type_list = synved_option_get( 'synved_social', 'automatic_follow_post_types', array() );
934
 
935
+ if ( false === is_array( $type_list ) ) {
936
+ $type_list = array();
937
+ }
938
+
939
+ if ( true === in_array( $post_type, $type_list, true ) ) {
940
  $position = synved_option_get( 'synved_social', 'automatic_follow_position' );
941
+ $position_before = true === in_array( $position, array( 'before_post', 'after_before_post' ), true );
942
+ $position_after = true === in_array( $position, array( 'after_post', 'after_before_post' ), true );
943
  $prefix = synved_option_get( 'synved_social', 'automatic_follow_prefix' );
944
  $postfix = synved_option_get( 'synved_social', 'automatic_follow_postfix' );
945
 
946
+ if ( true === $position_after ) {
947
  $markup = synved_social_follow_markup();
948
 
949
+ if ( false === empty( trim( $markup ) ) ) {
950
  $markup = $prefix . $markup . $postfix;
951
 
952
+ if ( false !== synved_option_get( 'synved_social', 'automatic_follow_before_share', false ) ) {
953
  $extra_after = $markup . $separator_after . $extra_after;
954
  } else {
955
  $extra_after .= $separator_after . $markup;
960
  if ( $position_before ) {
961
  $markup = synved_social_follow_markup();
962
 
963
+ if ( false === empty( trim( $markup ) ) ) {
964
  $markup = $prefix . $markup . $postfix;
965
 
966
+ if ( false !== synved_option_get( 'synved_social', 'automatic_follow_before_share', false ) ) {
967
  $extra_before = $markup . $separator_before . $extra_before;
968
  } else {
969
  $extra_before .= $separator_before . $markup;
976
  $prefix = synved_option_get( 'synved_social', 'automatic_append_prefix' );
977
  $postfix = synved_option_get( 'synved_social', 'automatic_append_postfix' );
978
 
979
+ if ( false === empty( $extra_after ) ) {
980
  $content .= $prefix . $extra_after . $postfix;
981
  }
982
 
983
+ if ( false === empty( $extra_before ) ) {
984
  $content = $prefix . $extra_before . $postfix . $content;
985
  }
986
  }
991
  /**
992
  * Renders ShareThis Terms of Service alert.
993
  *
994
+ * @param bool $render_html Render HTML.
995
+ * @param bool $is_dismissible Whether the notice is dismissable.
996
  *
997
  * @return string
998
  */
999
+ function synved_social_sharethis_terms_notice( $render_html = true, $is_dismissible = true ) {
1000
+ $out = '<div id="sharethis_terms_notice" class="notice-warning notice ' . esc_attr( false === empty( $is_dismissible ) ? 'is-dismissible' : '' ) . '">
1001
  <p>
1002
  To get the most out of Social Media Feather and to help enable its continued development,
1003
  please read the <a href="//sharethis.com/terms" target="_blank">ShareThis Terms of Service</a> and <a href="//sharethis.com/privacy" target="_blank">Privacy Notice</a>,
1004
+ then <a href="' . esc_url( admin_url( 'options-general.php?page=social-media-feather-settings&accept-terms=yes' ) ) . '">click here to accept the terms</a>.
1005
  </p>
1006
  </div>
1007
  ';
1008
 
1009
  if ( $render_html ) {
1010
+ echo wp_kses( $out, synved_get_allowed_html_array() );
1011
  } else {
1012
+ return wp_kses( $out, synved_get_allowed_html_array() );
1013
  }
 
1014
  }
1015
 
1016
  /**
1020
  synved_social_sharethis_terms_notice( true, true );
1021
  }
1022
 
1023
+ /**
1024
+ * Hide the terms agreement at user's request?
1025
+ *
1026
+ * @return void
1027
+ */
1028
  function synved_social_admin_hide_callback() {
1029
  synved_option_set( 'synved_social', 'hide_sharethis_terms', true );
1030
  }
1031
 
1032
+ /**
1033
+ * Init.
1034
+ *
1035
+ * @return void
1036
+ */
1037
  function synved_social_init() {
1038
  $priority = defined( 'SHORTCODE_PRIORITY' ) ? SHORTCODE_PRIORITY : 11;
1039
 
1040
+ if ( true === boolval( synved_option_get( 'synved_social', 'shortcode_widgets' ) ) ) {
1041
  remove_filter( 'widget_text', 'do_shortcode', $priority );
1042
  add_filter( 'widget_text', 'do_shortcode', $priority );
1043
  }
1044
 
1045
+ if ( true === function_exists( 'synved_shortcode_add' ) ) {
1046
  synved_shortcode_add( 'feather_share', 'synved_social_share_shortcode' );
1047
  synved_shortcode_add( 'feather_follow', 'synved_social_follow_shortcode' );
1048
 
1049
  $size_set = '16,24,32,48,64,96';
1050
  $size_item = synved_option_item( 'synved_social', 'icon_size' );
1051
 
1052
+ if ( false === empty( $size_item ) ) {
1053
  $item_set = synved_option_item_set( $size_item );
1054
 
1055
+ if ( false === empty( $item_set ) ) {
1056
+ $set_items = array();
1057
 
1058
  foreach ( $item_set as $set_item ) {
1059
  $item_keys = array_keys( $set_item );
1068
  $providers_share = array_keys( synved_social_service_provider_list( 'share' ) );
1069
  $providers_follow = array_keys( synved_social_service_provider_list( 'follow' ) );
1070
 
1071
+ $providers_params = array(
1072
+ /* translators: %1$s is the provider. %2$s are the possible values. */
1073
+ 'show' => __(
1074
+ 'Specify a comma-separated list of %1$s providers to show and their order, possible values are %2$s',
1075
+ 'social-media-feather'
1076
+ ),
1077
+ /* translators: %1$s is the provider. %2$s are the possible values. */
1078
+ 'hide' => __(
1079
+ 'Specify a comma-separated list of %1$s providers to hide, possible values are %2$s',
1080
+ 'social-media-feather'
1081
+ ),
1082
+ );
1083
 
1084
+ $common_params = array(
1085
  'skin' => __( 'Specify which skin to use for the icons', 'social-media-feather' ),
1086
+ 'size' => sprintf(
1087
+ /* translators: %s are the possible values of icons. */
1088
+ __(
1089
+ 'Specify the size for the icons, possible values are %s',
1090
+ 'social-media-feather'
1091
+ ),
1092
+ $size_set
1093
+ ),
1094
+ 'spacing' => __(
1095
+ 'Determines how much blank space there will be between the buttons, in pixels',
1096
+ 'social-media-feather'
1097
+ ),
1098
  'container' => __( 'Determines whether to wrap the buttons in a container', 'social-media-feather' ),
1099
+ 'container_type' => sprintf(
1100
+ /* translators: %s are the possible values of container types. */
1101
+ __(
1102
+ 'Determines what type of container to use, possible values are %1$s',
1103
+ 'social-media-feather'
1104
+ ),
1105
+ 'basic, block'
1106
+ ),
1107
+ 'class' => __(
1108
+ 'Select additional CSS classes for the buttons, separated by spaces',
1109
+ 'social-media-feather'
1110
+ ),
1111
+ );
1112
+
1113
+ $share_params = array(
1114
+ 'url' => __(
1115
+ 'URL to use for the sharing buttons, default is the current post URL',
1116
+ 'social-media-feather'
1117
+ ),
1118
+ 'title' => __(
1119
+ 'Title to use for the sharing buttons, default is the current post title',
1120
+ 'social-media-feather'
1121
+ ),
1122
+ 'message' => __(
1123
+ 'Message to use when sharing content, replaced into the %%message%% variable',
1124
+ 'social-media-feather'
1125
+ ),
1126
+ );
1127
+
1128
+ $follow_params = array();
1129
 
1130
  $share_params = array_merge( $common_params, $share_params );
1131
  $follow_params = array_merge( $common_params, $follow_params );
1135
  $follow_params[ $param_name ] = sprintf( $param_value, 'follow', implode( ', ', $providers_follow ) );
1136
  }
1137
 
1138
+ if ( true === function_exists( 'synved_shortcode_item_help_set' ) ) {
1139
+ synved_shortcode_item_help_set(
1140
+ 'feather_share',
1141
+ array(
1142
+ 'tip' => __(
1143
+ 'Creates a list of buttons for social sharing as selected in the Social Media options',
1144
+ 'social-media-feather'
1145
+ ),
1146
+ 'parameters' => $share_params,
1147
+ )
1148
+ );
1149
+
1150
+ synved_shortcode_item_help_set(
1151
+ 'feather_follow',
1152
+ array(
1153
+ 'tip' => __(
1154
+ 'Creates a list of buttons for social following as selected in the Social Media options',
1155
+ 'social-media-feather'
1156
+ ),
1157
+ 'parameters' => $follow_params,
1158
+ )
1159
+ );
1160
+ }
1161
  } else {
1162
  add_shortcode( 'feather_share', 'synved_social_share_shortcode' );
1163
  add_shortcode( 'synved_feather_share', 'synved_social_share_shortcode' );
1165
  add_shortcode( 'synved_feather_follow', 'synved_social_follow_shortcode' );
1166
  }
1167
 
1168
+ if ( false !== synved_option_get( 'synved_social', 'automatic_share', false )
1169
+ || false !== synved_option_get( 'synved_social', 'automatic_follow', false )
1170
+ ) {
 
 
 
 
1171
  add_filter( 'the_content', 'synved_social_wp_the_content', 10, 2 );
1172
  }
1173
 
1174
+ if ( true === is_admin() ) {
1175
+ if ( true === current_user_can( 'manage_options' ) ) {
1176
  $accept_terms = filter_input( INPUT_GET, 'accept-terms', FILTER_SANITIZE_STRING );
1177
 
1178
  if ( false === empty( $accept_terms ) ) {
1179
  synved_option_set( 'synved_social', 'accepted_sharethis_terms', ( 'yes' === $accept_terms ) );
1180
+ wp_safe_redirect( admin_url( 'options-general.php?page=social-media-feather-settings' ) );
1181
+ exit;
1182
  }
1183
  }
1184
 
1185
  $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
1186
 
1187
+ $can_show_share_this_alert =
1188
+ false !== synved_option_get( 'synved_social', 'accepted_sharethis_terms', false )
1189
+ && false !== synved_option_get( 'synved_social', 'hide_sharethis_terms', false )
1190
+ && false === preg_match( '/page=social-media-feather-settings/i', $request_uri );
1191
+
1192
+ if ( true === $can_show_share_this_alert ) {
1193
  add_action( 'admin_notices', 'synved_social_sharethis_terms_notice_callback_admin_notice_wrapper' );
1194
  add_action( 'wp_ajax_feather_hide_terms', 'synved_social_admin_hide_callback' );
1195
  }
1200
 
1201
  add_action( 'widgets_init', 'synved_social_register_widgets' );
1202
 
1203
+ if ( true === is_admin() ) {
1204
  add_action( 'admin_enqueue_scripts', 'synved_social_admin_enqueue_scripts' );
1205
  }
synved-social/synved-social.php CHANGED
@@ -1,174 +1,181 @@
1
  <?php
2
- /*
3
- Module Name: Synved Social
4
- Description: Social sharing and following tools
5
- Author: Synved
6
- Version: 1.7.16
7
- Author URI: http://synved.com/
8
- License: GPLv2
9
-
10
- LEGAL STATEMENTS
11
-
12
- NO WARRANTY
13
- All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
14
-
15
- NO LIABILITY
16
- In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
17
- */
 
 
18
 
19
  define( 'SYNVED_SOCIAL_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
20
  define( 'SYNVED_SOCIAL_LOADED', true );
21
  define( 'SYNVED_SOCIAL_VERSION', 100070016 );
22
  define( 'SYNVED_SOCIAL_VERSION_STRING', '1.7.16' );
23
- define('SYNVED_SOCIAL_ADDON_PATH', str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, dirname(__FILE__) . '/addons'));
24
 
25
- $synved_social = [];
26
 
27
- include_once SYNVED_SOCIAL_PLUGIN_PATH . 'synved-social-setup.php';
28
- require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/SynvedSocialWidget.php';
29
- require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/SynvedSocialShareWidget.php';
30
- require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/SynvedSocialFollowWidget.php';
31
 
32
  /**
33
  * Get service provider list array.
34
  *
35
- * @param $context
36
- * @param $raw
37
  *
38
  * @return array
39
  */
40
- function synved_social_service_provider_list($context, $raw = false)
41
- {
42
- $provider_list = [];
43
 
44
- if ($context == 'share') {
45
- $provider_list = [
46
- 'facebook' => [
47
  'link' => 'https://www.facebook.com/sharer.php?u=%%url%%&t=%%title%%&s=100&p[url]=%%url%%&p[images][0]=%%image%%&p[title]=%%title%%',
48
- 'title' => __('Share on Facebook'),
49
- ],
50
- 'twitter' => [
51
  'link' => 'https://twitter.com/intent/tweet?url=%%url%%&text=%%message%%',
52
- 'title' => __('Share on Twitter'),
53
- ],
54
- 'reddit' => [
55
  'link' => 'https://www.reddit.com/submit?url=%%url%%&title=%%title%%',
56
- 'title' => __('Share on Reddit'),
57
- ],
58
- 'pinterest' => [
59
  'link' => 'https://pinterest.com/pin/create/button/?url=%%url%%&media=%%image%%&description=%%title%%',
60
- 'title' => __('Pin it with Pinterest'),
61
- ],
62
- 'linkedin' => [
63
  'link' => 'https://www.linkedin.com/shareArticle?mini=true&url=%%url%%&title=%%title%%',
64
- 'title' => __('Share on Linkedin'),
65
- ],
66
- 'tumblr' => [
67
  'link' => 'https://tumblr.com/share?s=&v=3&t=%%title%%&u=%%url%%',
68
- 'title' => __('Share on tumblr'),
69
  'default-display' => false,
70
- ],
71
- 'mail' => [
72
  'link' => 'mailto:?subject=%%title%%&body=%%message%%:%20%%url%%',
73
- 'title' => __('Share by email'),
74
- ],
75
- ];
76
- } elseif ($context == 'follow') {
77
- $provider_list = [
78
- 'facebook' => [
79
  'link' => 'https://www.facebook.com/facebook',
80
- 'title' => __('Follow us on Facebook'),
81
- ],
82
- 'twitter' => [
83
  'link' => 'https://twitter.com/twitter',
84
- 'title' => __('Follow us on Twitter'),
85
- ],
86
- 'pinterest' => [
87
  'link' => 'https://pinterest.com/MyUserName/',
88
- 'title' => __('Our board on Pinterest'),
89
  'default-display' => false,
90
- ],
91
- 'linkedin' => [
92
  'link' => 'https://www.linkedin.com/in/yourid',
93
- 'title' => __('Find us on Linkedin'),
94
- ],
95
- 'rss' => [
96
  'label' => 'RSS',
97
  'link' => 'https://feeds.feedburner.com/MyFeedName',
98
- 'title' => __('Subscribe to our RSS Feed'),
99
- ],
100
- 'youtube' => [
101
  'link' => 'https://www.youtube.com/MyYouTubeName',
102
- 'title' => __('Find us on YouTube'),
103
- ],
104
- 'vimeo' => [
105
  'link' => 'https://vimeo.com/MyVimeoName',
106
- 'title' => __('Find us on vimeo'),
107
  'default-display' => false,
108
- ],
109
- 'tumblr' => [
110
  'link' => 'https://myname.tumblr.com',
111
- 'title' => __('Find us on tumblr'),
112
  'default-display' => false,
113
- ],
114
- 'instagram' => [
115
  'link' => 'https://instagram.com/myusername',
116
- 'title' => __('Check out our instagram feed'),
117
  'default-display' => false,
118
- ],
119
- 'flickr' => [
120
  'link' => 'https://www.flickr.com/photos/myusername/',
121
- 'title' => __('Check out our flickr feed'),
122
  'default-display' => false,
123
- ],
124
- 'foursquare' => [
125
  'link' => 'https://foursquare.com/myusername',
126
- 'title' => __('Check out our foursquare feed'),
127
  'default-display' => false,
128
- ],
129
- 'mail' => [
130
  'link' => 'mailto:mail@example.com?subject=Contact%20Request',
131
- 'title' => __('Contact Us'),
132
  'default-display' => false,
133
- ],
134
- ];
135
  }
136
 
137
  $return_list = $provider_list;
138
 
139
- if ($raw == false) {
140
  global $synved_social;
141
 
142
- $list_name = 'provider_list' . '_' . $context;
143
 
144
- if (!isset($synved_social[$list_name]) || $synved_social[$list_name] == null) {
145
- $return_list = [];
 
 
 
146
 
147
- foreach ($provider_list as $provider_name => $provider_item) {
148
- $display = synved_option_get('synved_social', $provider_name . '_display');
149
- $link = synved_option_get('synved_social', $provider_name . '_' . $context . '_link');
150
- $title = synved_option_get('synved_social', $provider_name . '_' . $context . '_title');
151
 
152
- if ($display === null || in_array($display, [$context, 'both'])) {
153
- if ($link != null) {
 
 
 
154
  $provider_item['link'] = $link;
155
  }
156
 
157
- if ($title != null) {
158
  $provider_item['title'] = $title;
159
  }
160
 
161
- $return_list[$provider_name] = $provider_item;
162
  }
163
  }
164
 
165
- $synved_social[$list_name] = $return_list;
166
  } else {
167
- $return_list = $synved_social[$list_name];
168
  }
169
  }
170
 
171
- return apply_filters('synved_social_service_provider_list', $return_list, $context, $raw);
172
  }
173
 
174
  /**
@@ -176,33 +183,32 @@ function synved_social_service_provider_list($context, $raw = false)
176
  *
177
  * @return array
178
  */
179
- function synved_social_icon_skin_list()
180
- {
181
  global $synved_social;
182
 
183
- if (!isset($synved_social['skin_list']) || $synved_social['skin_list'] == null) {
184
  $path = synved_social_path();
185
  $uri = synved_social_path_uri();
186
 
187
- $icons = [
188
- 'regular' => [
189
- 'label' => __('Regular'),
190
  'image' => $uri . '/image/social/regular/preview.png',
191
  'folder' => '/image/social/regular/',
192
  'path' => $path . '/image/social/regular/',
193
  'uri' => $uri . '/image/social/regular/',
194
- ],
195
- ];
196
 
197
- if (function_exists('synved_social_addon_extra_icons_get')) {
198
  $icons_extra = synved_social_addon_extra_icons_get();
199
- $icons = array_merge($icons, $icons_extra);
200
  }
201
 
202
- $icons = apply_filters('synved_social_icon_skin_list', $icons);
203
 
204
- foreach ($icons as $skin_name => $skin) {
205
- $icons[$skin_name]['name'] = $skin_name;
206
  }
207
 
208
  $synved_social['skin_list'] = $icons;
@@ -214,17 +220,16 @@ function synved_social_icon_skin_list()
214
  /**
215
  * Get icon skin.
216
  *
217
- * @param $name
218
  *
219
  * @return mixed|null
220
  */
221
- function synved_social_icon_skin_get($name = null)
222
- {
223
  $icons = synved_social_icon_skin_list();
224
 
225
- if ($name != null && !isset($icons[$name])) {
226
- foreach ($icons as $skin_name => $skin) {
227
- if (strtolower($name) == strtolower($skin['label'])) {
228
  $name = $skin_name;
229
 
230
  break;
@@ -232,17 +237,17 @@ function synved_social_icon_skin_get($name = null)
232
  }
233
  }
234
 
235
- if ($name == null || !isset($icons[$name])) {
236
- $selected = synved_option_get('synved_social', 'icon_skin');
237
 
238
  $name = $selected;
239
  }
240
 
241
- if (isset($icons[$name])) {
242
- return $icons[$name];
243
  }
244
 
245
- if (isset($icons['regular'])) {
246
  return $icons['regular'];
247
  }
248
 
@@ -252,59 +257,62 @@ function synved_social_icon_skin_get($name = null)
252
  /**
253
  * Get icon skin size list array.
254
  *
255
- * @param $skin
256
  *
257
  * @return array
258
  */
259
- function synved_social_icon_skin_get_size_list($skin)
260
- {
261
- if (isset($skin['size-list'])) {
262
  return $skin['size-list'];
263
  }
264
 
265
- if (isset($skin['name'])) {
266
- $skin_fresh = synved_social_icon_skin_get($skin['name']);
267
 
268
- if (isset($skin['path']) && isset($skin_fresh['path']) && $skin['path'] == $skin_fresh['path']) {
269
- if (isset($skin_fresh['size-list'])) {
 
 
 
 
270
  return $skin_fresh['size-list'];
271
  }
272
  }
273
  }
274
 
275
  $path = synved_social_path();
276
- $skin_path = isset($skin['path']) ? $skin['path'] : ($path . '/image/social/regular/');
277
 
278
- $sizes = glob($skin_path . '*', GLOB_ONLYDIR);
279
- $sizes = array_map('basename', $sizes);
280
- $size_list = [];
281
 
282
- foreach ($sizes as $size_dir) {
283
- $size_parts = explode('x', $size_dir);
284
- $size_width = (int)$size_parts[0];
285
 
286
- if ($size_width != null) {
287
  $size_list[] = $size_width;
288
  }
289
  }
290
 
291
- sort($size_list, SORT_NUMERIC);
292
 
293
- if (isset($skin['name'])) {
294
  global $synved_social;
295
 
296
  $name = $skin['name'];
297
 
298
- // ensure the global is set
299
  synved_social_icon_skin_list();
300
 
301
- if (isset($synved_social['skin_list']) && $synved_social['skin_list'] != null) {
302
- if (!isset($synved_social['skin_list'][$name])) {
303
- $synved_social['skin_list'][$name] = [];
304
  }
305
 
306
- foreach ($skin as $key => $value) {
307
- $synved_social['skin_list'][$name][$key] = $value;
308
  }
309
  }
310
  }
@@ -315,87 +323,90 @@ function synved_social_icon_skin_get_size_list($skin)
315
  /**
316
  * Get Icon Skin Image List array.
317
  *
318
- * @param $skin
319
- * @param $name_list
320
- * @param $forced_size
321
  *
322
  * @return array
323
  */
324
- function synved_social_icon_skin_get_image_list_raw($skin, $name_list, $forced_size = null)
325
- {
326
  $path = synved_social_path();
327
  $uri = synved_social_path_uri();
328
- $skin_default = synved_social_icon_skin_get('regular');
329
 
330
- $skin_default_path = isset($skin_default['path']) ? $skin_default['path'] : ($path . '/image/social/regular/');
331
- $skin_default_uri = isset($skin_default['uri']) ? $skin_default['uri'] : ($uri . '/image/social/regular/');
332
- $skin_sel_path = isset($skin['path']) ? $skin['path'] : ($path . '/image/social/regular/');
333
- $skin_sel_uri = isset($skin['uri']) ? $skin['uri'] : ($uri . '/image/social/regular/');
334
 
335
- $default_size_list = synved_social_icon_skin_get_size_list($skin_default);
336
- $sel_size_list = synved_social_icon_skin_get_size_list($skin);
337
 
338
- $skin_list = [
339
- [
340
  'path' => $skin_sel_path,
341
  'uri' => $skin_sel_uri,
342
  'list' => $sel_size_list,
343
- ],
344
- [
345
  'path' => $skin_default_path,
346
  'uri' => $skin_default_uri,
347
  'list' => $default_size_list,
348
- ],
349
- ];
350
 
351
- $image_list = [];
352
 
353
- foreach ($name_list as $name) {
354
- foreach ($skin_list as $skin) {
355
  $skin_path = $skin['path'];
356
  $skin_uri = $skin['uri'];
357
  $size_list = $skin['list'];
358
- $size_count = count($size_list);
359
 
360
- $image_size_list = [];
361
- $image_size_list_skipped = [];
362
 
363
- for ($i = 0; $i < $size_count; $i++) {
364
- $image_size = $size_list[$i];
365
  $image_sub = '/' . $name . '.png';
366
  $size_name = $image_size . 'x' . $image_size;
367
  $image_path = $skin_path . $size_name . $image_sub;
368
  $image_uri = $skin_uri . $size_name . $image_sub;
369
 
370
- if (true === file_exists($image_path)) {
371
- $image_size_meta = [
372
  'name' => $size_name,
373
  'sub' => $image_sub,
374
  'path' => $image_path,
375
  'uri' => $image_uri,
376
- ];
377
 
378
- foreach ($image_size_list_skipped as $image_size_skipped) {
379
- $image_size_list[$image_size_skipped] = $image_size_meta;
380
  }
381
 
382
- $image_size_skipped = [];
383
- $image_size_list[$image_size] = $image_size_meta;
384
 
385
- if ($forced_size != null && ($image_size > $forced_size || $i == $size_count - 1) && !isset($image_size_list[$forced_size])) {
386
- $image_size_list[$forced_size] = $image_size_meta;
 
 
 
 
387
  }
388
  } else {
389
  $image_size_skipped[] = $image_size;
390
  }
391
  }
392
 
393
- if ($image_size_list != null) {
394
  break;
395
  }
396
  }
397
 
398
- $image_list[$name] = $image_size_list;
399
  }
400
 
401
  return $image_list;
@@ -404,16 +415,15 @@ function synved_social_icon_skin_get_image_list_raw($skin, $name_list, $forced_s
404
  /**
405
  * Get filtered Icon skin image list array.
406
  *
407
- * @param $skin
408
- * @param $name_list
409
- * @param $forced_size
410
  *
411
- * @return array
412
  */
413
- function synved_social_icon_skin_get_image_list($skin, $name_list, $forced_size = null)
414
- {
415
- $image_list = synved_social_icon_skin_get_image_list_raw($skin, $name_list, $forced_size);
416
- $image_list = apply_filters('synved_social_skin_image_list', $image_list, $skin, $name_list, $forced_size);
417
 
418
  return $image_list;
419
  }
@@ -421,17 +431,21 @@ function synved_social_icon_skin_get_image_list($skin, $name_list, $forced_size
421
  /**
422
  * Get Button list shortcode HTML.
423
  *
424
- * @param $atts
425
- * @param $content
426
- * @param $code
427
- * @param $context
428
  *
429
  * @return string
430
  */
431
- function synved_social_button_list_shortcode($atts, $content = null, $code = '', $context = null)
432
- {
433
- $vars_def = ['url' => null, 'image' => null, 'title' => null, 'message' => null];
434
- $params_def = [
 
 
 
 
435
  'skin' => null,
436
  'size' => null,
437
  'spacing' => null,
@@ -444,19 +458,19 @@ function synved_social_button_list_shortcode($atts, $content = null, $code = '',
444
  'custom1' => null,
445
  'custom2' => null,
446
  'custom3' => null,
447
- ];
448
- $vars = shortcode_atts($vars_def, $atts, 'feather_' . $context);
449
- $params = shortcode_atts($params_def, $atts, 'feather_' . $context);
450
- $vars = array_filter($vars);
451
- $params = array_filter($params);
452
-
453
- $vars = apply_filters('synved_social_shortcode_variable_list', $vars, $context, $atts);
454
- $params = apply_filters('synved_social_shortcode_parameter_list', $params, $context, $atts);
455
-
456
- if ('share' === $context) {
457
- return synved_social_share_markup($vars, null, $params);
458
- } elseif ('follow' === $context) {
459
- return synved_social_follow_markup($vars, null, $params);
460
  }
461
 
462
  return '';
@@ -465,29 +479,27 @@ function synved_social_button_list_shortcode($atts, $content = null, $code = '',
465
  /**
466
  * Get Share shortcode HTML output.
467
  *
468
- * @param $atts
469
- * @param $content
470
- * @param $code
471
  *
472
  * @return string
473
  */
474
- function synved_social_share_shortcode($atts, $content = null, $code = '')
475
- {
476
- return synved_social_button_list_shortcode($atts, $content, $code, 'share');
477
  }
478
 
479
  /**
480
  * Get Follow shortcode HTML output.
481
  *
482
- * @param $atts
483
- * @param $content
484
- * @param $code
485
  *
486
  * @return string
487
  */
488
- function synved_social_follow_shortcode($atts, $content = null, $code = '')
489
- {
490
- return synved_social_button_list_shortcode($atts, $content, $code, 'follow');
491
  }
492
 
493
  /**
@@ -495,59 +507,63 @@ function synved_social_follow_shortcode($atts, $content = null, $code = '')
495
  *
496
  * Escaped via wp_kses_post.
497
  *
498
- * @param $out_item
499
  *
500
  * @return string
501
  */
502
- function synved_social_button_list_markup_item_out($out_item)
503
- {
504
  $out = null;
505
- $tag = isset($out_item['tag']) ? $out_item['tag'] : null;
506
- $content = isset($out_item['content']) ? $out_item['content'] : null;
507
- $list = isset($out_item['child-list']) ? $out_item['child-list'] : null;
508
 
509
- unset($out_item['tag']);
510
- unset($out_item['content']);
511
- unset($out_item['child-list']);
512
 
513
- if ($tag != null) {
514
  $out .= '<' . $tag;
515
 
516
- foreach ($out_item as $attr_name => $attr_value) {
517
- if ($attr_name != null && $attr_value !== null) {
518
- if (in_array($attr_name, ['href', 'src'])) {
519
- $attr_value = str_ireplace(['[', ']'], ['&#91;', '&#93;'], $attr_value);
520
- $attr_value = esc_url($attr_value);
521
  } else {
522
- $attr_value = esc_attr($attr_value);
523
  }
524
 
525
  $out .= ' ' . $attr_name . '="' . $attr_value . '"';
526
  }
527
  }
528
 
529
- if ($list != null || $content != null) {
530
  $out .= '>';
531
  } else {
532
  $out .= ' />';
533
  }
534
  }
535
 
536
- if ($list != null) {
537
- foreach ($list as $child) {
538
- $out .= synved_social_button_list_markup_item_out($child);
539
  }
540
  }
541
 
542
- if ($content != null) {
543
  $out .= $content;
544
  }
545
 
546
- if ($tag != null && ($list != null || $content != null)) {
 
 
 
 
 
547
  $out .= '</' . $tag . '>';
548
  }
549
 
550
- return wp_kses_post($out);
551
  }
552
 
553
  /**
@@ -555,92 +571,91 @@ function synved_social_button_list_markup_item_out($out_item)
555
  *
556
  * Escaped via wp_kses_post.
557
  *
558
- * @param $context
559
- * @param $vars
560
- * @param $buttons
561
- * @param $params
562
  *
563
  * @return string
564
  */
565
- function synved_social_button_list_markup($context, $vars = null, $buttons = null, $params = null)
566
- {
567
- $buttons_default = synved_social_service_provider_list($context);
568
 
569
- if ($buttons == null) {
570
  $buttons = $buttons_default;
571
  } else {
572
- $keys = array_keys($buttons);
573
 
574
- foreach ($keys as $key) {
575
- if ($buttons[$key] == null && isset($buttons_default[$key])) {
576
- $buttons[$key] = $buttons_default[$key];
577
  }
578
  }
579
  }
580
 
581
  $id = get_the_ID();
582
 
583
- if ($id == null) {
584
  global $post;
585
 
586
- if ($post != null) {
587
  $id = $post->ID;
588
  }
589
  }
590
 
591
- if (!isset($vars['url']) || !isset($vars['short_url'])) {
592
  $home_url = home_url();
593
- $req_uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING);
594
 
595
- $path = parse_url($home_url, PHP_URL_PATH);
596
- $path_len = strlen($path);
597
 
598
- if (strtolower(substr($req_uri, 0, $path_len)) == strtolower($path)) {
599
- $req_uri = substr($req_uri, $path_len);
600
  }
601
 
602
- $url = home_url($req_uri);
603
  $short_url = $url;
604
 
605
- if ($id != null && in_the_loop()) {
606
- $use_shortlinks = synved_option_get('synved_social', 'use_shortlinks');
607
- $url = get_permalink($id);
608
- $short_url = wp_get_shortlink($id);
609
 
610
- if ($short_url != null) {
611
- if ($use_shortlinks && function_exists('wp_get_shortlink')) {
612
  $url = $short_url;
613
  }
614
  } else {
615
  $short_url = $url;
616
  }
617
- } elseif (is_front_page()) {
618
  $url = $home_url;
619
  }
620
 
621
- if (!isset($vars['url'])) {
622
  $vars['url'] = $url;
623
  }
624
 
625
- if (!isset($vars['short_url'])) {
626
  $vars['short_url'] = $short_url;
627
  }
628
  }
629
 
630
- if (!isset($vars['image'])) {
631
  $image_src = null;
632
 
633
- if ($id != null) {
634
- $image_id = get_post_thumbnail_id($id);
635
 
636
- if ($image_id != null) {
637
- $src = wp_get_attachment_image_src($image_id, 'full');
638
  $image_src = $src[0];
639
  } else {
640
- $post = get_post($id);
641
- $match = null;
642
 
643
- if (preg_match('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $match) > 0) {
644
  $image_src = $match[1];
645
  }
646
  }
@@ -649,244 +664,247 @@ function synved_social_button_list_markup($context, $vars = null, $buttons = nul
649
  $vars['image'] = $image_src;
650
  }
651
 
652
- if (!isset($vars['title'])) {
653
  $title = get_the_title();
654
- // do this encoding to prevent non-tags things, like emoticons, from being stripped, i.e. <8
655
- $title = preg_replace('/\\<\\s*([^[:alpha:]\\/])/', '&lt;$1', $title);
656
- $vars['title'] = html_entity_decode(wp_strip_all_tags($title));
657
  }
658
 
659
- if (!isset($vars['message'])) {
660
- $message = synved_option_get('synved_social', 'share_message_default');
661
 
662
- if ($message == null) {
663
- $message = __('Hey check this out', 'social-media-feather');
664
  }
665
 
666
  $vars['message'] = $message;
667
  }
668
 
669
- if (!isset($vars['author_wp'])) {
670
- if ($id != null && in_the_loop()) {
671
  $author = get_the_author();
672
 
673
- if ($author != null) {
674
  $vars['author_wp'] = $author;
675
  }
676
  }
677
  }
678
 
679
- if (!isset($vars['author'])) {
680
- if ($id != null && in_the_loop()) {
681
- $author = get_the_author_meta('_synved_twitter_handle');
682
 
683
- if ($author == null) {
684
- $author = get_the_author_meta('twitter');
685
  }
686
 
687
- if ($author == null) {
688
  $author = get_the_author();
689
  }
690
 
691
- if ($author != null) {
692
  $vars['author'] = $author;
693
  }
694
  }
695
  }
696
 
697
- if (!isset($vars['date'])) {
698
- if ($id != null && in_the_loop()) {
699
- $date = get_the_date('', $id);
700
 
701
- if ($date != null) {
702
  $vars['date'] = $date;
703
  }
704
  }
705
  }
706
 
707
- if (isset($vars['url']) && !isset($vars['url_trimmed'])) {
708
- $url_trimmed = trim($vars['url']);
709
 
710
- while (substr($url_trimmed, -1) == '/') {
711
- $url_trimmed = substr($url_trimmed, 0, -1);
712
  }
713
 
714
- while (strtolower(substr($url_trimmed, -3)) == '%2f') {
715
- $url_trimmed = substr($url_trimmed, 0, -3);
716
  }
717
 
718
  $vars['url_trimmed'] = $url_trimmed;
719
  }
720
 
721
- if (isset($params['class']) && !is_array($params['class'])) {
722
- $class = explode(' ', $params['class']);
723
- $params['class'] = array_map('trim', $class);
724
  }
725
 
726
- if (isset($params['show']) && !is_array($params['show'])) {
727
- $show = explode(',', $params['show']);
728
- $params['show'] = array_map('trim', $show);
729
  }
730
 
731
- if (isset($params['hide']) && !is_array($params['hide'])) {
732
- $hide = explode(',', $params['hide']);
733
- $params['hide'] = array_map('trim', $hide);
734
  }
735
 
736
- $vars = apply_filters('synved_social_markup_variable_list', $vars, $context, $params);
737
- $params = apply_filters('synved_social_markup_parameter_list', $params, $context, $vars);
738
-
739
- if ($vars != null) {
740
- $vars = array_map('wp_kses_decode_entities', $vars);
741
- $vars = urlencode_deep($vars);
742
-
743
- // urlencode_deep converts space characters to + rather than %20 which messes things up
744
- $vars['message'] = str_ireplace('+', '%20', $vars['message']);
745
- $vars['title'] = str_ireplace('+', '%20', $vars['title']);
746
-
747
- // urlencode_deep tries to be smart and apostrophes (') to %19 not %27 and double quotes (") to their equivalent open/closed counterparts which doesn't work on most social networks sharings
748
- $vars['message'] = str_ireplace('%18', '%27', $vars['message']);
749
- $vars['title'] = str_ireplace('%18', '%27', $vars['title']);
750
- $vars['message'] = str_ireplace('%19', '%27', $vars['message']);
751
- $vars['title'] = str_ireplace('%19', '%27', $vars['title']);
752
- $vars['message'] = str_ireplace('%1c', '%22', $vars['message']);
753
- $vars['title'] = str_ireplace('%1c', '%22', $vars['title']);
754
- $vars['message'] = str_ireplace('%1d', '%22', $vars['message']);
755
- $vars['title'] = str_ireplace('%1d', '%22', $vars['title']);
756
  }
757
 
758
  $path = synved_social_path();
759
  $uri = synved_social_path_uri();
760
  $skin = synved_social_icon_skin_get();
761
 
762
- if (isset($params['skin'])) {
763
- $skin = synved_social_icon_skin_get($params['skin']);
764
  }
765
 
766
- $skin_path = isset($skin['path']) ? $skin['path'] : ($path . '/image/social/regular/');
767
- $skin_uri = isset($skin['uri']) ? $skin['uri'] : ($uri . '/image/social/regular/');
768
 
769
- $icon_size = synved_option_get('synved_social', 'icon_size');
770
  $size = 48;
771
 
772
- if ($icon_size != null) {
773
  $size = $icon_size;
774
  }
775
 
776
- if (isset($params['size'])) {
777
  $size = $params['size'];
778
 
779
- if (is_string($size)) {
780
- $size = strtolower($size);
781
- $size_parts = explode('x', $size);
782
- $size = (int)$size_parts[0];
783
  }
784
  }
785
 
786
- $icon_spacing = synved_option_get('synved_social', 'icon_spacing');
787
- $buttons_container = synved_option_get('synved_social', 'buttons_container');
788
- $buttons_container_type = synved_option_get('synved_social', 'buttons_container_type');
789
- $buttons_alignment = synved_option_get('synved_social', 'buttons_alignment_' . $context);
790
- $layout_rtl = synved_option_get('synved_social', 'layout_rtl');
791
  $spacing = 5;
792
  $container = 'none';
793
  $container_type = 'basic';
794
  $alignment = 'none';
795
 
796
- if ($icon_spacing != null) {
797
  $spacing = $icon_spacing;
798
  }
799
 
800
- if (isset($params['spacing'])) {
801
  $spacing = $params['spacing'];
802
  }
803
 
804
- if ($buttons_container != null) {
805
  $container = $buttons_container;
806
  }
807
 
808
- if ($buttons_container_type != null) {
809
  $container_type = $buttons_container_type;
810
  }
811
 
812
- if ($buttons_alignment != null) {
813
  $alignment = $buttons_alignment;
814
  }
815
 
816
- if (isset($params['alignment'])) {
817
  $alignment = $params['alignment'];
818
  }
819
 
820
- if ($alignment != 'none') {
821
- if ($container == 'none') {
822
  $container = $context;
823
- } elseif ($container != 'both' && $container != $context) {
824
  $container = 'both';
825
  }
826
  }
827
 
828
- // Allow parameters to override container after we decide a default based on selected alignment
829
- if (isset($params['container'])) {
830
  $container = $params['container'];
831
  }
832
 
833
- if ($alignment != 'none') {
834
  $container_type = 'block';
835
  }
836
 
837
- // Allow parameters to override container after we decide a default based on selected alignment
838
- if (isset($params['container_type'])) {
839
  $container_type = $params['container_type'];
840
  }
841
 
842
- $class = isset($params['class']) ? $params['class'] : null;
843
- $show = isset($params['show']) ? $params['show'] : null;
844
- $hide = isset($params['hide']) ? $params['hide'] : null;
845
 
846
- if ($show != null) {
847
- $button_list = [];
848
 
849
- foreach ($show as $button_key) {
850
- if (isset($buttons[$button_key])) {
851
- $button_list[$button_key] = $buttons[$button_key];
852
 
853
- unset($buttons[$button_key]);
854
  }
855
  }
856
 
857
- foreach ($buttons as $button_key => $button_item) {
858
- $button_list[$button_key] = $button_item;
859
  }
860
 
861
  $buttons = $button_list;
862
  }
863
 
864
- if ($hide != null) {
865
- foreach ($hide as $button_key) {
866
- if (isset($buttons[$button_key])) {
867
- unset($buttons[$button_key]);
868
  }
869
  }
870
  }
871
 
872
- $out_list = [];
873
- $out_params = [];
874
- $image_list = [];
875
- $icon_resolution = synved_option_get('synved_social', 'icon_resolution');
876
- $resolutions = ['normal' => $size, 'hidef' => $size * 2];
 
 
 
877
 
878
- if (true === is_feed()) {
879
  $icon_resolution = 'single';
880
  }
881
 
882
- if ($icon_resolution == 'single') {
883
- $resolutions = ['single' => $size * 2];
884
  }
885
 
886
- $button_keys = array_keys($buttons);
887
 
888
- foreach ($resolutions as $resolution_name => $resolution_size) {
889
- $image_list[$resolution_name] = synved_social_icon_skin_get_image_list(
890
  $skin,
891
  $button_keys,
892
  $resolution_size
@@ -894,88 +912,101 @@ function synved_social_button_list_markup($context, $vars = null, $buttons = nul
894
  }
895
 
896
  $index = 0;
897
- $count = count($buttons);
898
 
899
- foreach ($buttons as $button_key => $button_item) {
900
  $href = $button_item['link'];
901
  $title = $button_item['title'];
902
 
903
  $matches = null;
904
 
905
- if (preg_match_all('/%%(\\w+)%%/', $href, $matches, PREG_SET_ORDER) > 0) {
906
- foreach ($matches as $match) {
907
  $var_key = $match[1];
908
  $replace = null;
909
 
910
- if (isset($vars[$var_key])) {
911
- $replace = $vars[$var_key];
912
  }
913
 
914
- $href = str_replace($match[0], $replace, $href);
915
  }
916
  }
917
 
918
  $icon_sizes = $resolutions;
919
 
920
- foreach ($icon_sizes as $icon_def => $icon_size) {
921
- $image = $image_list[$icon_def][$button_key];
922
- $image_size = $image[$icon_size];
923
  $image_sub = $image_size['sub'];
924
  $image_path = $image_size['path'];
925
  $image_uri = $image_size['uri'];
926
 
927
- if (!file_exists($image_path)) {
928
- $size_list = array_keys($image);
929
- $image_path = apply_filters('synved_social_button_image_path', $image_path, $image_uri, $icon_size,
930
- $image_sub, $skin_path, $skin_uri, $size_list);
931
- $image_uri = apply_filters('synved_social_button_image_uri', $image_uri, $image_path, $icon_size,
932
- $image_sub, $skin_path, $skin_uri, $size_list);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
933
  }
934
 
935
- $style = 'margin:0;';
936
-
937
- if (true) {
938
- $style .= 'margin-bottom:' . $spacing . 'px;';
939
- }
940
 
941
- if ($index < $count - 1 || $layout_rtl) {
942
  $style .= 'margin-right:' . $spacing . 'px;';
943
  }
944
 
945
  $class_extra = null;
946
 
947
- if ($class != null) {
948
- $class_extra = ' ' . implode(' ', $class);
949
  }
950
 
951
- // don't use "nofancybox" because some plugins/themes interpret it as enabling fancybox
952
  $class_extra .= ' nolightbox';
953
 
954
- $out_button = [
955
  'tag' => 'a',
956
  'class' => 'synved-social-button synved-social-button-' . $context . ' synved-social-size-' . $size . ' synved-social-resolution-' . $icon_def . ' synved-social-provider-' . $button_key . $class_extra,
957
  'data-provider' => $button_key,
958
- 'target' => $button_key != 'mail' ? '_blank' : null,
959
  'rel' => 'nofollow',
960
  'title' => $title,
961
  'href' => $href,
962
- 'style' => 'font-size: 0px; width:' . $size . 'px;' . 'height:' . $size . 'px;' . $style,
963
- 'child-list' => [
964
- [
965
  'tag' => 'img',
966
- 'alt' => $button_key == 'facebook' ? 'Facebook' : $button_key,
967
  'title' => $title,
968
  'class' => 'synved-share-image synved-social-image synved-social-image-' . $context,
969
  'width' => $size,
970
  'height' => $size,
971
- 'style' => 'display: inline; width:' . $size . 'px;' . 'height:' . $size . 'px; margin: 0; padding: 0; border: none; box-shadow: none;',
972
  'src' => $image_uri,
973
- ],
974
- ],
975
- ];
976
 
977
- $out_list[$icon_def][$button_key] = $out_button;
978
- $out_params[$icon_def][$button_key] = ['icon-resolution' => $icon_def];
979
  }
980
 
981
  $index++;
@@ -983,70 +1014,78 @@ function synved_social_button_list_markup($context, $vars = null, $buttons = nul
983
 
984
  $out = null;
985
 
986
- if ($out_list != null) {
987
- foreach ($out_list as $def_key => $def_list) {
988
- $out_list[$def_key] = apply_filters('synved_social_button_list_markup', $def_list, $out_params[$def_key],
989
- $context, $vars, $params);
 
 
 
 
 
 
990
  }
991
  }
992
 
993
- if ($out_list != null) {
994
  $container_tag = 'span';
995
 
996
- if ($container_type == 'block') {
997
  $container_tag = 'div';
998
  }
999
 
1000
- if ($container != 'none' && ($container == 'both' || $container == $context)) {
1001
- $container_style = $alignment != 'none' ? ' style="text-align: ' . $alignment . '"' : null;
1002
 
1003
  $out .= '<' . $container_tag . ' class="synved-social-container synved-social-container-' . $context . '"' . $container_style . '>';
1004
  }
1005
 
1006
- foreach ($out_list as $def_list) {
1007
- foreach ($def_list as $out_item) {
1008
- $out .= synved_social_button_list_markup_item_out($out_item);
1009
  }
1010
  }
1011
 
1012
- if (synved_option_get('synved_social', 'show_credit')) {
1013
- $out .= '<a class="synved-social-credit" target="_blank" rel="nofollow" title="' . __('WordPress Social Media Feather',
1014
- 'social-media-feather') . '" href="http://synved.com/wordpress-social-media-feather/" style="color:#444; text-decoration:none; font-size:8px; margin-left:5px;vertical-align:10px;white-space:nowrap;"><span>' . __('by ',
1015
- 'social-media-feather') . '</span><img style="display: inline;margin:0;padding:0;width:16px;height:16px;" width="16" height="16" alt="feather" src="' . $uri . '/image/icon.png" /></a>';
 
 
 
 
1016
  }
1017
 
1018
- if ($container != 'none' && ($container == 'both' || $container == $context)) {
1019
  $out .= '</' . $container_tag . '>';
1020
  }
1021
  }
1022
 
1023
- return wp_kses_post($out);
1024
  }
1025
 
1026
  /**
1027
  * Share markup.
1028
  *
1029
- * @param $vars
1030
- * @param $buttons
1031
- * @param $params
1032
  *
1033
  * @return string
1034
  */
1035
- function synved_social_share_markup($vars = null, $buttons = null, $params = null)
1036
- {
1037
- return synved_social_button_list_markup('share', $vars, $buttons, $params);
1038
  }
1039
 
1040
  /**
1041
  * Follow markup.
1042
  *
1043
- * @param $vars
1044
- * @param $buttons
1045
- * @param $params
1046
  *
1047
  * @return string
1048
  */
1049
- function synved_social_follow_markup($vars = null, $buttons = null, $params = null)
1050
- {
1051
- return synved_social_button_list_markup('follow', $vars, $buttons, $params);
1052
  }
1
  <?php
2
+ /**
3
+ * Module Name: Synved Social
4
+ * Description: Social sharing and following tools
5
+ * Author: Synved
6
+ * Version: 1.7.16
7
+ * Author URI: http://synved.com/
8
+ * License: GPLv2
9
+ *
10
+ * LEGAL STATEMENTS
11
+ *
12
+ * NO WARRANTY
13
+ * All products, support, services, information and software are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of fitness for a particular purpose, and non-infringement.
14
+ *
15
+ * NO LIABILITY
16
+ * In no event shall Synved Ltd. be liable to you or any third party for any direct or indirect, special, incidental, or consequential damages in connection with or arising from errors, omissions, delays or other cause of action that may be attributed to your use of any product, support, services, information or software provided, including, but not limited to, lost profits or lost data, even if Synved Ltd. had been advised of the possibility of such damages.
17
+ *
18
+ * @package SocialMediaFeather
19
+ */
20
 
21
  define( 'SYNVED_SOCIAL_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
22
  define( 'SYNVED_SOCIAL_LOADED', true );
23
  define( 'SYNVED_SOCIAL_VERSION', 100070016 );
24
  define( 'SYNVED_SOCIAL_VERSION_STRING', '1.7.16' );
25
+ define( 'SYNVED_SOCIAL_ADDON_PATH', str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, dirname( __FILE__ ) . '/addons' ) );
26
 
27
+ $synved_social = array();
28
 
29
+ require_once SYNVED_SOCIAL_PLUGIN_PATH . 'synved-social-setup.php';
30
+ require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/class-synvedsocialwidget.php';
31
+ require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/class-synvedsocialsharewidget.php';
32
+ require_once SYNVED_SOCIAL_PLUGIN_PATH . 'inc/class-synvedsocialfollowwidget.php';
33
 
34
  /**
35
  * Get service provider list array.
36
  *
37
+ * @param string $context Context string.
38
+ * @param bool $raw Raw or not.
39
  *
40
  * @return array
41
  */
42
+ function synved_social_service_provider_list( $context, $raw = false ) {
43
+ $provider_list = array();
 
44
 
45
+ if ( 'share' === $context ) {
46
+ $provider_list = array(
47
+ 'facebook' => array(
48
  'link' => 'https://www.facebook.com/sharer.php?u=%%url%%&t=%%title%%&s=100&p[url]=%%url%%&p[images][0]=%%image%%&p[title]=%%title%%',
49
+ 'title' => __( 'Share on Facebook' ),
50
+ ),
51
+ 'twitter' => array(
52
  'link' => 'https://twitter.com/intent/tweet?url=%%url%%&text=%%message%%',
53
+ 'title' => __( 'Share on Twitter' ),
54
+ ),
55
+ 'reddit' => array(
56
  'link' => 'https://www.reddit.com/submit?url=%%url%%&title=%%title%%',
57
+ 'title' => __( 'Share on Reddit' ),
58
+ ),
59
+ 'pinterest' => array(
60
  'link' => 'https://pinterest.com/pin/create/button/?url=%%url%%&media=%%image%%&description=%%title%%',
61
+ 'title' => __( 'Pin it with Pinterest' ),
62
+ ),
63
+ 'linkedin' => array(
64
  'link' => 'https://www.linkedin.com/shareArticle?mini=true&url=%%url%%&title=%%title%%',
65
+ 'title' => __( 'Share on Linkedin' ),
66
+ ),
67
+ 'tumblr' => array(
68
  'link' => 'https://tumblr.com/share?s=&v=3&t=%%title%%&u=%%url%%',
69
+ 'title' => __( 'Share on tumblr' ),
70
  'default-display' => false,
71
+ ),
72
+ 'mail' => array(
73
  'link' => 'mailto:?subject=%%title%%&body=%%message%%:%20%%url%%',
74
+ 'title' => __( 'Share by email' ),
75
+ ),
76
+ );
77
+ } elseif ( 'follow' === $context ) {
78
+ $provider_list = array(
79
+ 'facebook' => array(
80
  'link' => 'https://www.facebook.com/facebook',
81
+ 'title' => __( 'Follow us on Facebook' ),
82
+ ),
83
+ 'twitter' => array(
84
  'link' => 'https://twitter.com/twitter',
85
+ 'title' => __( 'Follow us on Twitter' ),
86
+ ),
87
+ 'pinterest' => array(
88
  'link' => 'https://pinterest.com/MyUserName/',
89
+ 'title' => __( 'Our board on Pinterest' ),
90
  'default-display' => false,
91
+ ),
92
+ 'linkedin' => array(
93
  'link' => 'https://www.linkedin.com/in/yourid',
94
+ 'title' => __( 'Find us on Linkedin' ),
95
+ ),
96
+ 'rss' => array(
97
  'label' => 'RSS',
98
  'link' => 'https://feeds.feedburner.com/MyFeedName',
99
+ 'title' => __( 'Subscribe to our RSS Feed' ),
100
+ ),
101
+ 'youtube' => array(
102
  'link' => 'https://www.youtube.com/MyYouTubeName',
103
+ 'title' => __( 'Find us on YouTube' ),
104
+ ),
105
+ 'vimeo' => array(
106
  'link' => 'https://vimeo.com/MyVimeoName',
107
+ 'title' => __( 'Find us on vimeo' ),
108
  'default-display' => false,
109
+ ),
110
+ 'tumblr' => array(
111
  'link' => 'https://myname.tumblr.com',
112
+ 'title' => __( 'Find us on tumblr' ),
113
  'default-display' => false,
114
+ ),
115
+ 'instagram' => array(
116
  'link' => 'https://instagram.com/myusername',
117
+ 'title' => __( 'Check out our instagram feed' ),
118
  'default-display' => false,
119
+ ),
120
+ 'flickr' => array(
121
  'link' => 'https://www.flickr.com/photos/myusername/',
122
+ 'title' => __( 'Check out our flickr feed' ),
123
  'default-display' => false,
124
+ ),
125
+ 'foursquare' => array(
126
  'link' => 'https://foursquare.com/myusername',
127
+ 'title' => __( 'Check out our foursquare feed' ),
128
  'default-display' => false,
129
+ ),
130
+ 'mail' => array(
131
  'link' => 'mailto:mail@example.com?subject=Contact%20Request',
132
+ 'title' => __( 'Contact Us' ),
133
  'default-display' => false,
134
+ ),
135
+ );
136
  }
137
 
138
  $return_list = $provider_list;
139
 
140
+ if ( false === $raw ) {
141
  global $synved_social;
142
 
143
+ $list_name = 'provider_list_' . $context;
144
 
145
+ if (
146
+ false === isset( $synved_social[ $list_name ] )
147
+ || null === $synved_social[ $list_name ]
148
+ ) {
149
+ $return_list = array();
150
 
151
+ foreach ( $provider_list as $provider_name => $provider_item ) {
152
+ $display = synved_option_get( 'synved_social', $provider_name . '_display' );
153
+ $link = synved_option_get( 'synved_social', $provider_name . '_' . $context . '_link' );
154
+ $title = synved_option_get( 'synved_social', $provider_name . '_' . $context . '_title' );
155
 
156
+ if (
157
+ true === empty( $display )
158
+ || true === in_array( $display, array( $context, 'both' ), true )
159
+ ) {
160
+ if ( false === empty( $link ) ) {
161
  $provider_item['link'] = $link;
162
  }
163
 
164
+ if ( false === empty( $title ) ) {
165
  $provider_item['title'] = $title;
166
  }
167
 
168
+ $return_list[ $provider_name ] = $provider_item;
169
  }
170
  }
171
 
172
+ $synved_social[ $list_name ] = $return_list;
173
  } else {
174
+ $return_list = $synved_social[ $list_name ];
175
  }
176
  }
177
 
178
+ return apply_filters( 'synved_social_service_provider_list', $return_list, $context, $raw );
179
  }
180
 
181
  /**
183
  *
184
  * @return array
185
  */
186
+ function synved_social_icon_skin_list() {
 
187
  global $synved_social;
188
 
189
+ if ( true === empty( $synved_social['skin_list'] ) ) {
190
  $path = synved_social_path();
191
  $uri = synved_social_path_uri();
192
 
193
+ $icons = array(
194
+ 'regular' => array(
195
+ 'label' => __( 'Regular' ),
196
  'image' => $uri . '/image/social/regular/preview.png',
197
  'folder' => '/image/social/regular/',
198
  'path' => $path . '/image/social/regular/',
199
  'uri' => $uri . '/image/social/regular/',
200
+ ),
201
+ );
202
 
203
+ if ( function_exists( 'synved_social_addon_extra_icons_get' ) ) {
204
  $icons_extra = synved_social_addon_extra_icons_get();
205
+ $icons = array_merge( $icons, $icons_extra );
206
  }
207
 
208
+ $icons = apply_filters( 'synved_social_icon_skin_list', $icons );
209
 
210
+ foreach ( $icons as $skin_name => $skin ) {
211
+ $icons[ $skin_name ]['name'] = $skin_name;
212
  }
213
 
214
  $synved_social['skin_list'] = $icons;
220
  /**
221
  * Get icon skin.
222
  *
223
+ * @param string $name Name string.
224
  *
225
  * @return mixed|null
226
  */
227
+ function synved_social_icon_skin_get( $name = null ) {
 
228
  $icons = synved_social_icon_skin_list();
229
 
230
+ if ( false === empty( $name ) && false === isset( $icons[ $name ] ) ) {
231
+ foreach ( $icons as $skin_name => $skin ) {
232
+ if ( strtolower( $name ) === strtolower( $skin['label'] ) ) {
233
  $name = $skin_name;
234
 
235
  break;
237
  }
238
  }
239
 
240
+ if ( true === empty( $name ) || false === isset( $icons[ $name ] ) ) {
241
+ $selected = synved_option_get( 'synved_social', 'icon_skin' );
242
 
243
  $name = $selected;
244
  }
245
 
246
+ if ( isset( $icons[ $name ] ) ) {
247
+ return $icons[ $name ];
248
  }
249
 
250
+ if ( isset( $icons['regular'] ) ) {
251
  return $icons['regular'];
252
  }
253
 
257
  /**
258
  * Get icon skin size list array.
259
  *
260
+ * @param array $skin Skin array.
261
  *
262
  * @return array
263
  */
264
+ function synved_social_icon_skin_get_size_list( $skin ) {
265
+ if ( isset( $skin['size-list'] ) ) {
 
266
  return $skin['size-list'];
267
  }
268
 
269
+ if ( isset( $skin['name'] ) ) {
270
+ $skin_fresh = synved_social_icon_skin_get( $skin['name'] );
271
 
272
+ if (
273
+ true === isset( $skin['path'] )
274
+ && true === isset( $skin_fresh['path'] )
275
+ && $skin['path'] === $skin_fresh['path']
276
+ ) {
277
+ if ( isset( $skin_fresh['size-list'] ) ) {
278
  return $skin_fresh['size-list'];
279
  }
280
  }
281
  }
282
 
283
  $path = synved_social_path();
284
+ $skin_path = true === isset( $skin['path'] ) ? $skin['path'] : ( $path . '/image/social/regular/' );
285
 
286
+ $sizes = glob( $skin_path . '*', GLOB_ONLYDIR );
287
+ $sizes = array_map( 'basename', $sizes );
288
+ $size_list = array();
289
 
290
+ foreach ( $sizes as $size_dir ) {
291
+ $size_parts = explode( 'x', $size_dir );
292
+ $size_width = (int) $size_parts[0];
293
 
294
+ if ( false === empty( $size_width ) ) {
295
  $size_list[] = $size_width;
296
  }
297
  }
298
 
299
+ sort( $size_list, SORT_NUMERIC );
300
 
301
+ if ( isset( $skin['name'] ) ) {
302
  global $synved_social;
303
 
304
  $name = $skin['name'];
305
 
306
+ // Ensure the global is set.
307
  synved_social_icon_skin_list();
308
 
309
+ if ( true === isset( $synved_social['skin_list'] ) && null !== $synved_social['skin_list'] ) {
310
+ if ( false === isset( $synved_social['skin_list'][ $name ] ) ) {
311
+ $synved_social['skin_list'][ $name ] = array();
312
  }
313
 
314
+ foreach ( $skin as $key => $value ) {
315
+ $synved_social['skin_list'][ $name ][ $key ] = $value;
316
  }
317
  }
318
  }
323
  /**
324
  * Get Icon Skin Image List array.
325
  *
326
+ * @param array $skin Skin array.
327
+ * @param array $name_list Name list array.
328
+ * @param int|null $forced_size Forced size width.
329
  *
330
  * @return array
331
  */
332
+ function synved_social_icon_skin_get_image_list_raw( $skin, $name_list, $forced_size = null ) {
 
333
  $path = synved_social_path();
334
  $uri = synved_social_path_uri();
335
+ $skin_default = synved_social_icon_skin_get( 'regular' );
336
 
337
+ $skin_default_path = true === isset( $skin_default['path'] ) ? $skin_default['path'] : ( $path . '/image/social/regular/' );
338
+ $skin_default_uri = true === isset( $skin_default['uri'] ) ? $skin_default['uri'] : ( $uri . '/image/social/regular/' );
339
+ $skin_sel_path = true === isset( $skin['path'] ) ? $skin['path'] : ( $path . '/image/social/regular/' );
340
+ $skin_sel_uri = true === isset( $skin['uri'] ) ? $skin['uri'] : ( $uri . '/image/social/regular/' );
341
 
342
+ $default_size_list = synved_social_icon_skin_get_size_list( $skin_default );
343
+ $sel_size_list = synved_social_icon_skin_get_size_list( $skin );
344
 
345
+ $skin_list = array(
346
+ array(
347
  'path' => $skin_sel_path,
348
  'uri' => $skin_sel_uri,
349
  'list' => $sel_size_list,
350
+ ),
351
+ array(
352
  'path' => $skin_default_path,
353
  'uri' => $skin_default_uri,
354
  'list' => $default_size_list,
355
+ ),
356
+ );
357
 
358
+ $image_list = array();
359
 
360
+ foreach ( $name_list as $name ) {
361
+ foreach ( $skin_list as $skin ) {
362
  $skin_path = $skin['path'];
363
  $skin_uri = $skin['uri'];
364
  $size_list = $skin['list'];
365
+ $size_count = count( $size_list );
366
 
367
+ $image_size_list = array();
368
+ $image_size_list_skipped = array();
369
 
370
+ for ( $i = 0; $i < $size_count; $i++ ) {
371
+ $image_size = $size_list[ $i ];
372
  $image_sub = '/' . $name . '.png';
373
  $size_name = $image_size . 'x' . $image_size;
374
  $image_path = $skin_path . $size_name . $image_sub;
375
  $image_uri = $skin_uri . $size_name . $image_sub;
376
 
377
+ if ( true === file_exists( $image_path ) ) {
378
+ $image_size_meta = array(
379
  'name' => $size_name,
380
  'sub' => $image_sub,
381
  'path' => $image_path,
382
  'uri' => $image_uri,
383
+ );
384
 
385
+ foreach ( $image_size_list_skipped as $image_size_skipped ) {
386
+ $image_size_list[ $image_size_skipped ] = $image_size_meta;
387
  }
388
 
389
+ $image_size_skipped = array();
390
+ $image_size_list[ $image_size ] = $image_size_meta;
391
 
392
+ if (
393
+ false === empty( $forced_size )
394
+ && ( $image_size > $forced_size || $i === $size_count - 1 )
395
+ && false === isset( $image_size_list[ $forced_size ] )
396
+ ) {
397
+ $image_size_list[ $forced_size ] = $image_size_meta;
398
  }
399
  } else {
400
  $image_size_skipped[] = $image_size;
401
  }
402
  }
403
 
404
+ if ( false === empty( $image_size_list ) ) {
405
  break;
406
  }
407
  }
408
 
409
+ $image_list[ $name ] = $image_size_list;
410
  }
411
 
412
  return $image_list;
415
  /**
416
  * Get filtered Icon skin image list array.
417
  *
418
+ * @param array $skin Skin array.
419
+ * @param array $name_list Name list array.
420
+ * @param int $forced_size Forced size int.
421
  *
422
+ * @return array Image list.
423
  */
424
+ function synved_social_icon_skin_get_image_list( $skin, $name_list, $forced_size = null ) {
425
+ $image_list = synved_social_icon_skin_get_image_list_raw( $skin, $name_list, $forced_size );
426
+ $image_list = apply_filters( 'synved_social_skin_image_list', $image_list, $skin, $name_list, $forced_size );
 
427
 
428
  return $image_list;
429
  }
431
  /**
432
  * Get Button list shortcode HTML.
433
  *
434
+ * @param array $atts Attributes.
435
+ * @param string $content Content string.
436
+ * @param string $code Code string.
437
+ * @param string|null $context Context string.
438
  *
439
  * @return string
440
  */
441
+ function synved_social_button_list_shortcode( $atts, $content = null, $code = '', $context = null ) {
442
+ $vars_def = array(
443
+ 'url' => null,
444
+ 'image' => null,
445
+ 'title' => null,
446
+ 'message' => null,
447
+ );
448
+ $params_def = array(
449
  'skin' => null,
450
  'size' => null,
451
  'spacing' => null,
458
  'custom1' => null,
459
  'custom2' => null,
460
  'custom3' => null,
461
+ );
462
+ $vars = shortcode_atts( $vars_def, $atts, 'feather_' . $context );
463
+ $params = shortcode_atts( $params_def, $atts, 'feather_' . $context );
464
+ $vars = array_filter( $vars );
465
+ $params = array_filter( $params );
466
+
467
+ $vars = apply_filters( 'synved_social_shortcode_variable_list', $vars, $context, $atts );
468
+ $params = apply_filters( 'synved_social_shortcode_parameter_list', $params, $context, $atts );
469
+
470
+ if ( 'share' === $context ) {
471
+ return synved_social_share_markup( $vars, null, $params );
472
+ } elseif ( 'follow' === $context ) {
473
+ return synved_social_follow_markup( $vars, null, $params );
474
  }
475
 
476
  return '';
479
  /**
480
  * Get Share shortcode HTML output.
481
  *
482
+ * @param array $atts Attributes array.
483
+ * @param string $content Content string.
484
+ * @param string $code Code string.
485
  *
486
  * @return string
487
  */
488
+ function synved_social_share_shortcode( $atts, $content = null, $code = '' ) {
489
+ return synved_social_button_list_shortcode( $atts, $content, $code, 'share' );
 
490
  }
491
 
492
  /**
493
  * Get Follow shortcode HTML output.
494
  *
495
+ * @param array $atts Attributes array.
496
+ * @param string $content Content string.
497
+ * @param string $code Code string.
498
  *
499
  * @return string
500
  */
501
+ function synved_social_follow_shortcode( $atts, $content = null, $code = '' ) {
502
+ return synved_social_button_list_shortcode( $atts, $content, $code, 'follow' );
 
503
  }
504
 
505
  /**
507
  *
508
  * Escaped via wp_kses_post.
509
  *
510
+ * @param array $out_item Out item array.
511
  *
512
  * @return string
513
  */
514
+ function synved_social_button_list_markup_item_out( $out_item ) {
 
515
  $out = null;
516
+ $tag = isset( $out_item['tag'] ) ? $out_item['tag'] : null;
517
+ $content = isset( $out_item['content'] ) ? $out_item['content'] : null;
518
+ $list = isset( $out_item['child-list'] ) ? $out_item['child-list'] : null;
519
 
520
+ unset( $out_item['tag'] );
521
+ unset( $out_item['content'] );
522
+ unset( $out_item['child-list'] );
523
 
524
+ if ( false === empty( $tag ) ) {
525
  $out .= '<' . $tag;
526
 
527
+ foreach ( $out_item as $attr_name => $attr_value ) {
528
+ if ( null !== $attr_name && null !== $attr_value ) {
529
+ if ( true === in_array( $attr_name, array( 'href', 'src' ), true ) ) {
530
+ $attr_value = str_ireplace( array( '[', ']' ), array( '&#91;', '&#93;' ), $attr_value );
531
+ $attr_value = esc_url( $attr_value );
532
  } else {
533
+ $attr_value = esc_attr( $attr_value );
534
  }
535
 
536
  $out .= ' ' . $attr_name . '="' . $attr_value . '"';
537
  }
538
  }
539
 
540
+ if ( false === empty( $list ) || false === empty( $content ) ) {
541
  $out .= '>';
542
  } else {
543
  $out .= ' />';
544
  }
545
  }
546
 
547
+ if ( false === empty( $list ) ) {
548
+ foreach ( $list as $child ) {
549
+ $out .= synved_social_button_list_markup_item_out( $child );
550
  }
551
  }
552
 
553
+ if ( false === empty( $content ) ) {
554
  $out .= $content;
555
  }
556
 
557
+ if (
558
+ false === empty( $tag )
559
+ && (
560
+ false === empty( $list )
561
+ || false === empty( $content ) )
562
+ ) {
563
  $out .= '</' . $tag . '>';
564
  }
565
 
566
+ return wp_kses_post( $out );
567
  }
568
 
569
  /**
571
  *
572
  * Escaped via wp_kses_post.
573
  *
574
+ * @param string $context Context string.
575
+ * @param array|null $vars Variables array.
576
+ * @param array|null $buttons Buttons array.
577
+ * @param array|null $params Parameters array.
578
  *
579
  * @return string
580
  */
581
+ function synved_social_button_list_markup( $context, $vars = null, $buttons = null, $params = null ) {
582
+ $buttons_default = synved_social_service_provider_list( $context );
 
583
 
584
+ if ( true === empty( $buttons ) ) {
585
  $buttons = $buttons_default;
586
  } else {
587
+ $keys = array_keys( $buttons );
588
 
589
+ foreach ( $keys as $key ) {
590
+ if ( true === empty( $buttons[ $key ] ) && true === isset( $buttons_default[ $key ] ) ) {
591
+ $buttons[ $key ] = $buttons_default[ $key ];
592
  }
593
  }
594
  }
595
 
596
  $id = get_the_ID();
597
 
598
+ if ( true === empty( $id ) ) {
599
  global $post;
600
 
601
+ if ( false === empty( $post ) ) {
602
  $id = $post->ID;
603
  }
604
  }
605
 
606
+ if ( false === isset( $vars['url'], $vars['short_url'] ) ) {
607
  $home_url = home_url();
608
+ $req_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );
609
 
610
+ $path = wp_parse_url( $home_url, PHP_URL_PATH );
611
+ $path_len = strlen( $path );
612
 
613
+ if ( strtolower( substr( $req_uri, 0, $path_len ) ) === strtolower( $path ) ) {
614
+ $req_uri = substr( $req_uri, $path_len );
615
  }
616
 
617
+ $url = home_url( $req_uri );
618
  $short_url = $url;
619
 
620
+ if ( false === empty( $id ) && true === in_the_loop() ) {
621
+ $use_shortlinks = boolval( synved_option_get( 'synved_social', 'use_shortlinks' ) );
622
+ $url = get_permalink( $id );
623
+ $short_url = wp_get_shortlink( $id );
624
 
625
+ if ( false === empty( $short_url ) ) {
626
+ if ( true === $use_shortlinks && function_exists( 'wp_get_shortlink' ) ) {
627
  $url = $short_url;
628
  }
629
  } else {
630
  $short_url = $url;
631
  }
632
+ } elseif ( true === is_front_page() ) {
633
  $url = $home_url;
634
  }
635
 
636
+ if ( false === isset( $vars['url'] ) ) {
637
  $vars['url'] = $url;
638
  }
639
 
640
+ if ( false === isset( $vars['short_url'] ) ) {
641
  $vars['short_url'] = $short_url;
642
  }
643
  }
644
 
645
+ if ( false === isset( $vars['image'] ) ) {
646
  $image_src = null;
647
 
648
+ if ( false === empty( $id ) ) {
649
+ $image_id = get_post_thumbnail_id( $id );
650
 
651
+ if ( false === empty( $image_id ) ) {
652
+ $src = wp_get_attachment_image_src( $image_id, 'full' );
653
  $image_src = $src[0];
654
  } else {
655
+ $the_post = get_post( $id );
656
+ $match = null;
657
 
658
+ if ( false !== preg_match( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $the_post->post_content, $match ) > 0 ) {
659
  $image_src = $match[1];
660
  }
661
  }
664
  $vars['image'] = $image_src;
665
  }
666
 
667
+ if ( false === isset( $vars['title'] ) ) {
668
  $title = get_the_title();
669
+ // Do this encoding to prevent non-tags things, like emoticons, from being stripped, i.e. <8.
670
+ $title = preg_replace( '/\\<\\s*([^[:alpha:]\\/])/', '&lt;$1', $title );
671
+ $vars['title'] = html_entity_decode( wp_strip_all_tags( $title ) );
672
  }
673
 
674
+ if ( false === isset( $vars['message'] ) ) {
675
+ $message = synved_option_get( 'synved_social', 'share_message_default' );
676
 
677
+ if ( true === empty( $message ) ) {
678
+ $message = __( 'Hey check this out', 'social-media-feather' );
679
  }
680
 
681
  $vars['message'] = $message;
682
  }
683
 
684
+ if ( false === isset( $vars['author_wp'] ) ) {
685
+ if ( false === empty( $id ) && true === in_the_loop() ) {
686
  $author = get_the_author();
687
 
688
+ if ( false === empty( $author ) ) {
689
  $vars['author_wp'] = $author;
690
  }
691
  }
692
  }
693
 
694
+ if ( true === isset( $vars['author'] ) ) {
695
+ if ( false === empty( $id ) && true === in_the_loop() ) {
696
+ $author = get_the_author_meta( '_synved_twitter_handle' );
697
 
698
+ if ( true === empty( $author ) ) {
699
+ $author = get_the_author_meta( 'twitter' );
700
  }
701
 
702
+ if ( true === empty( $author ) ) {
703
  $author = get_the_author();
704
  }
705
 
706
+ if ( false === empty( $author ) ) {
707
  $vars['author'] = $author;
708
  }
709
  }
710
  }
711
 
712
+ if ( false === isset( $vars['date'] ) ) {
713
+ if ( false === empty( $id ) && true === in_the_loop() ) {
714
+ $date = get_the_date( '', $id );
715
 
716
+ if ( false === empty( $date ) ) {
717
  $vars['date'] = $date;
718
  }
719
  }
720
  }
721
 
722
+ if ( true === isset( $vars['url'] ) && false === isset( $vars['url_trimmed'] ) ) {
723
+ $url_trimmed = trim( $vars['url'] );
724
 
725
+ while ( substr( $url_trimmed, -1 ) === '/' ) {
726
+ $url_trimmed = substr( $url_trimmed, 0, -1 );
727
  }
728
 
729
+ while ( strtolower( substr( $url_trimmed, -3 ) ) === '%2f' ) {
730
+ $url_trimmed = substr( $url_trimmed, 0, -3 );
731
  }
732
 
733
  $vars['url_trimmed'] = $url_trimmed;
734
  }
735
 
736
+ if ( true === isset( $params['class'] ) && false === is_array( $params['class'] ) ) {
737
+ $class = explode( ' ', $params['class'] );
738
+ $params['class'] = array_map( 'trim', $class );
739
  }
740
 
741
+ if ( true === isset( $params['show'] ) && false === is_array( $params['show'] ) ) {
742
+ $show = explode( ',', $params['show'] );
743
+ $params['show'] = array_map( 'trim', $show );
744
  }
745
 
746
+ if ( true === isset( $params['hide'] ) && false === is_array( $params['hide'] ) ) {
747
+ $hide = explode( ',', $params['hide'] );
748
+ $params['hide'] = array_map( 'trim', $hide );
749
  }
750
 
751
+ $vars = apply_filters( 'synved_social_markup_variable_list', $vars, $context, $params );
752
+ $params = apply_filters( 'synved_social_markup_parameter_list', $params, $context, $vars );
753
+
754
+ if ( false === empty( $vars ) ) {
755
+ $vars = array_map( 'wp_kses_decode_entities', $vars );
756
+ $vars = urlencode_deep( $vars );
757
+
758
+ // NOTE: urlencode_deep converts space characters to + rather than %20 which messes things up.
759
+ $vars['message'] = str_ireplace( '+', '%20', $vars['message'] );
760
+ $vars['title'] = str_ireplace( '+', '%20', $vars['title'] );
761
+
762
+ // NOTE: urlencode_deep tries to be smart and apostrophes (') to %19 not %27 and double quotes (") to their equivalent open/closed counterparts which doesn't work on most social networks sharings.
763
+ $vars['message'] = str_ireplace( '%18', '%27', $vars['message'] );
764
+ $vars['title'] = str_ireplace( '%18', '%27', $vars['title'] );
765
+ $vars['message'] = str_ireplace( '%19', '%27', $vars['message'] );
766
+ $vars['title'] = str_ireplace( '%19', '%27', $vars['title'] );
767
+ $vars['message'] = str_ireplace( '%1c', '%22', $vars['message'] );
768
+ $vars['title'] = str_ireplace( '%1c', '%22', $vars['title'] );
769
+ $vars['message'] = str_ireplace( '%1d', '%22', $vars['message'] );
770
+ $vars['title'] = str_ireplace( '%1d', '%22', $vars['title'] );
771
  }
772
 
773
  $path = synved_social_path();
774
  $uri = synved_social_path_uri();
775
  $skin = synved_social_icon_skin_get();
776
 
777
+ if ( true === isset( $params['skin'] ) ) {
778
+ $skin = synved_social_icon_skin_get( $params['skin'] );
779
  }
780
 
781
+ $skin_path = true === isset( $skin['path'] ) ? $skin['path'] : ( $path . '/image/social/regular/' );
782
+ $skin_uri = true === isset( $skin['uri'] ) ? $skin['uri'] : ( $uri . '/image/social/regular/' );
783
 
784
+ $icon_size = synved_option_get( 'synved_social', 'icon_size' );
785
  $size = 48;
786
 
787
+ if ( false === empty( $icon_size ) ) {
788
  $size = $icon_size;
789
  }
790
 
791
+ if ( true === isset( $params['size'] ) ) {
792
  $size = $params['size'];
793
 
794
+ if ( is_string( $size ) ) {
795
+ $size = strtolower( $size );
796
+ $size_parts = explode( 'x', $size );
797
+ $size = (int) $size_parts[0];
798
  }
799
  }
800
 
801
+ $icon_spacing = synved_option_get( 'synved_social', 'icon_spacing' );
802
+ $buttons_container = synved_option_get( 'synved_social', 'buttons_container' );
803
+ $buttons_container_type = synved_option_get( 'synved_social', 'buttons_container_type' );
804
+ $buttons_alignment = synved_option_get( 'synved_social', 'buttons_alignment_' . $context );
805
+ $layout_rtl = boolval( synved_option_get( 'synved_social', 'layout_rtl' ) );
806
  $spacing = 5;
807
  $container = 'none';
808
  $container_type = 'basic';
809
  $alignment = 'none';
810
 
811
+ if ( false === empty( $icon_spacing ) ) {
812
  $spacing = $icon_spacing;
813
  }
814
 
815
+ if ( true === isset( $params['spacing'] ) ) {
816
  $spacing = $params['spacing'];
817
  }
818
 
819
+ if ( false === empty( $buttons_container ) ) {
820
  $container = $buttons_container;
821
  }
822
 
823
+ if ( false === empty( $buttons_container_type ) ) {
824
  $container_type = $buttons_container_type;
825
  }
826
 
827
+ if ( false === empty( $buttons_alignment ) ) {
828
  $alignment = $buttons_alignment;
829
  }
830
 
831
+ if ( true === isset( $params['alignment'] ) ) {
832
  $alignment = $params['alignment'];
833
  }
834
 
835
+ if ( 'none' !== $alignment ) {
836
+ if ( 'none' === $container ) {
837
  $container = $context;
838
+ } elseif ( 'both' !== $container && $container !== $context ) {
839
  $container = 'both';
840
  }
841
  }
842
 
843
+ // Allow parameters to override container after we decide a default based on selected alignment.
844
+ if ( true === isset( $params['container'] ) ) {
845
  $container = $params['container'];
846
  }
847
 
848
+ if ( 'none' !== $alignment ) {
849
  $container_type = 'block';
850
  }
851
 
852
+ // Allow parameters to override container after we decide a default based on selected alignment.
853
+ if ( true === isset( $params['container_type'] ) ) {
854
  $container_type = $params['container_type'];
855
  }
856
 
857
+ $class = true === isset( $params['class'] ) ? $params['class'] : null;
858
+ $show = true === isset( $params['show'] ) ? $params['show'] : null;
859
+ $hide = true === isset( $params['hide'] ) ? $params['hide'] : null;
860
 
861
+ if ( false === empty( $show ) ) {
862
+ $button_list = array();
863
 
864
+ foreach ( $show as $button_key ) {
865
+ if ( true === isset( $buttons[ $button_key ] ) ) {
866
+ $button_list[ $button_key ] = $buttons[ $button_key ];
867
 
868
+ unset( $buttons[ $button_key ] );
869
  }
870
  }
871
 
872
+ foreach ( $buttons as $button_key => $button_item ) {
873
+ $button_list[ $button_key ] = $button_item;
874
  }
875
 
876
  $buttons = $button_list;
877
  }
878
 
879
+ if ( false === empty( $hide ) ) {
880
+ foreach ( $hide as $button_key ) {
881
+ if ( true === isset( $buttons[ $button_key ] ) ) {
882
+ unset( $buttons[ $button_key ] );
883
  }
884
  }
885
  }
886
 
887
+ $out_list = array();
888
+ $out_params = array();
889
+ $image_list = array();
890
+ $icon_resolution = synved_option_get( 'synved_social', 'icon_resolution' );
891
+ $resolutions = array(
892
+ 'normal' => $size,
893
+ 'hidef' => $size * 2,
894
+ );
895
 
896
+ if ( true === is_feed() ) {
897
  $icon_resolution = 'single';
898
  }
899
 
900
+ if ( 'single' === $icon_resolution ) {
901
+ $resolutions = array( 'single' => $size * 2 );
902
  }
903
 
904
+ $button_keys = array_keys( $buttons );
905
 
906
+ foreach ( $resolutions as $resolution_name => $resolution_size ) {
907
+ $image_list[ $resolution_name ] = synved_social_icon_skin_get_image_list(
908
  $skin,
909
  $button_keys,
910
  $resolution_size
912
  }
913
 
914
  $index = 0;
915
+ $count = count( $buttons );
916
 
917
+ foreach ( $buttons as $button_key => $button_item ) {
918
  $href = $button_item['link'];
919
  $title = $button_item['title'];
920
 
921
  $matches = null;
922
 
923
+ if ( preg_match_all( '/%%(\\w+)%%/', $href, $matches, PREG_SET_ORDER ) > 0 ) {
924
+ foreach ( $matches as $match ) {
925
  $var_key = $match[1];
926
  $replace = null;
927
 
928
+ if ( isset( $vars[ $var_key ] ) ) {
929
+ $replace = $vars[ $var_key ];
930
  }
931
 
932
+ $href = str_replace( $match[0], $replace, $href );
933
  }
934
  }
935
 
936
  $icon_sizes = $resolutions;
937
 
938
+ foreach ( $icon_sizes as $icon_def => $icon_size ) {
939
+ $image = $image_list[ $icon_def ][ $button_key ];
940
+ $image_size = $image[ $icon_size ];
941
  $image_sub = $image_size['sub'];
942
  $image_path = $image_size['path'];
943
  $image_uri = $image_size['uri'];
944
 
945
+ if ( false === file_exists( $image_path ) ) {
946
+ $size_list = array_keys( $image );
947
+ $image_path = apply_filters(
948
+ 'synved_social_button_image_path',
949
+ $image_path,
950
+ $image_uri,
951
+ $icon_size,
952
+ $image_sub,
953
+ $skin_path,
954
+ $skin_uri,
955
+ $size_list
956
+ );
957
+ $image_uri = apply_filters(
958
+ 'synved_social_button_image_uri',
959
+ $image_uri,
960
+ $image_path,
961
+ $icon_size,
962
+ $image_sub,
963
+ $skin_path,
964
+ $skin_uri,
965
+ $size_list
966
+ );
967
  }
968
 
969
+ $style = 'margin:0;';
970
+ $style .= 'margin-bottom:' . $spacing . 'px;';
 
 
 
971
 
972
+ if ( $index < $count - 1 || false === empty( $layout_rtl ) ) {
973
  $style .= 'margin-right:' . $spacing . 'px;';
974
  }
975
 
976
  $class_extra = null;
977
 
978
+ if ( false === empty( $class ) ) {
979
+ $class_extra = ' ' . implode( ' ', $class );
980
  }
981
 
982
+ // Don't use "nofancybox" because some plugins/themes interpret it as enabling fancybox.
983
  $class_extra .= ' nolightbox';
984
 
985
+ $out_button = array(
986
  'tag' => 'a',
987
  'class' => 'synved-social-button synved-social-button-' . $context . ' synved-social-size-' . $size . ' synved-social-resolution-' . $icon_def . ' synved-social-provider-' . $button_key . $class_extra,
988
  'data-provider' => $button_key,
989
+ 'target' => 'mail' !== $button_key ? '_blank' : null,
990
  'rel' => 'nofollow',
991
  'title' => $title,
992
  'href' => $href,
993
+ 'style' => 'font-size: 0px; width:' . $size . 'px; height:' . $size . 'px;' . $style,
994
+ 'child-list' => array(
995
+ array(
996
  'tag' => 'img',
997
+ 'alt' => 'facebook' === $button_key ? 'Facebook' : $button_key,
998
  'title' => $title,
999
  'class' => 'synved-share-image synved-social-image synved-social-image-' . $context,
1000
  'width' => $size,
1001
  'height' => $size,
1002
+ 'style' => 'display: inline; width:' . $size . 'px; height:' . $size . 'px; margin: 0; padding: 0; border: none; box-shadow: none;',
1003
  'src' => $image_uri,
1004
+ ),
1005
+ ),
1006
+ );
1007
 
1008
+ $out_list[ $icon_def ][ $button_key ] = $out_button;
1009
+ $out_params[ $icon_def ][ $button_key ] = array( 'icon-resolution' => $icon_def );
1010
  }
1011
 
1012
  $index++;
1014
 
1015
  $out = null;
1016
 
1017
+ if ( false === empty( $out_list ) ) {
1018
+ foreach ( $out_list as $def_key => $def_list ) {
1019
+ $out_list[ $def_key ] = apply_filters(
1020
+ 'synved_social_button_list_markup',
1021
+ $def_list,
1022
+ $out_params[ $def_key ],
1023
+ $context,
1024
+ $vars,
1025
+ $params
1026
+ );
1027
  }
1028
  }
1029
 
1030
+ if ( false === empty( $out_list ) ) {
1031
  $container_tag = 'span';
1032
 
1033
+ if ( 'block' === $container_type ) {
1034
  $container_tag = 'div';
1035
  }
1036
 
1037
+ if ( 'none' !== $container && ( 'both' === $container || $container === $context ) ) {
1038
+ $container_style = 'none' !== $alignment ? ' style="text-align: ' . $alignment . '"' : null;
1039
 
1040
  $out .= '<' . $container_tag . ' class="synved-social-container synved-social-container-' . $context . '"' . $container_style . '>';
1041
  }
1042
 
1043
+ foreach ( $out_list as $def_list ) {
1044
+ foreach ( $def_list as $out_item ) {
1045
+ $out .= synved_social_button_list_markup_item_out( $out_item );
1046
  }
1047
  }
1048
 
1049
+ if ( false !== boolval( synved_option_get( 'synved_social', 'show_credit', false ) ) ) {
1050
+ $out .= '<a class="synved-social-credit" target="_blank" rel="nofollow" title="' . __(
1051
+ 'WordPress Social Media Feather',
1052
+ 'social-media-feather'
1053
+ ) . '" href="http://synved.com/wordpress-social-media-feather/" style="color:#444; text-decoration:none; font-size:8px; margin-left:5px;vertical-align:10px;white-space:nowrap;"><span>' . __(
1054
+ 'by ',
1055
+ 'social-media-feather'
1056
+ ) . '</span><img style="display: inline;margin:0;padding:0;width:16px;height:16px;" width="16" height="16" alt="feather" src="' . $uri . '/image/icon.png" /></a>';
1057
  }
1058
 
1059
+ if ( 'none' !== $container && ( 'both' === $container || $container === $context ) ) {
1060
  $out .= '</' . $container_tag . '>';
1061
  }
1062
  }
1063
 
1064
+ return wp_kses_post( $out );
1065
  }
1066
 
1067
  /**
1068
  * Share markup.
1069
  *
1070
+ * @param array|null $vars Variables array.
1071
+ * @param array|null $buttons Buttons array.
1072
+ * @param array|null $params Parameters array.
1073
  *
1074
  * @return string
1075
  */
1076
+ function synved_social_share_markup( $vars = null, $buttons = null, $params = null ) {
1077
+ return synved_social_button_list_markup( 'share', $vars, $buttons, $params );
 
1078
  }
1079
 
1080
  /**
1081
  * Follow markup.
1082
  *
1083
+ * @param array|null $vars Variables array.
1084
+ * @param array|null $buttons Buttons array.
1085
+ * @param array|null $params Parameters array.
1086
  *
1087
  * @return string
1088
  */
1089
+ function synved_social_follow_markup( $vars = null, $buttons = null, $params = null ) {
1090
+ return synved_social_button_list_markup( 'follow', $vars, $buttons, $params );
 
1091
  }
uninstall.php CHANGED
@@ -1,17 +1,19 @@
1
  <?php
2
- // if uninstall.php is not called by WordPress, die
3
- if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
 
 
 
 
 
 
4
  die;
5
  }
6
 
7
  delete_option( 'synved_connect_install_date' );
8
  delete_option( 'synved_version' );
9
-
10
  delete_option( 'synved_connect_id_default' );
11
-
12
  delete_option( 'widget_synved_social_share' );
13
  delete_option( 'widget_synved_social_follow' );
14
-
15
  delete_option( 'synved_option_wp_upgrade_addon_transfer' );
16
-
17
- delete_option( 'synved_social_settings' );
1
  <?php
2
+ /**
3
+ * Uninstall.
4
+ *
5
+ * @package SocialMediaFeather
6
+ */
7
+
8
+ // If uninstall.php is not called by WordPress, die.
9
+ if ( false === defined( 'WP_UNINSTALL_PLUGIN' ) ) {
10
  die;
11
  }
12
 
13
  delete_option( 'synved_connect_install_date' );
14
  delete_option( 'synved_version' );
 
15
  delete_option( 'synved_connect_id_default' );
 
16
  delete_option( 'widget_synved_social_share' );
17
  delete_option( 'widget_synved_social_follow' );
 
18
  delete_option( 'synved_option_wp_upgrade_addon_transfer' );
19
+ delete_option( 'synved_social_settings' );