52572b82 by Jeff Balicki

404

Signed-off-by: Jeff <jeff@gotenzing.com>
1 parent 423dd060
Showing 78 changed files with 19907 additions and 12 deletions
This diff could not be displayed because it is too large.
/* -------------------------------------------------------------------
Microtip
Modern, lightweight css-only tooltips
Just 1kb minified and gzipped
@author Ghosh
@package Microtip
----------------------------------------------------------------------
1. Base Styles
2. Direction Modifiers
3. Position Modifiers
--------------------------------------------------------------------*/
/* ------------------------------------------------
[1] Base Styles
-------------------------------------------------*/
[aria-label][role~="tooltip"] {
position: relative;
}
[aria-label][role~="tooltip"]::before,
[aria-label][role~="tooltip"]::after {
transform: translate3d(0, 0, 0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
will-change: transform;
opacity: 0;
pointer-events: none;
transition: all var(--microtip-transition-duration, .18s) var(--microtip-transition-easing, ease-in-out) var(--microtip-transition-delay, 0s);
position: absolute;
box-sizing: border-box;
z-index: 10;
transform-origin: top;
}
[aria-label][role~="tooltip"]::before {
background-size: 100% auto !important;
content: "";
}
[aria-label][role~="tooltip"]::after {
background: rgba(17, 17, 17, .9);
border-radius: 4px;
color: #ffffff;
content: attr(aria-label);
font-size: var(--microtip-font-size, 13px);
font-weight: var(--microtip-font-weight, normal);
text-transform: var(--microtip-text-transform, none);
padding: .5em 1em;
white-space: nowrap;
box-sizing: content-box;
}
[aria-label][role~="tooltip"]:hover::before,
[aria-label][role~="tooltip"]:hover::after,
[aria-label][role~="tooltip"]:focus::before,
[aria-label][role~="tooltip"]:focus::after {
opacity: 1;
pointer-events: auto;
}
/* ------------------------------------------------
[2] Position Modifiers
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position|="top"]::before {
background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
height: 6px;
width: 18px;
margin-bottom: 5px;
}
[role~="tooltip"][data-microtip-position|="top"]::after {
margin-bottom: 11px;
}
[role~="tooltip"][data-microtip-position|="top"]::before {
transform: translate3d(-50%, 0, 0);
bottom: 100%;
left: 50%;
}
[role~="tooltip"][data-microtip-position|="top"]:hover::before {
transform: translate3d(-50%, -5px, 0);
}
[role~="tooltip"][data-microtip-position|="top"]::after {
transform: translate3d(-50%, 0, 0);
bottom: 100%;
left: 50%;
}
[role~="tooltip"][data-microtip-position="top"]:hover::after {
transform: translate3d(-50%, -5px, 0);
}
/* ------------------------------------------------
[2.1] Top Left
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="top-left"]::after {
transform: translate3d(calc(-100% + 16px), 0, 0);
bottom: 100%;
}
[role~="tooltip"][data-microtip-position="top-left"]:hover::after {
transform: translate3d(calc(-100% + 16px), -5px, 0);
}
/* ------------------------------------------------
[2.2] Top Right
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="top-right"]::after {
transform: translate3d(calc(0% + -16px), 0, 0);
bottom: 100%;
}
[role~="tooltip"][data-microtip-position="top-right"]:hover::after {
transform: translate3d(calc(0% + -16px), -5px, 0);
}
/* ------------------------------------------------
[2.3] Bottom
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position|="bottom"]::before {
background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
height: 6px;
width: 18px;
margin-top: 5px;
margin-bottom: 0;
}
[role~="tooltip"][data-microtip-position|="bottom"]::after {
margin-top: 11px;
}
[role~="tooltip"][data-microtip-position|="bottom"]::before {
transform: translate3d(-50%, -10px, 0);
bottom: auto;
left: 50%;
top: 100%;
}
[role~="tooltip"][data-microtip-position|="bottom"]:hover::before {
transform: translate3d(-50%, 0, 0);
}
[role~="tooltip"][data-microtip-position|="bottom"]::after {
transform: translate3d(-50%, -10px, 0);
top: 100%;
left: 50%;
}
[role~="tooltip"][data-microtip-position="bottom"]:hover::after {
transform: translate3d(-50%, 0, 0);
}
/* ------------------------------------------------
[2.4] Bottom Left
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="bottom-left"]::after {
transform: translate3d(calc(-100% + 16px), -10px, 0);
top: 100%;
}
[role~="tooltip"][data-microtip-position="bottom-left"]:hover::after {
transform: translate3d(calc(-100% + 16px), 0, 0);
}
/* ------------------------------------------------
[2.5] Bottom Right
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="bottom-right"]::after {
transform: translate3d(calc(0% + -16px), -10px, 0);
top: 100%;
}
[role~="tooltip"][data-microtip-position="bottom-right"]:hover::after {
transform: translate3d(calc(0% + -16px), 0, 0);
}
/* ------------------------------------------------
[2.6] Left
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="left"]::before,
[role~="tooltip"][data-microtip-position="left"]::after {
bottom: auto;
left: auto;
right: 100%;
top: 50%;
transform: translate3d(10px, -50%, 0);
}
[role~="tooltip"][data-microtip-position="left"]::before {
background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
height: 18px;
width: 6px;
margin-right: 5px;
margin-bottom: 0;
}
[role~="tooltip"][data-microtip-position="left"]::after {
margin-right: 11px;
}
[role~="tooltip"][data-microtip-position="left"]:hover::before,
[role~="tooltip"][data-microtip-position="left"]:hover::after {
transform: translate3d(0, -50%, 0);
}
/* ------------------------------------------------
[2.7] Right
-------------------------------------------------*/
[role~="tooltip"][data-microtip-position="right"]::before,
[role~="tooltip"][data-microtip-position="right"]::after {
bottom: auto;
left: 100%;
top: 50%;
transform: translate3d(-10px, -50%, 0);
}
[role~="tooltip"][data-microtip-position="right"]::before {
background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
height: 18px;
width: 6px;
margin-bottom: 0;
margin-left: 5px;
}
[role~="tooltip"][data-microtip-position="right"]::after {
margin-left: 11px;
}
[role~="tooltip"][data-microtip-position="right"]:hover::before,
[role~="tooltip"][data-microtip-position="right"]:hover::after {
transform: translate3d(0, -50%, 0);
}
/* ------------------------------------------------
[3] Size
-------------------------------------------------*/
[role~="tooltip"][data-microtip-size="small"]::after {
white-space: initial;
width: 80px;
}
[role~="tooltip"][data-microtip-size="medium"]::after {
white-space: initial;
width: 150px;
}
[role~="tooltip"][data-microtip-size="large"]::after {
white-space: initial;
width: 260px;
}
/* -------------------------------------------------------------------
Microtip
Modern, lightweight css-only tooltips
Just 1kb minified and gzipped
@author Ghosh
@package Microtip
----------------------------------------------------------------------
1. Base Styles
2. Direction Modifiers
3. Position Modifiers
--------------------------------------------------------------------*/
[aria-label][role~="tooltip"]{position:relative}[aria-label][role~="tooltip"]::before,[aria-label][role~="tooltip"]::after{transform:translate3d(0,0,0);-webkit-backface-visibility:hidden;backface-visibility:hidden;will-change:transform;opacity:0;pointer-events:none;transition:all var(--microtip-transition-duration,.18s) var(--microtip-transition-easing,ease-in-out) var(--microtip-transition-delay,0s);position:absolute;box-sizing:border-box;z-index:10;transform-origin:top}[aria-label][role~="tooltip"]::before{background-size:100% auto!important;content:""}[aria-label][role~="tooltip"]::after{background:rgba(17,17,17,.9);border-radius:4px;color:#fff;content:attr(aria-label);font-size:var(--microtip-font-size,13px);font-weight:var(--microtip-font-weight,normal);text-transform:var(--microtip-text-transform,none);padding:.5em 1em;white-space:nowrap;box-sizing:content-box}[aria-label][role~="tooltip"]:hover::before,[aria-label][role~="tooltip"]:hover::after,[aria-label][role~="tooltip"]:focus::before,[aria-label][role~="tooltip"]:focus::after{opacity:1;pointer-events:auto}[role~="tooltip"][data-microtip-position|="top"]::before{background:url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E) no-repeat;height:6px;width:18px;margin-bottom:5px}[role~="tooltip"][data-microtip-position|="top"]::after{margin-bottom:11px}[role~="tooltip"][data-microtip-position|="top"]::before{transform:translate3d(-50%,0,0);bottom:100%;left:50%}[role~="tooltip"][data-microtip-position|="top"]:hover::before{transform:translate3d(-50%,-5px,0)}[role~="tooltip"][data-microtip-position|="top"]::after{transform:translate3d(-50%,0,0);bottom:100%;left:50%}[role~="tooltip"][data-microtip-position="top"]:hover::after{transform:translate3d(-50%,-5px,0)}[role~="tooltip"][data-microtip-position="top-left"]::after{transform:translate3d(calc(-100% + 16px),0,0);bottom:100%}[role~="tooltip"][data-microtip-position="top-left"]:hover::after{transform:translate3d(calc(-100% + 16px),-5px,0)}[role~="tooltip"][data-microtip-position="top-right"]::after{transform:translate3d(calc(0% + -16px),0,0);bottom:100%}[role~="tooltip"][data-microtip-position="top-right"]:hover::after{transform:translate3d(calc(0% + -16px),-5px,0)}[role~="tooltip"][data-microtip-position|="bottom"]::before{background:url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E) no-repeat;height:6px;width:18px;margin-top:5px;margin-bottom:0}[role~="tooltip"][data-microtip-position|="bottom"]::after{margin-top:11px}[role~="tooltip"][data-microtip-position|="bottom"]::before{transform:translate3d(-50%,-10px,0);bottom:auto;left:50%;top:100%}[role~="tooltip"][data-microtip-position|="bottom"]:hover::before{transform:translate3d(-50%,0,0)}[role~="tooltip"][data-microtip-position|="bottom"]::after{transform:translate3d(-50%,-10px,0);top:100%;left:50%}[role~="tooltip"][data-microtip-position="bottom"]:hover::after{transform:translate3d(-50%,0,0)}[role~="tooltip"][data-microtip-position="bottom-left"]::after{transform:translate3d(calc(-100% + 16px),-10px,0);top:100%}[role~="tooltip"][data-microtip-position="bottom-left"]:hover::after{transform:translate3d(calc(-100% + 16px),0,0)}[role~="tooltip"][data-microtip-position="bottom-right"]::after{transform:translate3d(calc(0% + -16px),-10px,0);top:100%}[role~="tooltip"][data-microtip-position="bottom-right"]:hover::after{transform:translate3d(calc(0% + -16px),0,0)}[role~="tooltip"][data-microtip-position="left"]::before,[role~="tooltip"][data-microtip-position="left"]::after{bottom:auto;left:auto;right:100%;top:50%;transform:translate3d(10px,-50%,0)}[role~="tooltip"][data-microtip-position="left"]::before{background:url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E) no-repeat;height:18px;width:6px;margin-right:5px;margin-bottom:0}[role~="tooltip"][data-microtip-position="left"]::after{margin-right:11px}[role~="tooltip"][data-microtip-position="left"]:hover::before,[role~="tooltip"][data-microtip-position="left"]:hover::after{transform:translate3d(0,-50%,0)}[role~="tooltip"][data-microtip-position="right"]::before,[role~="tooltip"][data-microtip-position="right"]::after{bottom:auto;left:100%;top:50%;transform:translate3d(-10px,-50%,0)}[role~="tooltip"][data-microtip-position="right"]::before{background:url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E) no-repeat;height:18px;width:6px;margin-bottom:0;margin-left:5px}[role~="tooltip"][data-microtip-position="right"]::after{margin-left:11px}[role~="tooltip"][data-microtip-position="right"]:hover::before,[role~="tooltip"][data-microtip-position="right"]:hover::after{transform:translate3d(0,-50%,0)}[role~="tooltip"][data-microtip-size="small"]::after{white-space:initial;width:80px}[role~="tooltip"][data-microtip-size="medium"]::after{white-space:initial;width:150px}[role~="tooltip"][data-microtip-size="large"]::after{white-space:initial;width:260px}
\ No newline at end of file
/*!
Modaal - accessible modals - v0.4.4
by Humaan, for all humans.
http://humaan.com
*/
.modaal-noscroll {
overflow: hidden;
}
.modaal-accessible-hide {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
.modaal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
opacity: 0;
}
.modaal-wrapper {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
overflow: auto;
opacity: 1;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.modaal-wrapper * {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-backface-visibility: hidden;
}
.modaal-wrapper .modaal-close {
border: none;
background: transparent;
padding: 0;
-webkit-appearance: none;
}
.modaal-wrapper.modaal-start_none {
display: none;
opacity: 1;
}
.modaal-wrapper.modaal-start_fade {
opacity: 0;
}
.modaal-wrapper *[tabindex="0"] {
outline: none !important;
}
.modaal-wrapper.modaal-fullscreen {
overflow: hidden;
}
.modaal-outer-wrapper {
display: table;
position: relative;
width: 100%;
height: 100%;
}
.modaal-fullscreen .modaal-outer-wrapper {
display: block;
}
.modaal-inner-wrapper {
display: table-cell;
width: 100%;
height: 100%;
position: relative;
vertical-align: middle;
text-align: center;
padding: 80px 25px;
}
.modaal-fullscreen .modaal-inner-wrapper {
padding: 0;
display: block;
vertical-align: top;
}
.modaal-container {
position: relative;
display: inline-block;
width: 100%;
margin: auto;
text-align: left;
color: #000;
max-width: 1000px;
border-radius: 0px;
background: #fff;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
cursor: auto;
}
.modaal-container.is_loading {
height: 100px;
width: 100px;
overflow: hidden;
}
.modaal-fullscreen .modaal-container {
max-width: none;
height: 100%;
overflow: auto;
}
.modaal-close {
position: fixed;
right: 20px;
top: 20px;
color: #fff;
cursor: pointer;
opacity: 1;
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0);
border-radius: 100%;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
.modaal-close:focus,
.modaal-close:hover {
outline: none;
background: #fff;
}
.modaal-close:focus:before,
.modaal-close:focus:after,
.modaal-close:hover:before,
.modaal-close:hover:after {
background: #b93d0c;
}
.modaal-close span {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
.modaal-close:before,
.modaal-close:after {
display: block;
content: " ";
position: absolute;
top: 14px;
left: 23px;
width: 4px;
height: 22px;
border-radius: 4px;
background: #fff;
-webkit-transition: background 0.2s ease-in-out;
transition: background 0.2s ease-in-out;
}
.modaal-close:before {
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.modaal-close:after {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.modaal-fullscreen .modaal-close {
background: #afb7bc;
right: 10px;
top: 10px;
}
.modaal-content-container {
padding: 30px;
}
.modaal-confirm-wrap {
padding: 30px 0 0;
text-align: center;
font-size: 0;
}
.modaal-confirm-btn {
font-size: 14px;
display: inline-block;
margin: 0 10px;
vertical-align: middle;
cursor: pointer;
border: none;
background: transparent;
}
.modaal-confirm-btn.modaal-ok {
padding: 10px 15px;
color: #fff;
background: #555;
border-radius: 3px;
-webkit-transition: background 0.2s ease-in-out;
transition: background 0.2s ease-in-out;
}
.modaal-confirm-btn.modaal-ok:hover {
background: #2f2f2f;
}
.modaal-confirm-btn.modaal-cancel {
text-decoration: underline;
}
.modaal-confirm-btn.modaal-cancel:hover {
text-decoration: none;
color: #2f2f2f;
}
.modaal-instagram .modaal-container {
width: auto;
background: transparent;
box-shadow: none !important;
}
.modaal-instagram .modaal-content-container {
padding: 0;
background: transparent;
}
.modaal-instagram .modaal-content-container > blockquote {
width: 1px !important;
height: 1px !important;
opacity: 0 !important;
}
.modaal-instagram iframe {
opacity: 0;
margin: -6px !important;
border-radius: 0 !important;
width: 1000px !important;
max-width: 800px !important;
box-shadow: none !important;
-webkit-animation: instaReveal 1s linear forwards;
animation: instaReveal 1s linear forwards;
}
.modaal-image .modaal-inner-wrapper {
padding-left: 140px;
padding-right: 140px;
}
.modaal-image .modaal-container {
width: auto;
max-width: 100%;
}
.modaal-gallery-wrap {
position: relative;
color: #fff;
}
.modaal-gallery-item {
display: none;
}
.modaal-gallery-item img {
display: block;
}
.modaal-gallery-item.is_active {
display: block;
}
.modaal-gallery-label {
position: absolute;
left: 0;
width: 100%;
margin: 20px 0 0;
font-size: 18px;
text-align: center;
color: #fff;
}
.modaal-gallery-label:focus {
outline: none;
}
.modaal-gallery-control {
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
opacity: 1;
cursor: pointer;
color: #fff;
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0);
border: none;
border-radius: 100%;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
.modaal-gallery-control.is_hidden {
opacity: 0;
cursor: default;
}
.modaal-gallery-control:focus,
.modaal-gallery-control:hover {
outline: none;
background: #fff;
}
.modaal-gallery-control:focus:before,
.modaal-gallery-control:focus:after,
.modaal-gallery-control:hover:before,
.modaal-gallery-control:hover:after {
background: #afb7bc;
}
.modaal-gallery-control span {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
.modaal-gallery-control:before,
.modaal-gallery-control:after {
display: block;
content: " ";
position: absolute;
top: 16px;
left: 25px;
width: 4px;
height: 18px;
border-radius: 4px;
background: #fff;
-webkit-transition: background 0.2s ease-in-out;
transition: background 0.2s ease-in-out;
}
.modaal-gallery-control:before {
margin: -5px 0 0;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.modaal-gallery-control:after {
margin: 5px 0 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.modaal-gallery-next-inner {
left: 100%;
margin-left: 40px;
}
.modaal-gallery-next-outer {
right: 45px;
}
.modaal-gallery-prev:before,
.modaal-gallery-prev:after {
left: 22px;
}
.modaal-gallery-prev:before {
margin: 5px 0 0;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.modaal-gallery-prev:after {
margin: -5px 0 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.modaal-gallery-prev-inner {
right: 100%;
margin-right: 40px;
}
.modaal-gallery-prev-outer {
left: 45px;
}
.modaal-video-wrap {
margin: auto 50px;
position: relative;
}
.modaal-video-container {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
max-width: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
background: #000;
max-width: 1300px;
margin-left: auto;
margin-right: auto;
}
.modaal-video-container iframe,
.modaal-video-container object,
.modaal-video-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.modaal-iframe .modaal-content {
width: 100%;
height: 100%;
}
.modaal-iframe-elem {
width: 100%;
height: 100%;
display: block;
}
.modaal-loading-spinner {
background: none;
position: absolute;
width: 200px;
height: 200px;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
-webkit-transform: scale(0.25);
-ms-transform: scale(0.25);
transform: scale(0.25);
}
.modaal-loading-spinner > div {
width: 24px;
height: 24px;
margin-left: 4px;
margin-top: 4px;
position: absolute;
}
.modaal-loading-spinner > div > div {
width: 100%;
height: 100%;
border-radius: 15px;
background: #fff;
}
.modaal-loading-spinner > div:nth-of-type(1) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: 0s;
animation-delay: 0s;
}
.modaal-loading-spinner > div:nth-of-type(2) > div,
.modaal-loading-spinner > div:nth-of-type(3) > div {
-ms-animation: modaal-loading-spinner 1s linear infinite;
-moz-animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation: modaal-loading-spinner 1s linear infinite;
-o-animation: modaal-loading-spinner 1s linear infinite;
}
.modaal-loading-spinner > div:nth-of-type(1) {
-ms-transform: translate(84px, 84px) rotate(45deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(45deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(45deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(2) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .12s;
animation-delay: .12s;
}
.modaal-loading-spinner > div:nth-of-type(2) {
-ms-transform: translate(84px, 84px) rotate(90deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(90deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(90deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(3) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .25s;
animation-delay: .25s;
}
.modaal-loading-spinner > div:nth-of-type(4) > div,
.modaal-loading-spinner > div:nth-of-type(5) > div {
-ms-animation: modaal-loading-spinner 1s linear infinite;
-moz-animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation: modaal-loading-spinner 1s linear infinite;
-o-animation: modaal-loading-spinner 1s linear infinite;
}
.modaal-loading-spinner > div:nth-of-type(3) {
-ms-transform: translate(84px, 84px) rotate(135deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(135deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(135deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(4) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .37s;
animation-delay: .37s;
}
.modaal-loading-spinner > div:nth-of-type(4) {
-ms-transform: translate(84px, 84px) rotate(180deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(180deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(180deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(5) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .5s;
animation-delay: .5s;
}
.modaal-loading-spinner > div:nth-of-type(6) > div,
.modaal-loading-spinner > div:nth-of-type(7) > div {
-ms-animation: modaal-loading-spinner 1s linear infinite;
-moz-animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation: modaal-loading-spinner 1s linear infinite;
-o-animation: modaal-loading-spinner 1s linear infinite;
}
.modaal-loading-spinner > div:nth-of-type(5) {
-ms-transform: translate(84px, 84px) rotate(225deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(225deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(225deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(6) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .62s;
animation-delay: .62s;
}
.modaal-loading-spinner > div:nth-of-type(6) {
-ms-transform: translate(84px, 84px) rotate(270deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(270deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(270deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(7) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .75s;
animation-delay: .75s;
}
.modaal-loading-spinner > div:nth-of-type(7) {
-ms-transform: translate(84px, 84px) rotate(315deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(315deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(315deg) translate(70px, 0);
}
.modaal-loading-spinner > div:nth-of-type(8) > div {
-webkit-animation: modaal-loading-spinner 1s linear infinite;
animation: modaal-loading-spinner 1s linear infinite;
-webkit-animation-delay: .87s;
animation-delay: .87s;
}
.modaal-loading-spinner > div:nth-of-type(8) {
-ms-transform: translate(84px, 84px) rotate(360deg) translate(70px, 0);
-webkit-transform: translate(84px, 84px) rotate(360deg) translate(70px, 0);
transform: translate(84px, 84px) rotate(360deg) translate(70px, 0);
}
@media only screen and (min-width: 1400px) {
.modaal-video-container {
padding-bottom: 0;
height: 731px;
}
}
@media only screen and (max-width: 1140px) {
.modaal-image .modaal-inner-wrapper {
padding-left: 25px;
padding-right: 25px;
}
.modaal-gallery-control {
top: auto;
bottom: 20px;
-webkit-transform: none;
-ms-transform: none;
transform: none;
background: rgba(0, 0, 0, 0.7);
}
.modaal-gallery-control:before,
.modaal-gallery-control:after {
background: #fff;
}
.modaal-gallery-next {
left: auto;
right: 20px;
}
.modaal-gallery-prev {
left: 20px;
right: auto;
}
}
@media screen and (max-width: 900px) {
.modaal-instagram iframe {
width: 500px !important;
}
}
@media only screen and (max-width: 600px) {
.modaal-instagram iframe {
width: 280px !important;
}
}
@media screen and (max-height: 1100px) {
.modaal-instagram iframe {
width: 700px !important;
}
}
@media screen and (max-height: 1000px) {
.modaal-inner-wrapper {
padding-top: 60px;
padding-bottom: 60px;
}
.modaal-instagram iframe {
width: 600px !important;
}
}
@media screen and (max-height: 900px) {
.modaal-instagram iframe {
width: 500px !important;
}
.modaal-video-container {
max-width: 900px;
max-height: 510px;
}
}
@media only screen and (max-height: 820px) {
.modaal-gallery-label {
display: none;
}
}
@keyframes instaReveal {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes instaReveal {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes modaal-loading-spinner {
0% {
opacity: 1;
-ms-transform: scale(1.5);
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
100% {
opacity: .1;
-ms-transform: scale(1);
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes modaal-loading-spinner {
0% {
opacity: 1;
-ms-transform: scale(1.5);
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
100% {
opacity: .1;
-ms-transform: scale(1);
-webkit-transform: scale(1);
transform: scale(1);
}
}
/*!
Modaal - accessible modals - v0.4.4
by Humaan, for all humans.
http://humaan.com
*/.modaal-noscroll{overflow:hidden}.modaal-accessible-hide{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.modaal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;opacity:0}.modaal-wrapper{display:block;position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;overflow:auto;opacity:1;box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.modaal-wrapper *{box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden}.modaal-wrapper .modaal-close{border:none;background:0 0;padding:0;-webkit-appearance:none}.modaal-wrapper.modaal-start_none{display:none;opacity:1}.modaal-wrapper.modaal-start_fade{opacity:0}.modaal-wrapper [tabindex="0"]{outline:0!important}.modaal-wrapper.modaal-fullscreen{overflow:hidden}.modaal-outer-wrapper{display:table;position:relative;width:100%;height:100%}.modaal-fullscreen .modaal-outer-wrapper{display:block}.modaal-inner-wrapper{display:table-cell;width:100%;height:100%;position:relative;vertical-align:middle;text-align:center;padding:80px 25px}.modaal-fullscreen .modaal-inner-wrapper{padding:0;display:block;vertical-align:top}.modaal-container{position:relative;display:inline-block;width:100%;margin:auto;text-align:left;color:#000;max-width:1000px;border-radius:0;background:#fff;box-shadow:0 4px 15px rgba(0,0,0,.2);cursor:auto}.modaal-container.is_loading{height:100px;width:100px;overflow:hidden}.modaal-fullscreen .modaal-container{max-width:none;height:100%;overflow:auto}.modaal-close{position:fixed;right:20px;top:20px;color:#fff;cursor:pointer;opacity:1;width:50px;height:50px;background:rgba(0,0,0,0);border-radius:100%;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.modaal-close:focus,.modaal-close:hover{outline:0;background:#fff}.modaal-close:focus:after,.modaal-close:focus:before,.modaal-close:hover:after,.modaal-close:hover:before{background:#b93d0c}.modaal-close span{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.modaal-close:after,.modaal-close:before{display:block;content:" ";position:absolute;top:14px;left:23px;width:4px;height:22px;border-radius:4px;background:#fff;-webkit-transition:background .2s ease-in-out;transition:background .2s ease-in-out}.modaal-close:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.modaal-close:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.modaal-fullscreen .modaal-close{background:#afb7bc;right:10px;top:10px}.modaal-content-container{padding:30px}.modaal-confirm-wrap{padding:30px 0 0;text-align:center;font-size:0}.modaal-confirm-btn{font-size:14px;display:inline-block;margin:0 10px;vertical-align:middle;cursor:pointer;border:none;background:0 0}.modaal-confirm-btn.modaal-ok{padding:10px 15px;color:#fff;background:#555;border-radius:3px;-webkit-transition:background .2s ease-in-out;transition:background .2s ease-in-out}.modaal-confirm-btn.modaal-ok:hover{background:#2f2f2f}.modaal-confirm-btn.modaal-cancel{text-decoration:underline}.modaal-confirm-btn.modaal-cancel:hover{text-decoration:none;color:#2f2f2f}.modaal-instagram .modaal-container{width:auto;background:0 0;box-shadow:none!important}.modaal-instagram .modaal-content-container{padding:0;background:0 0}.modaal-instagram .modaal-content-container>blockquote{width:1px!important;height:1px!important;opacity:0!important}.modaal-instagram iframe{opacity:0;margin:-6px!important;border-radius:0!important;width:1000px!important;max-width:800px!important;box-shadow:none!important;-webkit-animation:instaReveal 1s linear forwards;animation:instaReveal 1s linear forwards}.modaal-image .modaal-inner-wrapper{padding-left:140px;padding-right:140px}.modaal-image .modaal-container{width:auto;max-width:100%}.modaal-gallery-wrap{position:relative;color:#fff}.modaal-gallery-item{display:none}.modaal-gallery-item img{display:block}.modaal-gallery-item.is_active{display:block}.modaal-gallery-label{position:absolute;left:0;width:100%;margin:20px 0 0;font-size:18px;text-align:center;color:#fff}.modaal-gallery-label:focus{outline:0}.modaal-gallery-control{position:absolute;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);opacity:1;cursor:pointer;color:#fff;width:50px;height:50px;background:rgba(0,0,0,0);border:none;border-radius:100%;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.modaal-gallery-control.is_hidden{opacity:0;cursor:default}.modaal-gallery-control:focus,.modaal-gallery-control:hover{outline:0;background:#fff}.modaal-gallery-control:focus:after,.modaal-gallery-control:focus:before,.modaal-gallery-control:hover:after,.modaal-gallery-control:hover:before{background:#afb7bc}.modaal-gallery-control span{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.modaal-gallery-control:after,.modaal-gallery-control:before{display:block;content:" ";position:absolute;top:16px;left:25px;width:4px;height:18px;border-radius:4px;background:#fff;-webkit-transition:background .2s ease-in-out;transition:background .2s ease-in-out}.modaal-gallery-control:before{margin:-5px 0 0;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.modaal-gallery-control:after{margin:5px 0 0;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.modaal-gallery-next-inner{left:100%;margin-left:40px}.modaal-gallery-next-outer{right:45px}.modaal-gallery-prev:after,.modaal-gallery-prev:before{left:22px}.modaal-gallery-prev:before{margin:5px 0 0;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.modaal-gallery-prev:after{margin:-5px 0 0;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.modaal-gallery-prev-inner{right:100%;margin-right:40px}.modaal-gallery-prev-outer{left:45px}.modaal-video-wrap{margin:auto 50px;position:relative}.modaal-video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%;box-shadow:0 0 10px rgba(0,0,0,.3);background:#000;max-width:1300px;margin-left:auto;margin-right:auto}.modaal-video-container embed,.modaal-video-container iframe,.modaal-video-container object{position:absolute;top:0;left:0;width:100%;height:100%}.modaal-iframe .modaal-content{width:100%;height:100%}.modaal-iframe-elem{width:100%;height:100%;display:block}.modaal-loading-spinner{background:0 0;position:absolute;width:200px;height:200px;top:50%;left:50%;margin:-100px 0 0 -100px;-webkit-transform:scale(.25);-ms-transform:scale(.25);transform:scale(.25)}.modaal-loading-spinner>div{width:24px;height:24px;margin-left:4px;margin-top:4px;position:absolute}.modaal-loading-spinner>div>div{width:100%;height:100%;border-radius:15px;background:#fff}.modaal-loading-spinner>div:nth-of-type(1)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:0s;animation-delay:0s}.modaal-loading-spinner>div:nth-of-type(2)>div,.modaal-loading-spinner>div:nth-of-type(3)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(1){-ms-transform:translate(84px,84px) rotate(45deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(45deg) translate(70px,0);transform:translate(84px,84px) rotate(45deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(2)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.12s;animation-delay:.12s}.modaal-loading-spinner>div:nth-of-type(2){-ms-transform:translate(84px,84px) rotate(90deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(90deg) translate(70px,0);transform:translate(84px,84px) rotate(90deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(3)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.25s;animation-delay:.25s}.modaal-loading-spinner>div:nth-of-type(4)>div,.modaal-loading-spinner>div:nth-of-type(5)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(3){-ms-transform:translate(84px,84px) rotate(135deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(135deg) translate(70px,0);transform:translate(84px,84px) rotate(135deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(4)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.37s;animation-delay:.37s}.modaal-loading-spinner>div:nth-of-type(4){-ms-transform:translate(84px,84px) rotate(180deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(180deg) translate(70px,0);transform:translate(84px,84px) rotate(180deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(5)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.5s;animation-delay:.5s}.modaal-loading-spinner>div:nth-of-type(6)>div,.modaal-loading-spinner>div:nth-of-type(7)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(5){-ms-transform:translate(84px,84px) rotate(225deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(225deg) translate(70px,0);transform:translate(84px,84px) rotate(225deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(6)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.62s;animation-delay:.62s}.modaal-loading-spinner>div:nth-of-type(6){-ms-transform:translate(84px,84px) rotate(270deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(270deg) translate(70px,0);transform:translate(84px,84px) rotate(270deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(7)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.75s;animation-delay:.75s}.modaal-loading-spinner>div:nth-of-type(7){-ms-transform:translate(84px,84px) rotate(315deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(315deg) translate(70px,0);transform:translate(84px,84px) rotate(315deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(8)>div{-webkit-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-webkit-animation-delay:.87s;animation-delay:.87s}.modaal-loading-spinner>div:nth-of-type(8){-ms-transform:translate(84px,84px) rotate(360deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(360deg) translate(70px,0);transform:translate(84px,84px) rotate(360deg) translate(70px,0)}@media only screen and (min-width:1400px){.modaal-video-container{padding-bottom:0;height:731px}}@media only screen and (max-width:1140px){.modaal-image .modaal-inner-wrapper{padding-left:25px;padding-right:25px}.modaal-gallery-control{top:auto;bottom:20px;-webkit-transform:none;-ms-transform:none;transform:none;background:rgba(0,0,0,.7)}.modaal-gallery-control:after,.modaal-gallery-control:before{background:#fff}.modaal-gallery-next{left:auto;right:20px}.modaal-gallery-prev{left:20px;right:auto}}@media screen and (max-width:900px){.modaal-instagram iframe{width:500px!important}}@media only screen and (max-width:600px){.modaal-instagram iframe{width:280px!important}}@media screen and (max-height:1100px){.modaal-instagram iframe{width:700px!important}}@media screen and (max-height:1000px){.modaal-inner-wrapper{padding-top:60px;padding-bottom:60px}.modaal-instagram iframe{width:600px!important}}@media screen and (max-height:900px){.modaal-instagram iframe{width:500px!important}.modaal-video-container{max-width:900px;max-height:510px}}@media only screen and (max-height:820px){.modaal-gallery-label{display:none}}@keyframes instaReveal{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes instaReveal{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}}@keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}}
\ No newline at end of file
/*!
Modaal - accessible modals - v0.4.4
by Humaan, for all humans.
http://humaan.com
*/
// Modaal Variables
// --------------------------------------------------------
$modaal-overlay-color: rgba(0,0,0, 0.8);
$modaal-radius: 0px; //5px
$modaal-main-bg: #fff;
$modaal-main-text: #000;
$modaal-max-width: 1000px;
$modaal-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
$modaal-padding: 30px;
$modaal-hover-color: rgba(0,0,0, 0.7);
$modaal-close-hover-color: #b93d0c;
$modaal-light: #fff;
$modaal-primary: #555;
$modaal-grey: #afb7bc;
// Modaal Mixins
// --------------------------------------------------------
@mixin modaal-transition($type, $speed: .2s, $ease: ease-in-out) {
transition: $type #{$speed} #{$ease};
}
@mixin modaal-hidetext() {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
// Modaal Structure
// --------------------------------------------------------
.modaal-noscroll {
overflow: hidden;
}
.modaal-accessible-hide {
@include modaal-hidetext;
}
.modaal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
opacity: 0;
}
.modaal-wrapper {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
overflow: auto;
opacity: 1;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
@include modaal-transition(all, 0.3s);
& * {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-backface-visibility: hidden;
}
.modaal-close {
border: none;
background: transparent;
padding: 0;
-webkit-appearance: none;
}
&.modaal-start_none {
display: none;
opacity: 1;
}
&.modaal-start_fade {
opacity: 0;
}
& *[tabindex="0"] {
outline: none !important;
}
// is fullscreen
&.modaal-fullscreen {
overflow: hidden;
}
}
.modaal-outer-wrapper {
display: table;
position: relative;
width: 100%;
height: 100%;
.modaal-fullscreen & {
display: block;
}
}
.modaal-inner-wrapper {
display: table-cell;
width: 100%;
height: 100%;
position: relative;
vertical-align: middle;
text-align: center;
padding: 80px 25px;
// when is fullscreen
.modaal-fullscreen & {
padding: 0;
display: block;
vertical-align: top;
}
}
.modaal-container {
position: relative;
display: inline-block;
width: 100%;
margin: auto;
text-align: left;
color: $modaal-main-text;
max-width: $modaal-max-width;
border-radius: $modaal-radius;
background: $modaal-main-bg;
box-shadow: $modaal-shadow;
cursor: auto;
// while loading
&.is_loading {
height: 100px;
width: 100px;
overflow: hidden;
}
// when is fullscreen
.modaal-fullscreen & {
max-width: none;
height: 100%;
overflow: auto;
}
}
.modaal-close {
position: fixed;
right: 20px;
top: 20px;
color: $modaal-light;
cursor: pointer;
opacity: 1;
width: 50px;
height: 50px;
background: rgba(0,0,0, 0);
border-radius: 100%;
@include modaal-transition(all);
&:focus,
&:hover {
outline: none;
background: #fff;
&:before,
&:after { background: $modaal-close-hover-color; }
}
span {
@include modaal-hidetext;
}
&:before,
&:after {
display: block;
content: " ";
position: absolute;
top: 14px;
left: 23px;
width: 4px;
height: 22px;
border-radius: 4px;
background: #fff;
@include modaal-transition(background);
}
&:before {
transform: rotate(-45deg);
}
&:after {
transform: rotate(45deg);
}
.modaal-fullscreen & {
background: $modaal-grey;
right: 10px;
top: 10px;
}
}
.modaal-content-container {
padding: $modaal-padding;
}
// Confirm Modaal
// --------------------------------------------------------
.modaal-confirm-wrap {
padding: 30px 0 0;
text-align: center;
font-size: 0;
}
.modaal-confirm-btn {
font-size: 14px;
display: inline-block;
margin: 0 10px;
vertical-align: middle;
cursor: pointer;
border: none;
background: transparent;
// Ok Button
&.modaal-ok {
padding: 10px 15px;
color: $modaal-light;
background: $modaal-primary;
border-radius: 3px;
@include modaal-transition(background);
&:hover {
background: darken($modaal-primary, 15%);
}
}
&.modaal-cancel {
text-decoration: underline;
&:hover {
text-decoration: none;
color: darken($modaal-primary, 15%);
}
}
}
@keyframes instaReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-o-keyframes instaReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-moz-keyframes instaReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-webkit-keyframes instaReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-ms-keyframes instaReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
// Instagram Photo
// --------------------------------------------------------
.modaal-instagram {
.modaal-container {
width: auto;
background: transparent;
box-shadow: none !important;
}
.modaal-content-container {
padding: 0;
background: transparent;
}
.modaal-content-container > blockquote {
width: 1px !important;
height: 1px !important;
opacity: 0 !important;
}
iframe {
opacity: 0;
margin: -6px !important;
border-radius: 0 !important;
width: 1000px !important;
max-width: 800px !important;
box-shadow: none !important;
animation: instaReveal 1s linear forwards;
}
}
// Gallery
// --------------------------------------------------------
.modaal-image {
.modaal-inner-wrapper {
padding-left: 140px;
padding-right: 140px;
}
.modaal-container {
width: auto;
max-width: 100%;
}
}
.modaal-gallery-wrap {
position: relative;
color: $modaal-light;
}
.modaal-gallery-item {
display: none;
img {
display: block;
//width: 100%;
}
&.is_active {
display: block;
}
}
.modaal-gallery-label {
position: absolute;
left: 0;
width: 100%;
margin: 20px 0 0;
font-size: 18px;
text-align: center;
color: #fff;
&:focus {
outline: none;
}
}
.modaal-gallery-control {
position: absolute;
top: 50%;
transform: translateY(-50%);
opacity: 1;
cursor: pointer;
color: $modaal-light;
width: 50px;
height: 50px;
background: rgba(0,0,0, 0);
border: none;
border-radius: 100%;
@include modaal-transition(all);
&.is_hidden {
opacity: 0;
cursor: default;
}
&:focus,
&:hover {
outline: none;
background: #fff;
&:before,
&:after {
background: $modaal-grey;
}
}
span {
@include modaal-hidetext;
}
&:before,
&:after {
display: block;
content: " ";
position: absolute;
top: 16px;
left: 25px;
width: 4px;
height: 18px;
border-radius: 4px;
background: #fff;
@include modaal-transition(background);
}
&:before {
margin: -5px 0 0;
transform: rotate(-45deg);
}
&:after {
margin: 5px 0 0;
transform: rotate(45deg);
}
}
.modaal-gallery-next {
&-inner {
left: 100%;
margin-left: 40px;
}
&-outer {
right: 45px;
}
}
.modaal-gallery-prev {
&:before,
&:after { left: 22px; }
&:before {
margin: 5px 0 0;
transform: rotate(-45deg);
}
&:after {
margin: -5px 0 0;
transform: rotate(45deg);
}
&-inner {
right: 100%;
margin-right: 40px;
}
&-outer {
left: 45px;
}
}
// Video
// --------------------------------------------------------
.modaal-video-wrap {
margin: auto 50px;
position: relative;
}
.modaal-video-container {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
max-width: 100%;
box-shadow: 0 0 10px rgba(0,0,0, 0.3);
background: #000;
max-width: 1300px;
margin-left: auto;
margin-right: auto;
iframe,
object,
embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
// Modaal iFrame
// --------------------------------------------------------
.modaal-iframe .modaal-content {
width: 100%;
height: 100%;
}
.modaal-iframe-elem {
width: 100%;
height: 100%;
display: block;
}
// Responsive styles
// --------------------------------------------------------
@media only screen and (min-width: 1400px) {
.modaal-video-container {
padding-bottom: 0;
height: 731px;
}
}
@media only screen and (max-width: 1140px) {
.modaal-image {
.modaal-inner-wrapper {
padding-left: 25px;
padding-right: 25px;
}
}
.modaal-gallery-control {
top: auto;
bottom: 20px;
transform: none;
background: rgba(0,0,0, 0.7);;
&:before,
&:after {
background: #fff;
}
}
.modaal-gallery-next {
left: auto;
right: 20px;
}
.modaal-gallery-prev {
left: 20px;
right: auto;
}
}
@media screen and (max-width: 900px) {
.modaal-instagram iframe {
width: 500px !important;
}
}
@media screen and (max-height: 1100px) {
.modaal-instagram iframe {
width: 700px !important;
}
}
@media screen and (max-height: 1000px) {
.modaal-inner-wrapper {
padding-top: 60px;
padding-bottom: 60px;
}
.modaal-instagram iframe {
width: 600px !important;
}
}
@media screen and (max-height: 900px) {
.modaal-instagram iframe {
width: 500px !important;
}
.modaal-video-container {
max-width: 900px;
max-height: 510px;
}
}
@media only screen and (max-width: 600px) {
.modaal-instagram iframe {
width: 280px !important;
}
}
@media only screen and (max-height: 820px) {
.modaal-gallery-label {
display: none;
}
}
// CSS loading gif
// --------------------------------------------------------
.modaal-loading-spinner {
background: none;
position: absolute;
width: 200px;
height: 200px;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
transform: scale(0.25);
}
@-ms-keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-moz-transform:scale(1.5);-webkit-transform:scale(1.5);-o-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-moz-keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-moz-transform:scale(1.5);-webkit-transform:scale(1.5);-o-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-webkit-keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-moz-transform:scale(1.5);-webkit-transform:scale(1.5);-o-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-o-keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-moz-transform:scale(1.5);-webkit-transform:scale(1.5);-o-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes modaal-loading-spinner{0%{opacity:1;-ms-transform:scale(1.5);-moz-transform:scale(1.5);-webkit-transform:scale(1.5);-o-transform:scale(1.5);transform:scale(1.5)}100%{opacity:.1;-ms-transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.modaal-loading-spinner>div{width:24px;height:24px;margin-left:4px;margin-top:4px;position:absolute}.modaal-loading-spinner>div>div{width:100%;height:100%;border-radius:15px;background:#fff}.modaal-loading-spinner>div:nth-of-type(1)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:0s;-moz-animation-delay:0s;-webkit-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s}.modaal-loading-spinner>div:nth-of-type(2)>div,.modaal-loading-spinner>div:nth-of-type(3)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(1){-ms-transform:translate(84px,84px) rotate(45deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(45deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(45deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(45deg) translate(70px,0);transform:translate(84px,84px) rotate(45deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(2)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.12s;-moz-animation-delay:.12s;-webkit-animation-delay:.12s;-o-animation-delay:.12s;animation-delay:.12s}.modaal-loading-spinner>div:nth-of-type(2){-ms-transform:translate(84px,84px) rotate(90deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(90deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(90deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(90deg) translate(70px,0);transform:translate(84px,84px) rotate(90deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(3)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.25s;-moz-animation-delay:.25s;-webkit-animation-delay:.25s;-o-animation-delay:.25s;animation-delay:.25s}.modaal-loading-spinner>div:nth-of-type(4)>div,.modaal-loading-spinner>div:nth-of-type(5)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(3){-ms-transform:translate(84px,84px) rotate(135deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(135deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(135deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(135deg) translate(70px,0);transform:translate(84px,84px) rotate(135deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(4)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.37s;-moz-animation-delay:.37s;-webkit-animation-delay:.37s;-o-animation-delay:.37s;animation-delay:.37s}.modaal-loading-spinner>div:nth-of-type(4){-ms-transform:translate(84px,84px) rotate(180deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(180deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(180deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(180deg) translate(70px,0);transform:translate(84px,84px) rotate(180deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(5)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.5s;-moz-animation-delay:.5s;-webkit-animation-delay:.5s;-o-animation-delay:.5s;animation-delay:.5s}.modaal-loading-spinner>div:nth-of-type(6)>div,.modaal-loading-spinner>div:nth-of-type(7)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite}.modaal-loading-spinner>div:nth-of-type(5){-ms-transform:translate(84px,84px) rotate(225deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(225deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(225deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(225deg) translate(70px,0);transform:translate(84px,84px) rotate(225deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(6)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.62s;-moz-animation-delay:.62s;-webkit-animation-delay:.62s;-o-animation-delay:.62s;animation-delay:.62s}.modaal-loading-spinner>div:nth-of-type(6){-ms-transform:translate(84px,84px) rotate(270deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(270deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(270deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(270deg) translate(70px,0);transform:translate(84px,84px) rotate(270deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(7)>div{animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.75s;-moz-animation-delay:.75s;-webkit-animation-delay:.75s;-o-animation-delay:.75s;animation-delay:.75s}.modaal-loading-spinner>div:nth-of-type(7){-ms-transform:translate(84px,84px) rotate(315deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(315deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(315deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(315deg) translate(70px,0);transform:translate(84px,84px) rotate(315deg) translate(70px,0)}.modaal-loading-spinner>div:nth-of-type(8)>div{-ms-animation:modaal-loading-spinner 1s linear infinite;-moz-animation:modaal-loading-spinner 1s linear infinite;-webkit-animation:modaal-loading-spinner 1s linear infinite;-o-animation:modaal-loading-spinner 1s linear infinite;animation:modaal-loading-spinner 1s linear infinite;-ms-animation-delay:.87s;-moz-animation-delay:.87s;-webkit-animation-delay:.87s;-o-animation-delay:.87s;animation-delay:.87s}.modaal-loading-spinner>div:nth-of-type(8){-ms-transform:translate(84px,84px) rotate(360deg) translate(70px,0);-moz-transform:translate(84px,84px) rotate(360deg) translate(70px,0);-webkit-transform:translate(84px,84px) rotate(360deg) translate(70px,0);-o-transform:translate(84px,84px) rotate(360deg) translate(70px,0);transform:translate(84px,84px) rotate(360deg) translate(70px,0)}
/*!
Modaal - accessible modals - v0.4.4
by Humaan, for all humans.
http://humaan.com
*/
/**
Modaal jQuery Plugin : Accessible Modals
==== General Options ===
type (string) : ajax, inline, image, iframe, confirm. Defaults to 'inline'
content_source (stribg) : Accepts a string value for your target element, such as '#my-content'. This allows for when trigger element is
an `<a href="#">` link. Not to be confused with the already existing `source` event.
animation (string) : Fade, expand, down, up. Defaults to 'fade'
after_callback_delay (integer) : Specify a delay value for the after open callbacks. This is necessary because with the bundled animations
have a set duration in the bundled CSS. Specify a delay of the same amount as the animation duration in so
more accurately fire the after open/close callbacks. Defaults 350, does not apply if animation is 'none',
after open callbacks are dispatched immediately
is_locked (boolean) : Set this to true to disable closing the modal via keypress or clicking the background. Beware that if
type != 'confirm' there will be no interface to dismiss the modal if is_locked = true, you'd have to
programmatically arrange to dismiss the modal. Confirm modals are always locked regardless of this option
Defaults to false
hide_close (boolean) : Set this to true to hide the close modal button. Key press and overlay click will still close the modal.
This method is best used when you want to put a custom close button inside the modal container space.
background (string) : Background overlay style. Defaults to '#000'
overlay_opacity (float) : Background overlay transparency. Defaults to 0.8
overlay_close (boolean) : Set this to false if you want to disable click to close on overlay background.
accessible_title (string) : Accessible title. Default 'Dialog Window'
start_open (boolean) : Set this to true to launch the Modaal window immediately on page open
fullscreen (boolean) : Set this to true to make the modaal fill the entire screen, false will default to own width/height attributes.
custom_class (string) : Fill in this string with a custom class that will be applied to the outer most modal wrapper.
width (integer) : Desired width of the modal. Required for iframe type. Defaults to undefined //TODO
height (integer) : Desired height of the modal. Required for iframe type. Defaults to undefined //TODO
background_scroll (boolean) : Set this to true to enable the page to scroll behind the open modal.
should_open (boolean|function) : Boolean or closure that returns a boolean to determine whether to open the modal or not.
close_text : String for close button text. Available for localisation and alternative languages to be used.
close_aria_label : String for close button aria-label attribute (value that screen readers will read out). Available for localisation and alternative languages to be used.
=== Events ===
before_open (function) : Callback function executed before modal is opened
after_open (function) : Callback function executed after modal is opened
before_close (function) : Callback function executed before modal is closed
after_close (function) : Callback function executed after modal is closed
source (function(element, src)) : Callback function executed on the default source, it is intended to transform the
source (href in an AJAX modal or iframe). The function passes in the triggering element
as well as the default source depending of the modal type. The default output of the
function is an untransformed default source.
=== Confirm Options & Events ===
confirm_button_text (string) : Text on the confirm button. Defaults to 'Confirm'
confirm_cancel_button_text (string) : Text on the confirm modal cancel button. Defaults to 'Cancel'
confirm_title (string) : Title for confirm modal. Default 'Confirm Title'
confirm_content (string) : HTML content for confirm message
confirm_callback (function) : Callback function for when the confirm button is pressed as opposed to cancel
confirm_cancel_callback (function) : Callback function for when the cancel button is pressed
=== Gallery Options & Events ===
gallery_active_class (string) : Active class applied to the currently active image or image slide in a gallery 'gallery_active_item'
outer_controls (boolean) : Set to true to put the next/prev controls outside the Modaal wrapper, at the edges of the browser window.
before_image_change (function) : Callback function executed before the image slide changes in a gallery modal. Default function( current_item, incoming_item )
after_image_change (function) : Callback function executed after the image slide changes in a gallery modal. Default function ( current_item )
=== AJAX Options & Events ===
loading_content (string) : HTML content for loading message. Default 'Loading &hellip;'
loading_class (string) : Class name to be applied while content is loaded via AJAX. Default 'is_loading'
ajax_error_class (string) : Class name to be applied when content has failed to load. Default is 'modaal-error'
ajax_success (function) : Callback for when AJAX content is loaded in
=== SOCIAL CONTENT ===
instagram_id (string) : Unique photo ID for an Instagram photo.
*/
( function( $ ) {
var modaal_loading_spinner = '<div class="modaal-loading-spinner"><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div></div>'
var Modaal = {
init : function(options, elem) {
var self = this;
self.dom = $('body');
self.$elem = $(elem);
self.options = $.extend({}, $.fn.modaal.options, self.$elem.data(), options);
self.xhr = null;
// set up the scope
self.scope = {
is_open: false,
id: 'modaal_' + ( new Date().getTime() ) + ( Math.random().toString(16).substring(2) ),
source: self.options.content_source ? self.options.content_source : self.$elem.attr('href')
};
// add scope attribute to trigger element
self.$elem.attr('data-modaal-scope', self.scope.id);
// private options
self.private_options = {
active_class: 'is_active'
};
self.lastFocus = null;
// if is_locked
if ( self.options.is_locked || self.options.type == 'confirm' || self.options.hide_close ) {
self.scope.close_btn = '';
} else {
self.scope.close_btn = '<button type="button" class="modaal-close" id="modaal-close" aria-label="' + self.options.close_aria_label + '"><span>' + self.options.close_text + '</span></button>';
}
// reset animation_speed
if (self.options.animation === 'none' ){
self.options.animation_speed = 0;
self.options.after_callback_delay = 0;
}
// On click to open modal
$(elem).on('click.Modaal', function(e) {
e.preventDefault();
self.create_modaal(self, e);
});
// Define next/prev buttons
if (self.options.outer_controls === true) {
var mod_class = 'outer';
} else {
var mod_class = 'inner';
}
self.scope.prev_btn = '<button type="button" class="modaal-gallery-control modaal-gallery-prev modaal-gallery-prev-' + mod_class + '" id="modaal-gallery-prev" aria-label="Previous image (use left arrow to change)"><span>Previous Image</span></button>';
self.scope.next_btn = '<button type="button" class="modaal-gallery-control modaal-gallery-next modaal-gallery-next-' + mod_class + '" id="modaal-gallery-next" aria-label="Next image (use right arrow to change)"><span>Next Image</span></button>';
// Check for start_open
if (self.options.start_open === true ){
self.create_modaal( self );
}
},
// Initial create to determine which content type it requires
// ----------------------------------------------------------------
create_modaal : function(self, e) {
var self = this;
var source;
// Save last active state before modal
self.lastFocus = self.$elem;
if ( self.options.should_open === false || ( typeof self.options.should_open === 'function' && self.options.should_open() === false ) ) {
return;
}
// CB: before_open
self.options.before_open.call(self, e);
switch (self.options.type) {
case 'inline':
self.create_basic();
break;
case 'ajax':
source = self.options.source( self.$elem, self.scope.source );
self.fetch_ajax( source );
break;
case 'confirm':
self.options.is_locked = true;
self.create_confirm();
break;
case 'image':
self.create_image();
break;
case 'iframe':
source = self.options.source( self.$elem, self.scope.source );
self.create_iframe( source );
break;
case 'video':
self.create_video(self.scope.source);
break;
case 'instagram':
self.create_instagram();
break;
}
// call events to be watched (click, tab, keyup, keydown etc.)
self.watch_events();
},
// Watching Modal
// ----------------------------------------------------------------
watch_events : function() {
var self = this;
self.dom.off('click.Modaal keyup.Modaal keydown.Modaal');
// Body keydown
self.dom.on('keydown.Modaal', function(e) {
var key = e.keyCode;
var target = e.target;
// look for tab change and reset focus to modal window
// done in keydown so the check fires repeatedly when you hold the tab key down
if (key == 9 && self.scope.is_open) {
if (!$.contains(document.getElementById(self.scope.id), target) ) {
$('#' + self.scope.id).find('*[tabindex="0"]').focus();
}
}
});
// Body keyup
self.dom.on('keyup.Modaal', function(e) {
var key = e.keyCode;
var target = e.target;
if ( (e.shiftKey && e.keyCode == 9) && self.scope.is_open) {
// Watch for shift + tab key press. if open shift focus to close button.
if (!$.contains(document.getElementById(self.scope.id), target) ) {
$('#' + self.scope.id).find('.modaal-close').focus();
}
}
if ( !self.options.is_locked ){
// On escape key press close modal
if (key == 27 && self.scope.is_open ) {
if ( $(document.activeElement).is('input:not(:checkbox):not(:radio)') ) {
return false;
}
self.modaal_close();
return;
}
}
// is gallery open and images length is > 1
if ( self.options.type == 'image' ) {
// arrow left for back
if (key == 37 && self.scope.is_open && (!$('#' + self.scope.id + ' .modaal-gallery-prev').hasClass('is_hidden')) ) {
self.gallery_update('prev');
}
// arrow right for next
if (key == 39 && self.scope.is_open && (!$('#' + self.scope.id + ' .modaal-gallery-next').hasClass('is_hidden')) ) {
self.gallery_update('next');
}
return;
}
});
// Body click/touch
self.dom.on('click.Modaal', function(e) {
var trigger = $(e.target);
// General Controls: If it's not locked allow greedy close
if ( !self.options.is_locked ){
if ( (self.options.overlay_close && trigger.is('.modaal-inner-wrapper')) || trigger.is('.modaal-close') || trigger.closest('.modaal-close').length ) {
self.modaal_close();
return;
}
}
//Confirm Controls
if ( trigger.is('.modaal-confirm-btn' ) ){
// if 'OK' button is clicked, run confirm_callback()
if ( trigger.is('.modaal-ok') ) {
self.options.confirm_callback.call(self, self.lastFocus);
}
if ( trigger.is('.modaal-cancel') ) {
self.options.confirm_cancel_callback.call(self, self.lastFocus);
}
self.modaal_close();
return;
}
// Gallery Controls
if ( trigger.is( '.modaal-gallery-control' ) ){
// it not active, don't do nuthin!
if ( trigger.hasClass('is_hidden') ) {
return;
}
// trigger previous
if ( trigger.is('.modaal-gallery-prev') ) {
self.gallery_update('prev');
}
// trigger next
if ( trigger.is('.modaal-gallery-next') ) {
self.gallery_update('next');
}
return;
}
});
},
// Append markup into DOM
build_modal : function(content) {
var self = this;
// if is instagram
var igClass = '';
if ( self.options.type == 'instagram' ) {
igClass = ' modaal-instagram';
}
var wrap_class = (self.options.type == 'video') ? 'modaal-video-wrap' : 'modaal-content';
/*
modaal-start_none : fully hidden via display:none;
modaal-start_fade : hidden via opacity:0
modaal-start_slidedown : ...
*/
var animation_class;
switch ( self.options.animation ) {
case 'fade' :
animation_class = ' modaal-start_fade';
break;
case 'slide-down' :
animation_class = ' modaal-start_slidedown';
break;
default :
animation_class = ' modaal-start_none'
}
// fullscreen check
var fullscreen_class = '';
if ( self.options.fullscreen ) {
fullscreen_class = ' modaal-fullscreen';
}
// custom class check
if ( self.options.custom_class !== '' || typeof(self.options.custom_class) !== 'undefined' ) {
self.options.custom_class = ' ' + self.options.custom_class;
}
// if width and heights exists and is typeof number
var dimensionsStyle = '';
if ( self.options.width && self.options.height && typeof self.options.width == 'number' && typeof self.options.height == 'number' ) {
// if width and height exist, and they are both numbers
dimensionsStyle = ' style="max-width:' + self.options.width + 'px;height:' + self.options.height + 'px;overflow:auto;"';
} else if ( self.options.width && typeof self.options.width == 'number' ) {
// if only width
dimensionsStyle = ' style="max-width:' + self.options.width + 'px;"';
} else if ( self.options.height && typeof self.options.height == 'number' ) {
// if only height
dimensionsStyle = ' style="height:' + self.options.height + 'px;overflow:auto;"';
}
// Reset dimensions style (width and height) for certain types
if ( self.options.type == 'image' || self.options.type == 'video' || self.options.type == 'instagram' || self.options.fullscreen ) {
dimensionsStyle = '';
}
// if is touch
// this is a bug fix for iOS to allow regular click events on div elements.
var touchTrigger = '';
if ( self.is_touch() ) {
touchTrigger = ' style="cursor:pointer;"'
}
var build_markup = '<div class="modaal-wrapper modaal-' + self.options.type + animation_class + igClass + fullscreen_class + self.options.custom_class + '" id="' + self.scope.id + '"><div class="modaal-outer-wrapper"><div class="modaal-inner-wrapper"' + touchTrigger + '>';
// hide if video
if (self.options.type != 'video') {
build_markup += '<div class="modaal-container"' + dimensionsStyle + '>';
}
// add the guts of the content
build_markup += '<div class="' + wrap_class + ' modaal-focus" aria-hidden="false" aria-label="' + self.options.accessible_title + ' - ' + self.options.close_aria_label + '" role="dialog">';
// If it's inline type, we want to clone content instead of dropping it straight in
if (self.options.type == 'inline') {
build_markup += '<div class="modaal-content-container" role="document"></div>';
} else {
// Drop in the content if it's not inline
build_markup += content;
}
// close wrap_class
build_markup += '</div>' + self.scope.close_btn;
// hide if video
if (self.options.type != 'video') {
build_markup += '</div>';
}
// close off modaal-inner-wrapper
build_markup += '</div>';
// If type is image AND outer_controls is true: add gallery next and previous controls.
if (self.options.type == 'image' && self.options.outer_controls === true) {
build_markup += self.scope.prev_btn + self.scope.next_btn;
}
// close off modaal-wrapper
build_markup += '</div></div>';
// append ajax modal markup to dom
if ($('#' + self.scope.id + '_overlay').length < 1) {
self.dom.append(build_markup);
}
// if inline, clone content into space
if (self.options.type == 'inline') {
content.appendTo('#' + self.scope.id + ' .modaal-content-container');
}
// Trigger overlay show (which triggers modal show)
self.modaal_overlay('show');
},
// Create Basic Inline Modal
// ----------------------------------------------------------------
create_basic : function() {
var self = this;
var target = $(self.scope.source);
var content = '';
if (target.length) {
content = target.contents().detach();
target.empty();
} else {
content = 'Content could not be loaded. Please check the source and try again.';
}
// now push content into markup
self.build_modal(content);
},
// Create Instagram Modal
// ----------------------------------------------------------------
create_instagram : function() {
var self = this;
var id = self.options.instagram_id;
var content = '';
var error_msg = 'Instagram photo couldn\'t be loaded, please check the embed code and try again.';
self.build_modal('<div class="modaal-content-container' + ( self.options.loading_class != '' ? ' ' + self.options.loading_class : '' ) + '">' + self.options.loading_content + '</div>' );
// ID exists, is not empty null or undefined.
if ( id != '' && id !== null && id !== undefined ) {
// set up oembed url
var ig_url = 'https://api.instagram.com/oembed?url=http://instagr.am/p/' + id + '/';
$.ajax({
url: ig_url,
dataType: "jsonp",
cache: false,
success: function (data) {
// Create temp dom element from which we'll clone into the modaal instance. This is required to bypass the unusual small thumb issue instagram oembed was serving up
self.dom.append('<div id="temp-ig" style="width:0;height:0;overflow:hidden;">' + data.html + '</div>');
// Check if it has loaded once before.
// This is to stop the Embeds.process from throwing and error the first time it's being loaded.
// private_options are individual to a modaal_scope so will not work across multiple scopes when checking if true, only that one item.
if ( self.dom.attr('data-igloaded') ) {
window.instgrm.Embeds.process();
} else {
// first time it's loaded, let's set a new private option to use next time it's opened.
self.dom.attr('data-igloaded', 'true');
}
// now set location for new content
// timeout is required as well to bypass the unusual small thumb issue instagram oembed was serving up
var target = '#' + self.scope.id + ' .modaal-content-container';
if ( $(target).length > 0) {
setTimeout(function() {
$('#temp-ig').contents().clone().appendTo( target );
$('#temp-ig').remove();
}, 1000);
}
},
error: function() {
content = error_msg;
// now set location for new content
var target = $('#' + self.scope.id + ' .modaal-content-container');
if ( target.length > 0) {
target.removeClass( self.options.loading_class ).addClass( self.options.ajax_error_class );
target.html(content);
}
}
});
} else {
content = error_msg;
}
return false;
},
// Fetch Ajax Data
// ----------------------------------------------------------------
fetch_ajax : function(url) {
var self = this;
var content = '';
// If no accessible title, set it to 'Dialog Window'
if ( self.options.accessible_title == null ) {
self.options.accessible_title = 'Dialog Window'
}
if ( self.xhr !== null ){
self.xhr.abort();
self.xhr = null;
}
self.build_modal('<div class="modaal-content-container' + ( self.options.loading_class != '' ? ' ' + self.options.loading_class : '' ) + '">' + self.options.loading_content + '</div>' );
self.xhr = $.ajax(url, {
success: function(data) {
// content fetch is successful so push it into markup
var target = $('#' + self.scope.id).find('.modaal-content-container');
if ( target.length > 0){
target.removeClass( self.options.loading_class );
target.html( data );
self.options.ajax_success.call(self, target);
}
},
error: function( xhr ) {
// There were some errors so return an error message
if ( xhr.statusText == 'abort' ){
return;
}
var target = $('#' + self.scope.id + ' .modaal-content-container');
if ( target.length > 0){
target.removeClass( self.options.loading_class ).addClass( self.options.ajax_error_class );
target.html( 'Content could not be loaded. Please check the source and try again.' );
}
}
});
},
// Create Confirm Modal
// ----------------------------------------------------------------
create_confirm : function() {
var self = this;
var content;
content = '<div class="modaal-content-container">' +
'<h1 id="modaal-title">' + self.options.confirm_title + '</h1>' +
'<div class="modaal-confirm-content">' + self.options.confirm_content + '</div>' +
'<div class="modaal-confirm-wrap">' +
'<button type="button" class="modaal-confirm-btn modaal-ok" aria-label="Confirm">' + self.options.confirm_button_text + '</button>' +
'<button type="button" class="modaal-confirm-btn modaal-cancel" aria-label="Cancel">' + self.options.confirm_cancel_button_text + '</button>' +
'</div>' +
'</div>' +
'</div>';
// now push content into markup
self.build_modal(content);
},
// Create Image/Gallery Modal
// ----------------------------------------------------------------
create_image : function() {
var self = this;
var content;
var modaal_image_markup = '';
var gallery_total;
// If has group attribute
if ( self.$elem.is('[data-group]') || self.$elem.is('[rel]') ) {
// find gallery groups
var use_group = self.$elem.is('[data-group]');
var gallery_group = use_group ? self.$elem.attr('data-group') : self.$elem.attr('rel');
var gallery_group_items = use_group ? $('[data-group="' + gallery_group + '"]') : $('[rel="' + gallery_group + '"]');
// remove any previous active attribute to any in the group
gallery_group_items.removeAttr('data-gallery-active', 'is_active');
// add active attribute to the item clicked
self.$elem.attr('data-gallery-active', 'is_active');
// how many in the grouping are there (-1 to connect with each function starting with 0)
gallery_total = gallery_group_items.length - 1;
// prepare array for gallery data
var gallery = [];
// start preparing markup
modaal_image_markup = '<div class="modaal-gallery-item-wrap">';
// loop each grouping item and push it into our gallery array
gallery_group_items.each(function(i, item) {
// setup default content
var img_src = '';
var img_alt = '';
var img_description = '';
var img_active = false;
var img_src_error = false;
var data_modaal_desc = item.getAttribute('data-modaal-desc');
var data_item_active = item.getAttribute('data-gallery-active');
// if item has inline custom source, use that instead of href. Fall back to href if available.
if ( $(item).attr('data-modaal-content-source') ) {
img_src = $(item).attr('data-modaal-content-source');
} else if ( $(item).attr('href') ) {
img_src = $(item).attr('href');
} else if ( $(item).attr('src') ) {
img_src = $(item).attr('src');
} else {
img_src = 'trigger requires href or data-modaal-content-source attribute';
img_src_error = true;
}
// Does it have a modaal description
if ( data_modaal_desc != '' && data_modaal_desc !== null && data_modaal_desc !== undefined ) {
img_alt = data_modaal_desc;
img_description = '<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image ' + (i+1) + ' - </span>' + data_modaal_desc.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>'
} else {
img_description = '<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image ' + (i+1) + '</span></div>';
}
// is it the active item
if ( data_item_active ) {
img_active = true
}
// set new object for values we want
var gallery_item = {
'url': img_src,
'alt': img_alt,
'rawdesc': data_modaal_desc,
'desc': img_description,
'active': img_active,
'src_error': img_src_error
};
// push object into gallery array
gallery.push( gallery_item );
});
// now loop through all items in the gallery and build up the markup
for (var i = 0; i < gallery.length; i++) {
// Set default active class, then check if array item active is true and update string for class
var is_active = '';
var aria_label = gallery[i].rawdesc ? 'Image: ' + gallery[i].rawdesc : 'Image ' + i + ' no description';
if ( gallery[i].active ) {
is_active = ' ' + self.private_options.active_class;
}
// if gallery item has source error, output message rather than undefined image
var image_output = gallery[i].src_error ? gallery[i].url : '<img src="' + gallery[i].url + '" alt=" " style="width:100%">';
// for each item build up the markup
modaal_image_markup += '<div class="modaal-gallery-item gallery-item-' + i + is_active + '" aria-label="' + aria_label + '">' +
image_output + gallery[i].desc +
'</div>';
}
// Close off the markup for the gallery
modaal_image_markup += '</div>';
// Add next and previous buttons if outside
if (self.options.outer_controls != true) {
modaal_image_markup += self.scope.prev_btn + self.scope.next_btn;
}
} else {
// This is only a single gallery item so let's grab the necessary values
// define the source, check if content_source option exists, and use that or fall back to href.
var this_img_src;
var img_src_error = false;
if ( self.$elem.attr('data-modaal-content-source') ) {
this_img_src = self.$elem.attr('data-modaal-content-source');
} else if ( self.$elem.attr('href') ) {
this_img_src = self.$elem.attr('href');
} else if ( self.$elem.attr('src') ) {
this_img_src = self.$elem.attr('src');
} else {
this_img_src = 'trigger requires href or data-modaal-content-source attribute';
img_src_error = true;
}
var this_img_alt_txt = '';
var this_img_alt = '';
var aria_label = '';
if ( self.$elem.attr('data-modaal-desc') ) {
aria_label = self.$elem.attr('data-modaal-desc');
this_img_alt_txt = self.$elem.attr('data-modaal-desc');
this_img_alt = '<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image - </span>' + this_img_alt_txt.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>';
} else {
aria_label = "Image with no description";
}
// if image item has source error, output message rather than undefined image
var image_output = img_src_error ? this_img_src : '<img src="' + this_img_src + '" alt=" " style="width:100%">';
// build up the html
modaal_image_markup = '<div class="modaal-gallery-item is_active" aria-label="' + aria_label + '">' +
image_output + this_img_alt +
'</div>';
}
// Update content variable
content = modaal_image_markup;
// now push content into markup
self.build_modal(content);
// setup next & prev buttons
if ( $('.modaal-gallery-item.is_active').is('.gallery-item-0') ) {
$('.modaal-gallery-prev').hide();
}
if ( $('.modaal-gallery-item.is_active').is('.gallery-item-' + gallery_total) ) {
$('.modaal-gallery-next').hide();
}
},
// Gallery Change Image
// ----------------------------------------------------------------
gallery_update : function(direction) {
var self = this;
var this_gallery = $('#' + self.scope.id);
var this_gallery_item = this_gallery.find('.modaal-gallery-item');
var this_gallery_total = this_gallery_item.length - 1;
// if single item, don't proceed
if ( this_gallery_total == 0 ) {
return false;
}
var prev_btn = this_gallery.find('.modaal-gallery-prev'),
next_btn = this_gallery.find('.modaal-gallery-next');
var duration = 250;
var new_img_w = 0,
new_img_h = 0;
// CB: Before image change
var current_item = this_gallery.find( '.modaal-gallery-item.' + self.private_options.active_class ),
incoming_item = ( direction == 'next' ? current_item.next( '.modaal-gallery-item' ) : current_item.prev( '.modaal-gallery-item' ) );
self.options.before_image_change.call(self, current_item, incoming_item);
// stop change if at start of end
if ( direction == 'prev' && this_gallery.find('.gallery-item-0').hasClass('is_active') ) {
return false;
} else if ( direction == 'next' && this_gallery.find('.gallery-item-' + this_gallery_total).hasClass('is_active') ) {
return false;
}
// lock dimensions
current_item.stop().animate({
opacity: 0
}, duration, function(){
// Move to appropriate image
incoming_item.addClass('is_next').css({
'position': 'absolute',
'display': 'block',
'opacity': 0
});
// Collect doc width
var doc_width = $(document).width();
var width_threshold = doc_width > 1140 ? 280 : 50;
// start toggle to 'is_next'
new_img_w = this_gallery.find('.modaal-gallery-item.is_next').width();
new_img_h = this_gallery.find('.modaal-gallery-item.is_next').height();
var new_natural_w = this_gallery.find('.modaal-gallery-item.is_next img').prop('naturalWidth');
var new_natural_h = this_gallery.find('.modaal-gallery-item.is_next img').prop('naturalHeight');
// if new image is wider than doc width
if ( new_natural_w > (doc_width - width_threshold) ) {
// set new width just below doc width
new_img_w = doc_width - width_threshold;
// Set temp widths so we can calulate the correct height;
this_gallery.find('.modaal-gallery-item.is_next').css({ 'width': new_img_w });
this_gallery.find('.modaal-gallery-item.is_next img').css({ 'width': new_img_w });
// Set new height variable
new_img_h = this_gallery.find('.modaal-gallery-item.is_next').find('img').height();
} else {
// new img is not wider than screen, so let's set the new dimensions
new_img_w = new_natural_w;
new_img_h = new_natural_h;
}
// resize gallery region
this_gallery.find('.modaal-gallery-item-wrap').stop().animate({
'width': new_img_w,
'height': new_img_h
}, duration, function() {
// hide old active image
current_item.removeClass(self.private_options.active_class + ' ' + self.options.gallery_active_class).removeAttr('style');
current_item.find('img').removeAttr('style');
// show new image
incoming_item.addClass(self.private_options.active_class + ' ' + self.options.gallery_active_class).removeClass('is_next').css('position','');
// animate in new image (now has the normal is_active class
incoming_item.stop().animate({
opacity: 1
}, duration, function(){
$(this).removeAttr('style').css({
'width': '100%'
});
$(this).find('img').css('width', '100%');
// remove dimension lock
this_gallery.find('.modaal-gallery-item-wrap').removeAttr('style');
// CB: After image change
self.options.after_image_change.call( self, incoming_item );
});
// Focus on the new gallery item
this_gallery.find('.modaal-gallery-item').removeAttr('tabindex');
this_gallery.find('.modaal-gallery-item.' + self.private_options.active_class + '').attr('tabindex', '0').focus();
// hide/show next/prev
if ( this_gallery.find('.modaal-gallery-item.' + self.private_options.active_class).is('.gallery-item-0') ) {
prev_btn.stop().animate({
opacity: 0
}, 150, function(){
$(this).hide();
});
} else {
prev_btn.stop().css({
'display': 'block',
'opacity': prev_btn.css('opacity')
}).animate({
opacity: 1
}, 150);
}
if ( this_gallery.find('.modaal-gallery-item.' + self.private_options.active_class).is('.gallery-item-' + this_gallery_total) ) {
next_btn.stop().animate({
opacity: 0
}, 150, function(){
$(this).hide();
});
} else {
next_btn.stop().css({
'display': 'block',
'opacity': prev_btn.css('opacity')
}).animate({
opacity: 1
}, 150);
}
});
});
},
// Create Video Modal
// ----------------------------------------------------------------
create_video : function(url) {
var self = this;
var content;
// video markup
content = '<iframe src="' + url + '" class="modaal-video-frame" frameborder="0" allowfullscreen></iframe>';
// now push content into markup
self.build_modal('<div class="modaal-video-container">' + content + '</div>');
},
// Create iFrame Modal
// ----------------------------------------------------------------
create_iframe : function(url) {
var self = this;
var content;
if ( self.options.width !== null || self.options.width !== undefined || self.options.height !== null || self.options.height !== undefined ) {
// video markup
content = '<iframe src="' + url + '" class="modaal-iframe-elem" frameborder="0" allowfullscreen></iframe>';
} else {
content = '<div class="modaal-content-container">Please specify a width and height for your iframe</div>';
}
// now push content into markup
self.build_modal(content);
},
// Open Modaal
// ----------------------------------------------------------------
modaal_open : function() {
var self = this;
var modal_wrapper = $( '#' + self.scope.id );
var animation_type = self.options.animation;
if (animation_type === 'none' ){
modal_wrapper.removeClass('modaal-start_none');
self.options.after_open.call(self, modal_wrapper);
}
// Open with fade
if (animation_type === 'fade') {
modal_wrapper.removeClass('modaal-start_fade');
}
// Open with slide down
if (animation_type === 'slide-down') {
modal_wrapper.removeClass('modaal-start_slide_down');
}
var focusTarget = modal_wrapper;
// Switch focusTarget tabindex (switch from other modal if exists)
$('.modaal-wrapper *[tabindex=0]').removeAttr('tabindex');
if ( self.options.type == 'image' ) {
focusTarget = $('#' + self.scope.id).find('.modaal-gallery-item.' + self.private_options.active_class);
} else if ( modal_wrapper.find('.modaal-iframe-elem').length ) {
focusTarget = modal_wrapper.find('.modaal-iframe-elem');
} else if ( modal_wrapper.find('.modaal-video-wrap').length ) {
focusTarget = modal_wrapper.find('.modaal-video-wrap');
} else {
focusTarget = modal_wrapper.find('.modaal-focus');
}
// now set the focus
focusTarget.attr('tabindex', '0').focus();
// Run after_open
if (animation_type !== 'none') {
// CB: after_open
setTimeout(function() {
self.options.after_open.call(self, modal_wrapper)
}, self.options.after_callback_delay);
}
},
// Close Modal
// ----------------------------------------------------------------
modaal_close : function() {
var self = this;
var modal_wrapper = $( '#' + self.scope.id );
// CB: before_close
self.options.before_close.call(self, modal_wrapper);
if (self.xhr !== null){
self.xhr.abort();
self.xhr = null;
}
// Now we close the modal
if (self.options.animation === 'none' ){
modal_wrapper.addClass('modaal-start_none');
}
// Close with fade
if (self.options.animation === 'fade') {
modal_wrapper.addClass('modaal-start_fade');
}
// Close with slide up (using initial slide down)
if (self.options.animation === 'slide-down') {
modal_wrapper.addClass('modaal-start_slide_down');
}
// CB: after_close and remove
setTimeout(function() {
// clone inline content back to origin place
if (self.options.type == 'inline') {
$('#' + self.scope.id + ' .modaal-content-container').contents().detach().appendTo( self.scope.source )
}
// remove markup from dom
modal_wrapper.remove();
// CB: after_close
self.options.after_close.call(self);
// scope is now closed
self.scope.is_open = false;
}, self.options.after_callback_delay);
// Call overlay hide
self.modaal_overlay('hide');
// Roll back to last focus state before modal open. If was closed programmatically, this might not be set
if (self.lastFocus != null) {
self.lastFocus.focus();
}
},
// Overlay control (accepts action for show or hide)
// ----------------------------------------------------------------
modaal_overlay : function(action) {
var self = this;
if (action == 'show') {
// Modal is open so update scope
self.scope.is_open = true;
// set body to overflow hidden if background_scroll is false
if (! self.options.background_scroll) {
self.dom.addClass('modaal-noscroll');
}
// append modaal overlay
if ($('#' + self.scope.id + '_overlay').length < 1) {
self.dom.append('<div class="modaal-overlay" id="' + self.scope.id + '_overlay"></div>');
}
// now show
$('#' + self.scope.id + '_overlay').css('background', self.options.background).stop().animate({
opacity: self.options.overlay_opacity
}, self.options.animation_speed, function(){
// now open the modal
self.modaal_open();
});
} else if (action == 'hide') {
// now hide the overlay
$('#' + self.scope.id + '_overlay').stop().animate({
opacity: 0
}, self.options.animation_speed, function(){
// remove overlay from dom
$(this).remove();
// remove body overflow lock
self.dom.removeClass('modaal-noscroll');
});
}
},
// Check if is touch
// ----------------------------------------------------------------
is_touch : function() {
return 'ontouchstart' in window || navigator.maxTouchPoints;
}
};
// Define default object to store
var modaal_existing_selectors = [];
// Declare the modaal jQuery method
// ------------------------------------------------------------
$.fn.modaal = function(options) {
return this.each(function (i) {
var existing_modaal = $(this).data('modaal');
if ( existing_modaal ){
// Checking for string value, used for methods
if (typeof(options) == 'string'){
switch (options) {
case 'open':
// create the modal
existing_modaal.create_modaal(existing_modaal);
break;
case 'close':
existing_modaal.modaal_close();
break;
}
}
} else {
// Not a string, so let's setup the modal ready to use
var modaal = Object.create(Modaal);
modaal.init(options, this);
$.data(this, "modaal", modaal);
// push this select into existing selectors array which is referenced during modaal_dom_observer
modaal_existing_selectors.push({
'element': $(this).attr('class'),
'options': options
});
}
});
};
// Default options
// ------------------------------------------------------------
$.fn.modaal.options = {
//General
type: 'inline',
content_source: null,
animation: 'fade',
animation_speed: 300,
after_callback_delay: 350,
is_locked: false,
hide_close: false,
background: '#000',
overlay_opacity: '0.8',
overlay_close: true,
accessible_title: 'Dialog Window',
start_open: false,
fullscreen: false,
custom_class: '',
background_scroll: false,
should_open: true,
close_text: 'Close',
close_aria_label: 'Close (Press escape to close)',
width: null,
height: null,
//Events
before_open: function(){},
after_open: function(){},
before_close: function(){},
after_close: function(){},
source: function( element, src ){
return src;
},
//Confirm Modal
confirm_button_text: 'Confirm', // text on confirm button
confirm_cancel_button_text: 'Cancel',
confirm_title: 'Confirm Title', // title for confirm modal
confirm_content: '<p>This is the default confirm dialog content. Replace me through the options</p>', // html for confirm message
confirm_callback: function() {},
confirm_cancel_callback: function() {},
//Gallery Modal
gallery_active_class: 'gallery_active_item',
outer_controls: false,
before_image_change: function( current_item, incoming_item ) {},
after_image_change: function( current_item ) {},
//Ajax Modal
loading_content: modaal_loading_spinner,
loading_class: 'is_loading',
ajax_error_class: 'modaal-error',
ajax_success: function(){},
//Instagram
instagram_id: null
};
// Check and Set Inline Options
// ------------------------------------------------------------
function modaal_inline_options(self) {
// new empty options
var options = {};
var inline_options = false;
// option: type
if ( self.attr('data-modaal-type') ) {
inline_options = true;
options.type = self.attr('data-modaal-type');
}
// option: type
if ( self.attr('data-modaal-content-source') ) {
inline_options = true;
options.content_source = self.attr('data-modaal-content-source');
}
// option: animation
if ( self.attr('data-modaal-animation') ) {
inline_options = true;
options.animation = self.attr('data-modaal-animation');
}
// option: animation_speed
if ( self.attr('data-modaal-animation-speed') ) {
inline_options = true;
options.animation_speed = self.attr('data-modaal-animation-speed');
}
// option: after_callback_delay
if ( self.attr('data-modaal-after-callback-delay') ) {
inline_options = true;
options.after_callback_delay = self.attr('data-modaal-after-callback-delay');
}
// option: is_locked
if ( self.attr('data-modaal-is-locked') ) {
inline_options = true;
options.is_locked = (self.attr('data-modaal-is-locked') === 'true' ? true : false);
}
// option: hide_close
if ( self.attr('data-modaal-hide-close') ) {
inline_options = true;
options.hide_close = (self.attr('data-modaal-hide-close') === 'true' ? true : false);
}
// option: background
if ( self.attr('data-modaal-background') ) {
inline_options = true;
options.background = self.attr('data-modaal-background');
}
// option: overlay_opacity
if ( self.attr('data-modaal-overlay-opacity') ) {
inline_options = true;
options.overlay_opacity = self.attr('data-modaal-overlay-opacity');
}
// option: overlay_close
if ( self.attr('data-modaal-overlay-close') ) {
inline_options = true;
options.overlay_close = (self.attr('data-modaal-overlay-close') === 'false' ? false : true);
}
// option: accessible_title
if ( self.attr('data-modaal-accessible-title') ) {
inline_options = true;
options.accessible_title = self.attr('data-modaal-accessible-title');
}
// option: start_open
if ( self.attr('data-modaal-start-open') ) {
inline_options = true;
options.start_open = (self.attr('data-modaal-start-open') === 'true' ? true : false);
}
// option: fullscreen
if ( self.attr('data-modaal-fullscreen') ) {
inline_options = true;
options.fullscreen = (self.attr('data-modaal-fullscreen') === 'true' ? true : false);
}
// option: custom_class
if ( self.attr('data-modaal-custom-class') ) {
inline_options = true;
options.custom_class = self.attr('data-modaal-custom-class');
}
// option: close_text
if ( self.attr('data-modaal-close-text') ) {
inline_options = true;
options.close_text = self.attr('data-modaal-close-text');
}
// option: close_aria_label
if ( self.attr('data-modaal-close-aria-label') ) {
inline_options = true;
options.close_aria_label = self.attr('data-modaal-close-aria-label');
}
// option: background_scroll
if ( self.attr('data-modaal-background-scroll') ) {
inline_options = true;
options.background_scroll = (self.attr('data-modaal-background-scroll') === 'true' ? true : false);
}
// option: width
if ( self.attr('data-modaal-width') ) {
inline_options = true;
options.width = parseInt( self.attr('data-modaal-width') );
}
// option: height
if ( self.attr('data-modaal-height') ) {
inline_options = true;
options.height = parseInt( self.attr('data-modaal-height') );
}
// option: confirm_button_text
if ( self.attr('data-modaal-confirm-button-text') ) {
inline_options = true;
options.confirm_button_text = self.attr('data-modaal-confirm-button-text');
}
// option: confirm_cancel_button_text
if ( self.attr('data-modaal-confirm-cancel-button-text') ) {
inline_options = true;
options.confirm_cancel_button_text = self.attr('data-modaal-confirm-cancel-button-text');
}
// option: confirm_title
if ( self.attr('data-modaal-confirm-title') ) {
inline_options = true;
options.confirm_title = self.attr('data-modaal-confirm-title');
}
// option: confirm_content
if ( self.attr('data-modaal-confirm-content') ) {
inline_options = true;
options.confirm_content = self.attr('data-modaal-confirm-content');
}
// option: gallery_active_class
if ( self.attr('data-modaal-gallery-active-class') ) {
inline_options = true;
options.gallery_active_class = self.attr('data-modaal-gallery-active-class');
}
// option: loading_content
if ( self.attr('data-modaal-loading-content') ) {
inline_options = true;
options.loading_content = self.attr('data-modaal-loading-content');
}
// option: loading_class
if ( self.attr('data-modaal-loading-class') ) {
inline_options = true;
options.loading_class = self.attr('data-modaal-loading-class');
}
// option: ajax_error_class
if ( self.attr('data-modaal-ajax-error-class') ) {
inline_options = true;
options.ajax_error_class = self.attr('data-modaal-ajax-error-class');
}
// option: start_open
if ( self.attr('data-modaal-instagram-id') ) {
inline_options = true;
options.instagram_id = self.attr('data-modaal-instagram-id');
}
// now set it up for the trigger, but only if inline_options is true
if ( inline_options ) {
self.modaal(options);
}
};
// On body load (or now, if already loaded), init any modaals defined inline
// Ensure this is done after $.fn.modaal and default options are declared
// ----------------------------------------------------------------
$(function(){
var single_modaal = $('.modaal');
// Check for existing modaal elements
if ( single_modaal.length ) {
single_modaal.each(function() {
var self = $(this);
modaal_inline_options(self);
});
}
// Obvserve DOM mutations for newly added triggers
var modaal_dom_observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
// element added to DOM
var findElement = [].some.call(mutation.addedNodes, function(el) {
var elm = $(el);
if ( elm.is('a') || elm.is('button') ) {
if ( elm.hasClass('modaal') ) {
// is inline Modaal, initialise options
modaal_inline_options(elm);
} else {
// is not inline modaal. Check for existing selector
modaal_existing_selectors.forEach(function(modaalSelector) {
if ( modaalSelector.element == elm.attr('class') ) {
$(elm).modaal( modaalSelector.options );
return false;
}
});
}
}
});
}
});
});
var observer_config = {
subtree: true,
attributes: true,
childList: true,
characterData: true
};
// pass in the target node, as well as the observer options
setTimeout(function() {
modaal_dom_observer.observe(document.body, observer_config);
}, 500);
});
} ( jQuery, window, document ) );
\ No newline at end of file
/*!
Modaal - accessible modals - v0.4.4
by Humaan, for all humans.
http://humaan.com
*/
!function(a){function t(a){var t={},o=!1;a.attr("data-modaal-type")&&(o=!0,t.type=a.attr("data-modaal-type")),a.attr("data-modaal-content-source")&&(o=!0,t.content_source=a.attr("data-modaal-content-source")),a.attr("data-modaal-animation")&&(o=!0,t.animation=a.attr("data-modaal-animation")),a.attr("data-modaal-animation-speed")&&(o=!0,t.animation_speed=a.attr("data-modaal-animation-speed")),a.attr("data-modaal-after-callback-delay")&&(o=!0,t.after_callback_delay=a.attr("data-modaal-after-callback-delay")),a.attr("data-modaal-is-locked")&&(o=!0,t.is_locked="true"===a.attr("data-modaal-is-locked")),a.attr("data-modaal-hide-close")&&(o=!0,t.hide_close="true"===a.attr("data-modaal-hide-close")),a.attr("data-modaal-background")&&(o=!0,t.background=a.attr("data-modaal-background")),a.attr("data-modaal-overlay-opacity")&&(o=!0,t.overlay_opacity=a.attr("data-modaal-overlay-opacity")),a.attr("data-modaal-overlay-close")&&(o=!0,t.overlay_close="false"!==a.attr("data-modaal-overlay-close")),a.attr("data-modaal-accessible-title")&&(o=!0,t.accessible_title=a.attr("data-modaal-accessible-title")),a.attr("data-modaal-start-open")&&(o=!0,t.start_open="true"===a.attr("data-modaal-start-open")),a.attr("data-modaal-fullscreen")&&(o=!0,t.fullscreen="true"===a.attr("data-modaal-fullscreen")),a.attr("data-modaal-custom-class")&&(o=!0,t.custom_class=a.attr("data-modaal-custom-class")),a.attr("data-modaal-close-text")&&(o=!0,t.close_text=a.attr("data-modaal-close-text")),a.attr("data-modaal-close-aria-label")&&(o=!0,t.close_aria_label=a.attr("data-modaal-close-aria-label")),a.attr("data-modaal-background-scroll")&&(o=!0,t.background_scroll="true"===a.attr("data-modaal-background-scroll")),a.attr("data-modaal-width")&&(o=!0,t.width=parseInt(a.attr("data-modaal-width"))),a.attr("data-modaal-height")&&(o=!0,t.height=parseInt(a.attr("data-modaal-height"))),a.attr("data-modaal-confirm-button-text")&&(o=!0,t.confirm_button_text=a.attr("data-modaal-confirm-button-text")),a.attr("data-modaal-confirm-cancel-button-text")&&(o=!0,t.confirm_cancel_button_text=a.attr("data-modaal-confirm-cancel-button-text")),a.attr("data-modaal-confirm-title")&&(o=!0,t.confirm_title=a.attr("data-modaal-confirm-title")),a.attr("data-modaal-confirm-content")&&(o=!0,t.confirm_content=a.attr("data-modaal-confirm-content")),a.attr("data-modaal-gallery-active-class")&&(o=!0,t.gallery_active_class=a.attr("data-modaal-gallery-active-class")),a.attr("data-modaal-loading-content")&&(o=!0,t.loading_content=a.attr("data-modaal-loading-content")),a.attr("data-modaal-loading-class")&&(o=!0,t.loading_class=a.attr("data-modaal-loading-class")),a.attr("data-modaal-ajax-error-class")&&(o=!0,t.ajax_error_class=a.attr("data-modaal-ajax-error-class")),a.attr("data-modaal-instagram-id")&&(o=!0,t.instagram_id=a.attr("data-modaal-instagram-id")),o&&a.modaal(t)}var o={init:function(t,o){var e=this;if(e.dom=a("body"),e.$elem=a(o),e.options=a.extend({},a.fn.modaal.options,e.$elem.data(),t),e.xhr=null,e.scope={is_open:!1,id:"modaal_"+(new Date).getTime()+Math.random().toString(16).substring(2),source:e.options.content_source?e.options.content_source:e.$elem.attr("href")},e.$elem.attr("data-modaal-scope",e.scope.id),e.private_options={active_class:"is_active"},e.lastFocus=null,e.options.is_locked||"confirm"==e.options.type||e.options.hide_close?e.scope.close_btn="":e.scope.close_btn='<button type="button" class="modaal-close" id="modaal-close" aria-label="'+e.options.close_aria_label+'"><span>'+e.options.close_text+"</span></button>","none"===e.options.animation&&(e.options.animation_speed=0,e.options.after_callback_delay=0),a(o).on("click.Modaal",function(a){a.preventDefault(),e.create_modaal(e,a)}),!0===e.options.outer_controls)var i="outer";else var i="inner";e.scope.prev_btn='<button type="button" class="modaal-gallery-control modaal-gallery-prev modaal-gallery-prev-'+i+'" id="modaal-gallery-prev" aria-label="Previous image (use left arrow to change)"><span>Previous Image</span></button>',e.scope.next_btn='<button type="button" class="modaal-gallery-control modaal-gallery-next modaal-gallery-next-'+i+'" id="modaal-gallery-next" aria-label="Next image (use right arrow to change)"><span>Next Image</span></button>',!0===e.options.start_open&&e.create_modaal(e)},create_modaal:function(a,t){var o,a=this;if(a.lastFocus=a.$elem,!1!==a.options.should_open&&("function"!=typeof a.options.should_open||!1!==a.options.should_open())){switch(a.options.before_open.call(a,t),a.options.type){case"inline":a.create_basic();break;case"ajax":o=a.options.source(a.$elem,a.scope.source),a.fetch_ajax(o);break;case"confirm":a.options.is_locked=!0,a.create_confirm();break;case"image":a.create_image();break;case"iframe":o=a.options.source(a.$elem,a.scope.source),a.create_iframe(o);break;case"video":a.create_video(a.scope.source);break;case"instagram":a.create_instagram()}a.watch_events()}},watch_events:function(){var t=this;t.dom.off("click.Modaal keyup.Modaal keydown.Modaal"),t.dom.on("keydown.Modaal",function(o){var e=o.keyCode,i=o.target;9==e&&t.scope.is_open&&(a.contains(document.getElementById(t.scope.id),i)||a("#"+t.scope.id).find('*[tabindex="0"]').focus())}),t.dom.on("keyup.Modaal",function(o){var e=o.keyCode,i=o.target;return o.shiftKey&&9==o.keyCode&&t.scope.is_open&&(a.contains(document.getElementById(t.scope.id),i)||a("#"+t.scope.id).find(".modaal-close").focus()),!t.options.is_locked&&27==e&&t.scope.is_open?!a(document.activeElement).is("input:not(:checkbox):not(:radio)")&&void t.modaal_close():"image"==t.options.type?(37==e&&t.scope.is_open&&!a("#"+t.scope.id+" .modaal-gallery-prev").hasClass("is_hidden")&&t.gallery_update("prev"),void(39==e&&t.scope.is_open&&!a("#"+t.scope.id+" .modaal-gallery-next").hasClass("is_hidden")&&t.gallery_update("next"))):void 0}),t.dom.on("click.Modaal",function(o){var e=a(o.target);if(!t.options.is_locked&&(t.options.overlay_close&&e.is(".modaal-inner-wrapper")||e.is(".modaal-close")||e.closest(".modaal-close").length))return void t.modaal_close();if(e.is(".modaal-confirm-btn"))return e.is(".modaal-ok")&&t.options.confirm_callback.call(t,t.lastFocus),e.is(".modaal-cancel")&&t.options.confirm_cancel_callback.call(t,t.lastFocus),void t.modaal_close();if(e.is(".modaal-gallery-control")){if(e.hasClass("is_hidden"))return;return e.is(".modaal-gallery-prev")&&t.gallery_update("prev"),void(e.is(".modaal-gallery-next")&&t.gallery_update("next"))}})},build_modal:function(t){var o=this,e="";"instagram"==o.options.type&&(e=" modaal-instagram");var i,l="video"==o.options.type?"modaal-video-wrap":"modaal-content";switch(o.options.animation){case"fade":i=" modaal-start_fade";break;case"slide-down":i=" modaal-start_slidedown";break;default:i=" modaal-start_none"}var n="";o.options.fullscreen&&(n=" modaal-fullscreen"),""===o.options.custom_class&&void 0===o.options.custom_class||(o.options.custom_class=" "+o.options.custom_class);var s="";o.options.width&&o.options.height&&"number"==typeof o.options.width&&"number"==typeof o.options.height?s=' style="max-width:'+o.options.width+"px;height:"+o.options.height+'px;overflow:auto;"':o.options.width&&"number"==typeof o.options.width?s=' style="max-width:'+o.options.width+'px;"':o.options.height&&"number"==typeof o.options.height&&(s=' style="height:'+o.options.height+'px;overflow:auto;"'),("image"==o.options.type||"video"==o.options.type||"instagram"==o.options.type||o.options.fullscreen)&&(s="");var d="";o.is_touch()&&(d=' style="cursor:pointer;"');var r='<div class="modaal-wrapper modaal-'+o.options.type+i+e+n+o.options.custom_class+'" id="'+o.scope.id+'"><div class="modaal-outer-wrapper"><div class="modaal-inner-wrapper"'+d+">";"video"!=o.options.type&&(r+='<div class="modaal-container"'+s+">"),r+='<div class="'+l+' modaal-focus" aria-hidden="false" aria-label="'+o.options.accessible_title+" - "+o.options.close_aria_label+'" role="dialog">',"inline"==o.options.type?r+='<div class="modaal-content-container" role="document"></div>':r+=t,r+="</div>"+o.scope.close_btn,"video"!=o.options.type&&(r+="</div>"),r+="</div>","image"==o.options.type&&!0===o.options.outer_controls&&(r+=o.scope.prev_btn+o.scope.next_btn),r+="</div></div>",a("#"+o.scope.id+"_overlay").length<1&&o.dom.append(r),"inline"==o.options.type&&t.appendTo("#"+o.scope.id+" .modaal-content-container"),o.modaal_overlay("show")},create_basic:function(){var t=this,o=a(t.scope.source),e="";o.length?(e=o.contents().detach(),o.empty()):e="Content could not be loaded. Please check the source and try again.",t.build_modal(e)},create_instagram:function(){var t=this,o=t.options.instagram_id,e="",i="Instagram photo couldn't be loaded, please check the embed code and try again.";if(t.build_modal('<div class="modaal-content-container'+(""!=t.options.loading_class?" "+t.options.loading_class:"")+'">'+t.options.loading_content+"</div>"),""!=o&&null!==o&&void 0!==o){var l="https://api.instagram.com/oembed?url=http://instagr.am/p/"+o+"/";a.ajax({url:l,dataType:"jsonp",cache:!1,success:function(o){t.dom.append('<div id="temp-ig" style="width:0;height:0;overflow:hidden;">'+o.html+"</div>"),t.dom.attr("data-igloaded")?window.instgrm.Embeds.process():t.dom.attr("data-igloaded","true");var e="#"+t.scope.id+" .modaal-content-container";a(e).length>0&&setTimeout(function(){a("#temp-ig").contents().clone().appendTo(e),a("#temp-ig").remove()},1e3)},error:function(){e=i;var o=a("#"+t.scope.id+" .modaal-content-container");o.length>0&&(o.removeClass(t.options.loading_class).addClass(t.options.ajax_error_class),o.html(e))}})}else e=i;return!1},fetch_ajax:function(t){var o=this;null==o.options.accessible_title&&(o.options.accessible_title="Dialog Window"),null!==o.xhr&&(o.xhr.abort(),o.xhr=null),o.build_modal('<div class="modaal-content-container'+(""!=o.options.loading_class?" "+o.options.loading_class:"")+'">'+o.options.loading_content+"</div>"),o.xhr=a.ajax(t,{success:function(t){var e=a("#"+o.scope.id).find(".modaal-content-container");e.length>0&&(e.removeClass(o.options.loading_class),e.html(t),o.options.ajax_success.call(o,e))},error:function(t){if("abort"!=t.statusText){var e=a("#"+o.scope.id+" .modaal-content-container");e.length>0&&(e.removeClass(o.options.loading_class).addClass(o.options.ajax_error_class),e.html("Content could not be loaded. Please check the source and try again."))}}})},create_confirm:function(){var a,t=this;a='<div class="modaal-content-container"><h1 id="modaal-title">'+t.options.confirm_title+'</h1><div class="modaal-confirm-content">'+t.options.confirm_content+'</div><div class="modaal-confirm-wrap"><button type="button" class="modaal-confirm-btn modaal-ok" aria-label="Confirm">'+t.options.confirm_button_text+'</button><button type="button" class="modaal-confirm-btn modaal-cancel" aria-label="Cancel">'+t.options.confirm_cancel_button_text+"</button></div></div></div>",t.build_modal(a)},create_image:function(){var t,o,e=this,i="";if(e.$elem.is("[data-group]")||e.$elem.is("[rel]")){var l=e.$elem.is("[data-group]"),n=l?e.$elem.attr("data-group"):e.$elem.attr("rel"),s=a(l?'[data-group="'+n+'"]':'[rel="'+n+'"]');s.removeAttr("data-gallery-active","is_active"),e.$elem.attr("data-gallery-active","is_active"),o=s.length-1;var d=[];i='<div class="modaal-gallery-item-wrap">',s.each(function(t,o){var e="",i="",l="",n=!1,s=!1,r=o.getAttribute("data-modaal-desc"),c=o.getAttribute("data-gallery-active");a(o).attr("data-modaal-content-source")?e=a(o).attr("data-modaal-content-source"):a(o).attr("href")?e=a(o).attr("href"):a(o).attr("src")?e=a(o).attr("src"):(e="trigger requires href or data-modaal-content-source attribute",s=!0),""!=r&&null!==r&&void 0!==r?(i=r,l='<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image '+(t+1)+" - </span>"+r.replace(/</g,"&lt;").replace(/>/g,"&gt;")+"</div>"):l='<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image '+(t+1)+"</span></div>",c&&(n=!0);var m={url:e,alt:i,rawdesc:r,desc:l,active:n,src_error:s};d.push(m)});for(var r=0;r<d.length;r++){var c="",m=d[r].rawdesc?"Image: "+d[r].rawdesc:"Image "+r+" no description";d[r].active&&(c=" "+e.private_options.active_class);var p=d[r].src_error?d[r].url:'<img src="'+d[r].url+'" alt=" " style="width:100%">';i+='<div class="modaal-gallery-item gallery-item-'+r+c+'" aria-label="'+m+'">'+p+d[r].desc+"</div>"}i+="</div>",1!=e.options.outer_controls&&(i+=e.scope.prev_btn+e.scope.next_btn)}else{var u,_=!1;e.$elem.attr("data-modaal-content-source")?u=e.$elem.attr("data-modaal-content-source"):e.$elem.attr("href")?u=e.$elem.attr("href"):e.$elem.attr("src")?u=e.$elem.attr("src"):(u="trigger requires href or data-modaal-content-source attribute",_=!0);var v="",f="",m="";e.$elem.attr("data-modaal-desc")?(m=e.$elem.attr("data-modaal-desc"),v=e.$elem.attr("data-modaal-desc"),f='<div class="modaal-gallery-label"><span class="modaal-accessible-hide">Image - </span>'+v.replace(/</g,"&lt;").replace(/>/g,"&gt;")+"</div>"):m="Image with no description";var p=_?u:'<img src="'+u+'" alt=" " style="width:100%">';i='<div class="modaal-gallery-item is_active" aria-label="'+m+'">'+p+f+"</div>"}t=i,e.build_modal(t),a(".modaal-gallery-item.is_active").is(".gallery-item-0")&&a(".modaal-gallery-prev").hide(),a(".modaal-gallery-item.is_active").is(".gallery-item-"+o)&&a(".modaal-gallery-next").hide()},gallery_update:function(t){var o=this,e=a("#"+o.scope.id),i=e.find(".modaal-gallery-item"),l=i.length-1;if(0==l)return!1;var n=e.find(".modaal-gallery-prev"),s=e.find(".modaal-gallery-next"),d=0,r=0,c=e.find(".modaal-gallery-item."+o.private_options.active_class),m="next"==t?c.next(".modaal-gallery-item"):c.prev(".modaal-gallery-item");return o.options.before_image_change.call(o,c,m),("prev"!=t||!e.find(".gallery-item-0").hasClass("is_active"))&&(("next"!=t||!e.find(".gallery-item-"+l).hasClass("is_active"))&&void c.stop().animate({opacity:0},250,function(){m.addClass("is_next").css({position:"absolute",display:"block",opacity:0});var t=a(document).width(),i=t>1140?280:50;d=e.find(".modaal-gallery-item.is_next").width(),r=e.find(".modaal-gallery-item.is_next").height();var p=e.find(".modaal-gallery-item.is_next img").prop("naturalWidth"),u=e.find(".modaal-gallery-item.is_next img").prop("naturalHeight");p>t-i?(d=t-i,e.find(".modaal-gallery-item.is_next").css({width:d}),e.find(".modaal-gallery-item.is_next img").css({width:d}),r=e.find(".modaal-gallery-item.is_next").find("img").height()):(d=p,r=u),e.find(".modaal-gallery-item-wrap").stop().animate({width:d,height:r},250,function(){c.removeClass(o.private_options.active_class+" "+o.options.gallery_active_class).removeAttr("style"),c.find("img").removeAttr("style"),m.addClass(o.private_options.active_class+" "+o.options.gallery_active_class).removeClass("is_next").css("position",""),m.stop().animate({opacity:1},250,function(){a(this).removeAttr("style").css({width:"100%"}),a(this).find("img").css("width","100%"),e.find(".modaal-gallery-item-wrap").removeAttr("style"),o.options.after_image_change.call(o,m)}),e.find(".modaal-gallery-item").removeAttr("tabindex"),e.find(".modaal-gallery-item."+o.private_options.active_class).attr("tabindex","0").focus(),e.find(".modaal-gallery-item."+o.private_options.active_class).is(".gallery-item-0")?n.stop().animate({opacity:0},150,function(){a(this).hide()}):n.stop().css({display:"block",opacity:n.css("opacity")}).animate({opacity:1},150),e.find(".modaal-gallery-item."+o.private_options.active_class).is(".gallery-item-"+l)?s.stop().animate({opacity:0},150,function(){a(this).hide()}):s.stop().css({display:"block",opacity:n.css("opacity")}).animate({opacity:1},150)})}))},create_video:function(a){var t,o=this;t='<iframe src="'+a+'" class="modaal-video-frame" frameborder="0" allowfullscreen></iframe>',o.build_modal('<div class="modaal-video-container">'+t+"</div>")},create_iframe:function(a){var t,o=this;t=null!==o.options.width||void 0!==o.options.width||null!==o.options.height||void 0!==o.options.height?'<iframe src="'+a+'" class="modaal-iframe-elem" frameborder="0" allowfullscreen></iframe>':'<div class="modaal-content-container">Please specify a width and height for your iframe</div>',o.build_modal(t)},modaal_open:function(){var t=this,o=a("#"+t.scope.id),e=t.options.animation;"none"===e&&(o.removeClass("modaal-start_none"),t.options.after_open.call(t,o)),"fade"===e&&o.removeClass("modaal-start_fade"),"slide-down"===e&&o.removeClass("modaal-start_slide_down");var i=o;a(".modaal-wrapper *[tabindex=0]").removeAttr("tabindex"),i="image"==t.options.type?a("#"+t.scope.id).find(".modaal-gallery-item."+t.private_options.active_class):o.find(".modaal-iframe-elem").length?o.find(".modaal-iframe-elem"):o.find(".modaal-video-wrap").length?o.find(".modaal-video-wrap"):o.find(".modaal-focus"),i.attr("tabindex","0").focus(),"none"!==e&&setTimeout(function(){t.options.after_open.call(t,o)},t.options.after_callback_delay)},modaal_close:function(){var t=this,o=a("#"+t.scope.id);t.options.before_close.call(t,o),null!==t.xhr&&(t.xhr.abort(),t.xhr=null),"none"===t.options.animation&&o.addClass("modaal-start_none"),"fade"===t.options.animation&&o.addClass("modaal-start_fade"),"slide-down"===t.options.animation&&o.addClass("modaal-start_slide_down"),setTimeout(function(){"inline"==t.options.type&&a("#"+t.scope.id+" .modaal-content-container").contents().detach().appendTo(t.scope.source),o.remove(),t.options.after_close.call(t),t.scope.is_open=!1},t.options.after_callback_delay),t.modaal_overlay("hide"),null!=t.lastFocus&&t.lastFocus.focus()},modaal_overlay:function(t){var o=this;"show"==t?(o.scope.is_open=!0,o.options.background_scroll||o.dom.addClass("modaal-noscroll"),a("#"+o.scope.id+"_overlay").length<1&&o.dom.append('<div class="modaal-overlay" id="'+o.scope.id+'_overlay"></div>'),a("#"+o.scope.id+"_overlay").css("background",o.options.background).stop().animate({opacity:o.options.overlay_opacity},o.options.animation_speed,function(){o.modaal_open()})):"hide"==t&&a("#"+o.scope.id+"_overlay").stop().animate({opacity:0},o.options.animation_speed,function(){a(this).remove(),o.dom.removeClass("modaal-noscroll")})},is_touch:function(){return"ontouchstart"in window||navigator.maxTouchPoints}},e=[];a.fn.modaal=function(t){return this.each(function(i){var l=a(this).data("modaal");if(l){if("string"==typeof t)switch(t){case"open":l.create_modaal(l);break;case"close":l.modaal_close()}}else{var n=Object.create(o);n.init(t,this),a.data(this,"modaal",n),e.push({element:a(this).attr("class"),options:t})}})},a.fn.modaal.options={type:"inline",content_source:null,animation:"fade",animation_speed:300,after_callback_delay:350,is_locked:!1,hide_close:!1,background:"#000",overlay_opacity:"0.8",overlay_close:!0,accessible_title:"Dialog Window",start_open:!1,fullscreen:!1,custom_class:"",background_scroll:!1,should_open:!0,close_text:"Close",close_aria_label:"Close (Press escape to close)",width:null,height:null,before_open:function(){},after_open:function(){},before_close:function(){},after_close:function(){},source:function(a,t){return t},confirm_button_text:"Confirm",confirm_cancel_button_text:"Cancel",confirm_title:"Confirm Title",confirm_content:"<p>This is the default confirm dialog content. Replace me through the options</p>",confirm_callback:function(){},confirm_cancel_callback:function(){},gallery_active_class:"gallery_active_item",outer_controls:!1,before_image_change:function(a,t){},after_image_change:function(a){},loading_content:'<div class="modaal-loading-spinner"><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div><div><div></div></div></div>',loading_class:"is_loading",ajax_error_class:"modaal-error",ajax_success:function(){},instagram_id:null},a(function(){var o=a(".modaal");o.length&&o.each(function(){t(a(this))});var i=new MutationObserver(function(o){o.forEach(function(o){if(o.addedNodes&&o.addedNodes.length>0){[].some.call(o.addedNodes,function(o){var i=a(o);(i.is("a")||i.is("button"))&&(i.hasClass("modaal")?t(i):e.forEach(function(t){if(t.element==i.attr("class"))return a(i).modaal(t.options),!1}))})}})}),l={subtree:!0,attributes:!0,childList:!0,characterData:!0};setTimeout(function(){i.observe(document.body,l)},500)})}(jQuery,window,document);
\ No newline at end of file
.sp-container{position:absolute;top:0;left:0;display:inline-block;z-index:9999994;overflow:hidden}.sp-original-input-container{position:relative;display:inline-flex}.sp-original-input-container input{margin:0!important}.sp-original-input-container .sp-add-on{width:40px;border-top-right-radius:0!important;border-bottom-right-radius:0!important}input.spectrum.with-add-on{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.sp-original-input-container .sp-add-on .sp-colorize{height:100%;width:100%;border-radius:inherit}.sp-colorize-container{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.sp-container.sp-flat{position:relative}.sp-container,.sp-container *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.sp-top{position:relative;width:100%;display:inline-block}.sp-top-inner{position:absolute;top:0;left:0;bottom:0;right:0}.sp-color{position:absolute;top:0;left:0;bottom:0;right:20px!important}.sp-hue{position:absolute;top:0;right:0;bottom:0;width:12px;height:100%;left:initial!important}.sp-clear-enabled .sp-hue{top:15%;height:85%}.sp-fill{padding-top:80%}.sp-sat,.sp-val{position:absolute;top:0;left:0;right:0;bottom:0}.sp-alpha-enabled .sp-top{margin-bottom:28px!important}.sp-alpha-enabled .sp-alpha{display:block}.sp-alpha-handle{position:absolute;top:-3px;cursor:pointer;height:16px;border-radius:50%;width:16px;margin-right:5px;left:-2px;right:0;background:#f9f9f9;box-shadow:0 0 2px 0 #3a3a3a}.sp-alpha{display:none;position:absolute;bottom:-18px;right:0;left:0;height:10px}.sp-alpha-inner{border-radius:4px}.sp-clear{display:none}.sp-clear.sp-clear-display{background-position:center}.sp-clear-enabled .sp-clear{display:block;position:absolute;top:3px;right:0;bottom:0;cursor:pointer;left:initial;height:12px;width:12px}.sp-alpha,.sp-alpha-handle,.sp-clear,.sp-container,.sp-container button,.sp-container.sp-dragging .sp-input,.sp-dragger,.sp-preview,.sp-replacer,.sp-slider{-webkit-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}.sp-container.sp-input-disabled .sp-input-container{display:none}.sp-container.sp-buttons-disabled .sp-button-container{display:none}.sp-container.sp-palette-buttons-disabled .sp-palette-button-container{display:none}.sp-palette-only .sp-picker-container{display:none}.sp-palette-disabled .sp-palette-container{display:none}.sp-initial-disabled .sp-initial{display:none}.sp-sat{background-image:-webkit-gradient(linear,0 0,100% 0,from(#fff),to(rgba(204,154,129,0)));background-image:-webkit-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-moz-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-o-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-ms-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:linear-gradient(to right,#fff,rgba(204,154,129,0))}.sp-val{border-radius:4px;background-image:-webkit-gradient(linear,0 100%,0 0,from(#000),to(rgba(204,154,129,0)));background-image:-webkit-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-moz-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-o-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-ms-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:linear-gradient(to top,#000,rgba(204,154,129,0))}.sp-hue{background:-moz-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-ms-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-o-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(.17,#ff0),color-stop(.33,#0f0),color-stop(.5,#0ff),color-stop(.67,#00f),color-stop(.83,#f0f),to(red));background:-webkit-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.sp-1{height:17%}.sp-2{height:16%}.sp-3{height:17%}.sp-4{height:17%}.sp-5{height:16%}.sp-6{height:17%}.sp-hidden{display:none!important}.sp-cf:after,.sp-cf:before{content:"";display:table}.sp-cf:after{clear:both}@media (max-device-width:480px){.sp-color{right:40%}.sp-hue{left:63%}.sp-fill{padding-top:60%}}.sp-dragger{border-radius:5px;height:10px;width:10px;border:1px solid #fff;cursor:pointer;position:absolute;top:0;left:0;margin-left:3px;margin-top:3px;box-shadow:0 0 2px 1px rgba(0,0,0,.2)}.sp-slider{position:absolute;top:0;cursor:pointer;height:16px;border-radius:50%;width:16px;left:-2px;background:#f9f9f9;box-shadow:0 0 2px 0 #3a3a3a;margin-top:8px}.sp-container{display:inline-flex;border-radius:0;background-color:#fff;padding:0;border-radius:4px;color:#000;box-shadow:0 0 0 1px rgba(99,114,130,.16),0 8px 16px rgba(27,39,51,.08)}.sp-clear,.sp-color,.sp-container,.sp-container button,.sp-container input,.sp-hue{font-size:12px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.sp-top{margin-bottom:10px}.sp-clear,.sp-color,.sp-hue,.sp-sat,.sp-val{border-radius:3px}.sp-input-container{margin-top:-5px}.sp-button-container.sp-cf,.sp-initial.sp-thumb.sp-cf,.sp-input-container.sp-cf{height:25px}.sp-picker-container .sp-cf{margin-bottom:10px}.sp-palette-row-initial>span:first-child{cursor:pointer}.sp-initial-disabled .sp-input-container{width:100%}.sp-input{padding:0 5px!important;margin:0;width:100%;box-shadow:none!important;height:100%!important;background:0 0;color:#3a3a3a;border-radius:2px!important;border:1px solid #e0e0e0!important;text-align:center;font-family:monospace;font-size:inherit!important}.sp-input:focus{border:1px solid orange}.sp-input.sp-validation-error{border:1px solid red;background:#fdd}.sp-palette-container,.sp-picker-container{position:relative;padding:10px}.sp-picker-container{width:200px;padding-bottom:0}.sp-palette-container{border-right:solid 1px #ccc}.sp-palette-only .sp-palette-container{border:0}.sp-palette .sp-thumb-el{display:block;position:relative;float:left;width:24px;height:15px;margin:3px;cursor:pointer;border:solid 2px transparent}.sp-palette .sp-thumb-el.sp-thumb-active,.sp-palette .sp-thumb-el:hover{border-color:orange}.sp-thumb-el{position:relative}.sp-initial{float:left}.sp-initial span{width:30px;height:25px;border:none;display:block;float:left;margin:0}.sp-initial .spe-thumb-el.sp-thumb-active{border-radius:0 5px 5px 0}.sp-initial .spe-thumb-el{border-radius:5px 0 0 5px}.sp-initial .sp-clear-display{background-position:center}.sp-button-container{float:right}.sp-palette-button-container{margin-top:10px}.sp-replacer{position:relative;overflow:hidden;cursor:pointer;display:inline-block;border-radius:3px;border:1px solid #aaa;color:#666;transition:border-color .3s;vertical-align:middle;width:3rem;height:1.5rem}.sp-replacer.sp-active,.sp-replacer:hover{border:1px solid #666;color:#000}.sp-replacer.sp-disabled{cursor:default;border-color:silver;color:silver}.sp-dd{position:absolute;font-size:10px;right:0;top:0;bottom:0;padding:0 2px;line-height:1.6rem;background-color:#fff}.sp-preview{position:relative;width:100%;height:100%;float:left;z-index:0}.sp-preview-inner{transition:background-color .2s}.sp-preview-inner.sp-clear-display{display:none}.sp-palette .sp-thumb-el{width:16px;height:16px;margin:3px;border:none;border-radius:3px}.sp-container button{border-radius:3px;border:none;background:0 0;line-height:1;padding:0 8px;height:25px;text-transform:capitalize;text-align:center;vertical-align:middle;cursor:pointer;color:#606c72;font-weight:700}.sp-container button.sp-choose{background-color:#3cab3b;color:#fff;margin-left:5px}.sp-container button:hover{opacity:.8}.sp-container button.sp-palette-toggle{width:100%;background-color:#f3f3f3;margin:0}.sp-palette span.sp-thumb-active,.sp-palette span:hover{border-color:#000}.sp-alpha,.sp-preview,.sp-thumb-el{position:relative;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.sp-alpha-inner,.sp-preview-inner,.sp-thumb-inner{display:block;position:absolute;top:0;left:0;bottom:0;right:0}.sp-palette .sp-thumb-inner{border-radius:3px;background-position:50% 50%;background-repeat:no-repeat}.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=)}.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=)}.sp-clear-display{background-repeat:no-repeat;background-position:center;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABe0lEQVQokYXSsUtcQRTF4d8Jj+VhHSxkEQuLsEUKK0nhTBFTmLSSUhBCMCAWsmgIwWrBLk0akfwLCaSQKBJmtrIIISwpRFKIhViETScphGMzysMtvOVwvpm5d0bGNCuGWAOPgYdl6S8wSDn9b+bUhDHEKWAdeAFMANg+l/TV9ofcz6cjMIbYBvaBMds7QCqZ58CmpBNgPuV0DvAAIMyFGugWtJr7eTv38xEwkPRPErY7QDeG2LqFkjrAgu0dSd/KDVqSNmxvAZ8lfbS9AHRuYemnLWkv5XRVBrQMbAI/gTXgEzAJtJuwBVS2L2OIle03QA/4Lmkl5XQBXEqqbFcAVYFDYChpFngiqWf7l6TXKaezMt2Zkhk24THwG+jZriX9AFZvUAyxLbRke2D75O5zPAO+ADXwEtizjaRHwDvbTyUtppwOmicCHAJvbXcl9YA1SQDjtseA97YPRz7ATcUQp2y/kjRdevsjaTfldNrMjcDGBjXA3T96L7yvrgFzP69+0Ao/HAAAAABJRU5ErkJggg==)}
\ No newline at end of file
!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports&&"object"==typeof module?module.exports=e(require("jquery")):e(jQuery)}(function(De,qe){"use strict";var e,Ie={beforeShow:a,move:a,change:a,show:a,hide:a,color:!1,flat:!1,type:"",showInput:!1,allowEmpty:!0,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!0,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:8,locale:"en",cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:"name",className:"",containerClassName:"",replacerClassName:"",showAlpha:!0,theme:"sp-light",palette:[["#000000","#444444","#5b5b5b","#999999","#bcbcbc","#eeeeee","#f3f6f4","#ffffff"],["#f44336","#744700","#ce7e00","#8fce00","#2986cc","#16537e","#6a329f","#c90076"],["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],["#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],["#990000","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],["#660000","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]],selectionPalette:[],disabled:!1,offset:null},Ve=[],We=!!/msie/i.exec(window.navigator.userAgent),Be=((e=document.createElement("div").style).cssText="background-color:rgba(0,0,0,.5)",t(e.backgroundColor,"rgba")||t(e.backgroundColor,"hsla")),Ke=["<div class='sp-replacer'>","<div class='sp-preview'><div class='sp-preview-inner'></div></div>","<div class='sp-dd'>&#9660;</div>","</div>"].join(""),$e=function(){var e="";if(We)for(var t=1;t<=6;t++)e+="<div class='sp-"+t+"'></div>";return["<div class='sp-container sp-hidden'>","<div class='sp-palette-container'>","<div class='sp-palette sp-thumb sp-cf'></div>","<div class='sp-palette-button-container sp-cf'>","<button type='button' class='sp-palette-toggle'></button>","</div>","</div>","<div class='sp-picker-container'>","<div class='sp-top sp-cf'>","<div class='sp-fill'></div>","<div class='sp-top-inner'>","<div class='sp-color'>","<div class='sp-sat'>","<div class='sp-val'>","<div class='sp-dragger'></div>","</div>","</div>","</div>","<div class='sp-clear sp-clear-display'>","</div>","<div class='sp-hue'>","<div class='sp-slider'></div>",e,"</div>","</div>","<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>","</div>","<div class='sp-input-container sp-cf'>","<input class='sp-input' type='text' spellcheck='false' />","</div>","<div class='sp-initial sp-thumb sp-cf'></div>","<div class='sp-button-container sp-cf'>","<button class='sp-cancel' href='#'></button>","<button type='button' class='sp-choose'></button>","</div>","</div>","</div>"].join("")}();function t(e,t){return!!~(""+e).indexOf(t)}function Xe(e,t,a,o){for(var r=[],n=0;n<e.length;n++){var s=e[n];if(s){var i=tinycolor(s),l=i.toHsl().l<.5?"sp-thumb-el sp-thumb-dark":"sp-thumb-el sp-thumb-light";l+=tinycolor.equals(t,s)?" sp-thumb-active":"";var c=i.toString(o.preferredFormat||"rgb"),u=Be?"background-color:"+i.toRgbString():"filter:"+i.toFilter();r.push('<span title="'+c+'" data-color="'+i.toRgbString()+'" class="'+l+'"><span class="sp-thumb-inner" style="'+u+';"></span></span>')}else r.push('<span class="sp-thumb-el sp-clear-display" ><span class="sp-clear-palette-only" style="background-color: transparent;"></span></span>')}return"<div class='sp-cf "+a+"'>"+r.join("")+"</div>"}function n(e,t){var a,o,r,n,h=function(e,t){e.locale=e.locale||window.navigator.language,e.locale&&(e.locale=e.locale.split("-")[0].toLowerCase()),"en"!=e.locale&&De.spectrum.localization[e.locale]&&(e=De.extend({},De.spectrum.localization[e.locale],e));var a=De.extend({},Ie,e);return a.callbacks={move:Ge(a.move,t),change:Ge(a.change,t),show:Ge(a.show,t),hide:Ge(a.hide,t),beforeShow:Ge(a.beforeShow,t)},a}(t,e),s=h.type,d="flat"==s,i=h.showSelectionPalette,l=h.localStorageKey,c=h.theme,u=h.callbacks,f=(a=Qe,function(){var e=this,t=arguments;r&&clearTimeout(n),!r&&n||(n=setTimeout(function(){n=null,a.apply(e,t)},o))}),p=!(o=10),g=!1,b=0,m=0,v=0,x=0,y=0,T=0,w=0,_=0,k=0,P=0,C=1,S=[],M=[],z={},j=h.selectionPalette.slice(0),A=h.maxSelectionSize,R="sp-dragging",F=!1,H=null,L=e.ownerDocument,O=(L.body,De(e)),Q=!1,E=De($e,L).addClass(c),N=E.find(".sp-picker-container"),D=E.find(".sp-color"),q=E.find(".sp-dragger"),I=E.find(".sp-hue"),V=E.find(".sp-slider"),W=E.find(".sp-alpha-inner"),B=E.find(".sp-alpha"),K=E.find(".sp-alpha-handle"),$=E.find(".sp-input"),X=E.find(".sp-palette"),Y=E.find(".sp-initial"),G=E.find(".sp-cancel"),U=E.find(".sp-clear"),J=E.find(".sp-choose"),Z=E.find(".sp-palette-toggle"),ee=O.is("input"),te=(ee&&"color"===O.attr("type")&&Je(),ee&&"color"==s),ae=te?De(Ke).addClass(c).addClass(h.className).addClass(h.replacerClassName):De([]),oe=te?ae:O,re=ae.find(".sp-preview-inner"),ne=h.color||ee&&O.val(),se=!1,ie=h.preferredFormat,le=!h.showButtons||h.clickoutFiresChange,ce=!ne,ue=h.allowEmpty,fe=null,he=null,de=null,pe=null,ge=O.attr("id");if(ge!==qe&&0<ge.length){var be=De('label[for="'+ge+'"]');be.length&&be.on("click",function(e){return e.preventDefault(),O.spectrum("show"),!1})}function me(){if(h.showPaletteOnly&&(h.showPalette=!0),Z.text(h.showPaletteOnly?h.togglePaletteMoreText:h.togglePaletteLessText),h.palette){S=h.palette.slice(0),M=De.isArray(S[0])?S:[S],z={};for(var e=0;e<M.length;e++)for(var t=0;t<M[e].length;t++){var a=tinycolor(M[e][t]).toRgbString();z[a]=!0}h.showPaletteOnly&&!ne&&(ne=""===S[0][0]?S[0][0]:Object.keys(z)[0])}E.toggleClass("sp-flat",d),E.toggleClass("sp-input-disabled",!h.showInput),E.toggleClass("sp-alpha-enabled",h.showAlpha),E.toggleClass("sp-clear-enabled",ue),E.toggleClass("sp-buttons-disabled",!h.showButtons),E.toggleClass("sp-palette-buttons-disabled",!h.togglePaletteOnly),E.toggleClass("sp-palette-disabled",!h.showPalette),E.toggleClass("sp-palette-only",h.showPaletteOnly),E.toggleClass("sp-initial-disabled",!h.showInitial),E.addClass(h.className).addClass(h.containerClassName),Qe()}function ve(){if(l){try{var e=window.localStorage,t=e[l].split(",#");1<t.length&&(delete e[l],De.each(t,function(e,t){xe(t)}))}catch(e){}try{j=window.localStorage[l].split(";")}catch(e){}}}function xe(e){if(i){var t=tinycolor(e).toRgbString();if(!z[t]&&-1===De.inArray(t,j))for(j.push(t);j.length>A;)j.shift();if(l)try{window.localStorage[l]=j.join(";")}catch(e){}}}function ye(){var a=Re(),e=De.map(M,function(e,t){return Xe(e,a,"sp-palette-row sp-palette-row-"+t,h)});ve(),j&&e.push(Xe(function(){var e=[];if(h.showPalette)for(var t=0;t<j.length;t++){var a=tinycolor(j[t]).toRgbString();z[a]||e.push(j[t])}return e.reverse().slice(0,h.maxSelectionSize)}(),a,"sp-palette-row sp-palette-row-selection",h)),X.html(e.join(""))}function Te(){if(h.showInitial){var e=se,t=Re();Y.html(Xe([e,t],t,"sp-palette-row-initial",h))}}function we(){(m<=0||b<=0||x<=0)&&Qe(),g=!0,E.addClass(R),H=null,O.trigger("dragstart.spectrum",[Re()])}function _e(){g=!1,E.removeClass(R),O.trigger("dragstop.spectrum",[Re()])}function ke(e){if(F)F=!1;else if(null!==e&&""!==e||!ue){var t=tinycolor(e);t.isValid()?(Ae(t),Fe(),Oe()):$.addClass("sp-validation-error")}else Ae(null),Fe(),Oe()}function Pe(){(p?ze:Ce)()}function Ce(){var e=De.Event("beforeShow.spectrum");p?Qe():(O.trigger(e,[Re()]),!1===u.beforeShow(Re())||e.isDefaultPrevented()||(function(){for(var e=0;e<Ve.length;e++)Ve[e]&&Ve[e].hide()}(),p=!0,De(L).on("keydown.spectrum",Se),De(L).on("click.spectrum",Me),De(window).on("resize.spectrum",f),ae.addClass("sp-active"),E.removeClass("sp-hidden"),Qe(),He(),se=Re(),Te(),u.show(se),O.trigger("show.spectrum",[se])))}function Se(e){27===e.keyCode&&ze()}function Me(e){2!=e.button&&(g||(le?Oe(!0):je(),ze()))}function ze(){p&&!d&&(p=!1,De(L).off("keydown.spectrum",Se),De(L).off("click.spectrum",Me),De(window).off("resize.spectrum",f),ae.removeClass("sp-active"),E.addClass("sp-hidden"),u.hide(Re()),O.trigger("hide.spectrum",[Re()]))}function je(){Ae(se,!0),Oe(!0)}function Ae(e,t){var a,o;tinycolor.equals(e,Re())?He():(e&&e!==qe||!ue?(ce=!1,o=(a=tinycolor(e)).toHsv(),_=o.h%360/360,k=o.s,P=o.v,C=o.a):ce=!0,He(),a&&a.isValid()&&!t&&(ie=h.preferredFormat||a.getFormat()))}function Re(e){return e=e||{},ue&&ce?null:tinycolor.fromRatio({h:_,s:k,v:P,a:Math.round(1e3*C)/1e3},{format:e.format||ie})}function Fe(){He(),u.move(Re()),O.trigger("move.spectrum",[Re()])}function He(){$.removeClass("sp-validation-error"),Le();var e=tinycolor.fromRatio({h:_,s:1,v:1});D.css("background-color",e.toHexString());var t=ie;C<1&&(0!==C||"name"!==t)&&("hex"!==t&&"hex3"!==t&&"hex6"!==t&&"name"!==t||(t="rgb"));var a=Re({format:t}),o="";if(re.removeClass("sp-clear-display"),re.css("background-color","transparent"),!a&&ue)re.addClass("sp-clear-display");else{var r=a.toHexString(),n=a.toRgbString();if(Be||1===a.alpha?re.css("background-color",n):(re.css("background-color","transparent"),re.css("filter",a.toFilter())),h.showAlpha){var s=a.toRgb();s.a=0;var i=tinycolor(s).toRgbString(),l="linear-gradient(left, "+i+", "+r+")";We?W.css("filter",tinycolor(i).toFilter({gradientType:1},r)):(W.css("background","-webkit-"+l),W.css("background","-moz-"+l),W.css("background","-ms-"+l),W.css("background","linear-gradient(to right, "+i+", "+r+")"))}o=a.toString(t)}if(h.showInput&&$.val(o),O.val(o),"text"==h.type||"component"==h.type){var c=a;if(c&&he){var u=c.isLight()||c.getAlpha()<.4?"black":"white";he.css("background-color",c.toRgbString()).css("color",u)}else he.css("background-color",pe).css("color",de)}h.showPalette&&ye(),Te()}function Le(){var e=k,t=P;if(ue&&ce)K.hide(),V.hide(),q.hide();else{K.show(),V.show(),q.show();var a=e*b,o=m-t*m;a=Math.max(-v,Math.min(b-v,a-v)),o=Math.max(-v,Math.min(m-v,o-v)),q.css({top:o+"px",left:a+"px"});var r=C*y;K.css({left:r-T/2+"px"});var n=_*x;V.css({top:n-w+"px"})}}function Oe(e){var t=Re(),a=!tinycolor.equals(t,se);t&&(t.toString(ie),xe(t)),e&&a&&(u.change(t),F=!0,O.trigger("change",[t]))}function Qe(){var e,t,a,o,r,n,s,i,l,c,u,f;p&&(b=D.width(),m=D.height(),v=q.height(),I.width(),x=I.height(),w=V.height(),y=B.width(),T=K.width(),d||(E.css("position","absolute"),h.offset?E.offset(h.offset):E.offset((t=oe,a=(e=E).outerWidth(),o=e.outerHeight(),r=t.outerHeight(),n=e[0].ownerDocument,s=n.documentElement,i=s.clientWidth+De(n).scrollLeft(),l=s.clientHeight+De(n).scrollTop(),c=t.offset(),u=c.left,f=c.top,f+=r,u-=Math.min(u,i<u+a&&a<i?Math.abs(u+a-i):0),{top:f-=Math.min(f,l<f+o&&o<l?Math.abs(+(o+r)):0),bottom:c.bottom,left:u,right:c.right,width:c.width,height:c.height}))),Le(),h.showPalette&&ye(),O.trigger("reflow.spectrum"))}function Ee(){ze(),Q=!0,O.attr("disabled",!0),oe.addClass("sp-disabled")}!function(){if(We&&E.find("*:not(input)").attr("unselectable","on"),me(),fe=De('<span class="sp-original-input-container"></span>'),["margin"].forEach(function(e){fe.css(e,O.css(e))}),"block"==O.css("display")&&fe.css("display","flex"),te)O.after(ae).hide();else if("text"==s)fe.addClass("sp-colorize-container"),O.addClass("spectrum sp-colorize").wrap(fe);else if("component"==s){O.addClass("spectrum").wrap(fe);var e=De(["<div class='sp-colorize-container sp-add-on'>","<div class='sp-colorize'></div> ","</div>"].join(""));e.width(O.outerHeight()+"px").css("border-radius",O.css("border-radius")).css("border",O.css("border")),O.addClass("with-add-on").before(e)}if(he=O.parent().find(".sp-colorize"),de=he.css("color"),pe=he.css("background-color"),ue||U.hide(),d)O.after(E).hide();else{var t="parent"===h.appendTo?O.parent():De(h.appendTo);1!==t.length&&(t=De("body")),t.append(E)}function a(e){return e.data&&e.data.ignore?(Ae(De(e.target).closest(".sp-thumb-el").data("color")),Fe()):(Ae(De(e.target).closest(".sp-thumb-el").data("color")),Fe(),h.hideAfterPaletteSelect?(Oe(!0),ze()):Oe()),!1}ve(),oe.on("click.spectrum touchstart.spectrum",function(e){Q||Pe(),e.stopPropagation(),De(e.target).is("input")||e.preventDefault()}),!O.is(":disabled")&&!0!==h.disabled||Ee(),E.click(Ye),[$,O].forEach(function(t){t.change(function(){ke(t.val())}),t.on("paste",function(){setTimeout(function(){ke(t.val())},1)}),t.keydown(function(e){13==e.keyCode&&(ke(De(t).val()),t==O&&ze())})}),G.text(h.cancelText),G.on("click.spectrum",function(e){e.stopPropagation(),e.preventDefault(),je(),ze()}),U.attr("title",h.clearText),U.on("click.spectrum",function(e){e.stopPropagation(),e.preventDefault(),ce=!0,Fe(),d&&Oe(!0)}),J.text(h.chooseText),J.on("click.spectrum",function(e){e.stopPropagation(),e.preventDefault(),We&&$.is(":focus")&&$.trigger("change"),$.hasClass("sp-validation-error")||(Oe(!0),ze())}),Z.text(h.showPaletteOnly?h.togglePaletteMoreText:h.togglePaletteLessText),Z.on("click.spectrum",function(e){e.stopPropagation(),e.preventDefault(),h.showPaletteOnly=!h.showPaletteOnly,h.showPaletteOnly||d||E.css("left","-="+(N.outerWidth(!0)+5)),me()}),Ue(B,function(e,t,a){C=e/y,ce=!1,a.shiftKey&&(C=Math.round(10*C)/10),Fe()},we,_e),Ue(I,function(e,t){_=parseFloat(t/x),ce=!1,h.showAlpha||(C=1),Fe()},we,_e),Ue(D,function(e,t,a){if(a.shiftKey){if(!H){var o=k*b,r=m-P*m,n=Math.abs(e-o)>Math.abs(t-r);H=n?"x":"y"}}else H=null;var s=!H||"y"===H;H&&"x"!==H||(k=parseFloat(e/b)),s&&(P=parseFloat((m-t)/m)),ce=!1,h.showAlpha||(C=1),Fe()},we,_e),ne?(Ae(ne),He(),ie=tinycolor(ne).format||h.preferredFormat,xe(ne)):(""===ne&&Ae(ne),He()),d&&Ce();var o=We?"mousedown.spectrum":"click.spectrum touchstart.spectrum";X.on(o,".sp-thumb-el",a),Y.on(o,".sp-thumb-el:nth-child(1)",{ignore:!0},a)}();var Ne={show:Ce,hide:ze,toggle:Pe,reflow:Qe,option:function(e,t){return e===qe?De.extend({},h):t===qe?h[e]:(h[e]=t,"preferredFormat"===e&&(ie=h.preferredFormat),void me())},enable:function(){Q=!1,O.attr("disabled",!1),oe.removeClass("sp-disabled")},disable:Ee,offset:function(e){h.offset=e,Qe()},set:function(e){Ae(e),Oe()},get:Re,destroy:function(){O.show().removeClass("spectrum with-add-on sp-colorize"),oe.off("click.spectrum touchstart.spectrum"),E.remove(),ae.remove(),he&&he.css("background-color",pe).css("color",de);var e=O.closest(".sp-original-input-container");0<e.length&&e.after(O).remove(),Ve[Ne.id]=null},container:E};return Ne.id=Ve.push(Ne)-1,Ne}function a(){}function Ye(e){e.stopPropagation()}function Ge(e,t){var a=Array.prototype.slice,o=a.call(arguments,2);return function(){return e.apply(t,o.concat(a.call(arguments)))}}function Ue(s,i,t,e){i=i||function(){},t=t||function(){},e=e||function(){};var l=document,c=!1,u={},f=0,h=0,d="ontouchstart"in window,a={};function p(e){e.stopPropagation&&e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.returnValue=!1}function o(e){if(c){if(We&&l.documentMode<9&&!e.button)return g();var t=e.originalEvent&&e.originalEvent.touches&&e.originalEvent.touches[0],a=t&&t.pageX||e.pageX,o=t&&t.pageY||e.pageY,r=Math.max(0,Math.min(a-u.left,h)),n=Math.max(0,Math.min(o-u.top,f));d&&p(e),i.apply(s,[r,n,e])}}function g(){c&&(De(l).off(a),De(l.body).removeClass("sp-dragging"),setTimeout(function(){e.apply(s,arguments)},0)),c=!1}a.selectstart=p,a.dragstart=p,a["touchmove mousemove"]=o,a["touchend mouseup"]=g,De(s).on("touchstart mousedown",function(e){(e.which?3==e.which:2==e.button)||c||!1!==t.apply(s,arguments)&&(c=!0,f=De(s).height(),h=De(s).width(),u=De(s).offset(),De(l).on(a),De(l.body).addClass("sp-dragging"),o(e),p(e))})}function Je(){return De.fn.spectrum.inputTypeColorSupport()}var s="spectrum.id";De.fn.spectrum=function(a,e){if("string"!=typeof a)return this.spectrum("destroy").each(function(){var e=De.extend({},De(this).data(),a);De(this).is("input")?e.flat||"flat"==e.type?e.type="flat":"color"==De(this).attr("type")?e.type="color":e.type=e.type||"component":e.type="noInput";var t=n(this,e);De(this).data(s,t.id)});var o=this,r=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=Ve[De(this).data(s)];if(e){var t=e[a];if(!t)throw new Error("Spectrum: no such method: '"+a+"'");"get"==a?o=e.get():"container"==a?o=e.container:"option"==a?o=e.option.apply(e,r):"destroy"==a?(e.destroy(),De(this).removeData(s)):t.apply(e,r)}}),o},De.fn.spectrum.load=!0,De.fn.spectrum.loadOpts={},De.fn.spectrum.draggable=Ue,De.fn.spectrum.defaults=Ie,De.fn.spectrum.inputTypeColorSupport=function e(){if(void 0===e._cachedResult){var t=De("<input type='color'/>")[0];e._cachedResult="color"===t.type&&""!==t.value}return e._cachedResult},De.spectrum={},De.spectrum.localization={},De.spectrum.palettes={},De.fn.spectrum.processNativeColorInputs=function(){var e=De("input[type=color]");e.length&&!Je()&&e.spectrum({preferredFormat:"hex6"})},function(){var n=/^[\s,#]+/,s=/\s+$/,o=0,c=Math,i=c.round,u=c.min,f=c.max,e=c.random,h=function(e,t){if(t=t||{},(e=e||"")instanceof h)return e;if(!(this instanceof h))return new h(e,t);var a=function(e){var t={r:0,g:0,b:0},a=1,o=!1,r=!1;"string"==typeof e&&(e=function(e){e=e.replace(n,"").replace(s,"").toLowerCase();var t,a=!1;if(C[e])e=C[e],a=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};if(t=Q.rgb.exec(e))return{r:t[1],g:t[2],b:t[3]};if(t=Q.rgba.exec(e))return{r:t[1],g:t[2],b:t[3],a:t[4]};if(t=Q.hsl.exec(e))return{h:t[1],s:t[2],l:t[3]};if(t=Q.hsla.exec(e))return{h:t[1],s:t[2],l:t[3],a:t[4]};if(t=Q.hsv.exec(e))return{h:t[1],s:t[2],v:t[3]};if(t=Q.hsva.exec(e))return{h:t[1],s:t[2],v:t[3],a:t[4]};if(t=Q.hex8.exec(e))return{a:function(e){return A(e)/255}(t[1]),r:A(t[2]),g:A(t[3]),b:A(t[4]),format:a?"name":"hex8"};if(t=Q.hex6.exec(e))return{r:A(t[1]),g:A(t[2]),b:A(t[3]),format:a?"name":"hex"};if(t=Q.hex3.exec(e))return{r:A(t[1]+""+t[1]),g:A(t[2]+""+t[2]),b:A(t[3]+""+t[3]),format:a?"name":"hex"};return!1}(e));"object"==typeof e&&(e.hasOwnProperty("r")&&e.hasOwnProperty("g")&&e.hasOwnProperty("b")?(t=function(e,t,a){return{r:255*z(e,255),g:255*z(t,255),b:255*z(a,255)}}(e.r,e.g,e.b),o=!0,r="%"===String(e.r).substr(-1)?"prgb":"rgb"):e.hasOwnProperty("h")&&e.hasOwnProperty("s")&&e.hasOwnProperty("v")?(e.s=F(e.s),e.v=F(e.v),t=function(e,t,a){e=6*z(e,360),t=z(t,100),a=z(a,100);var o=c.floor(e),r=e-o,n=a*(1-t),s=a*(1-r*t),i=a*(1-(1-r)*t),l=o%6;return{r:255*[a,s,n,n,i,a][l],g:255*[i,a,a,s,n,n][l],b:255*[n,n,i,a,a,s][l]}}(e.h,e.s,e.v),o=!0,r="hsv"):e.hasOwnProperty("h")&&e.hasOwnProperty("s")&&e.hasOwnProperty("l")&&(e.s=F(e.s),e.l=F(e.l),t=function(e,t,a){var o,r,n;function s(e,t,a){return a<0&&(a+=1),1<a&&--a,a<1/6?e+6*(t-e)*a:a<.5?t:a<2/3?e+(t-e)*(2/3-a)*6:e}if(e=z(e,360),t=z(t,100),a=z(a,100),0===t)o=r=n=a;else{var i=a<.5?a*(1+t):a+t-a*t,l=2*a-i;o=s(l,i,e+1/3),r=s(l,i,e),n=s(l,i,e-1/3)}return{r:255*o,g:255*r,b:255*n}}(e.h,e.s,e.l),o=!0,r="hsl"),e.hasOwnProperty("a")&&(a=e.a));return a=M(a),{ok:o,format:e.format||r,r:u(255,f(t.r,0)),g:u(255,f(t.g,0)),b:u(255,f(t.b,0)),a:a}}(e);this._originalInput=e,this._r=a.r,this._g=a.g,this._b=a.b,this._a=a.a,this._roundA=i(1e3*this._a)/1e3,this._format=t.format||a.format,this._gradientType=t.gradientType,this._r<1&&(this._r=i(this._r)),this._g<1&&(this._g=i(this._g)),this._b<1&&(this._b=i(this._b)),this._ok=a.ok,this._tc_id=o++};function r(e,t,a){e=z(e,255),t=z(t,255),a=z(a,255);var o,r,n=f(e,t,a),s=u(e,t,a),i=(n+s)/2;if(n==s)o=r=0;else{var l=n-s;switch(r=.5<i?l/(2-n-s):l/(n+s),n){case e:o=(t-a)/l+(t<a?6:0);break;case t:o=(a-e)/l+2;break;case a:o=(e-t)/l+4}o/=6}return{h:o,s:r,l:i}}function l(e,t,a){e=z(e,255),t=z(t,255),a=z(a,255);var o,r,n=f(e,t,a),s=u(e,t,a),i=n,l=n-s;if(r=0===n?0:l/n,n==s)o=0;else{switch(n){case e:o=(t-a)/l+(t<a?6:0);break;case t:o=(a-e)/l+2;break;case a:o=(e-t)/l+4}o/=6}return{h:o,s:r,v:i}}function t(e,t,a,o){var r=[R(i(e).toString(16)),R(i(t).toString(16)),R(i(a).toString(16))];return o&&r[0].charAt(0)==r[0].charAt(1)&&r[1].charAt(0)==r[1].charAt(1)&&r[2].charAt(0)==r[2].charAt(1)?r[0].charAt(0)+r[1].charAt(0)+r[2].charAt(0):r.join("")}function d(e,t,a,o){var r;return[R((r=o,Math.round(255*parseFloat(r)).toString(16))),R(i(e).toString(16)),R(i(t).toString(16)),R(i(a).toString(16))].join("")}function a(e,t){t=0===t?0:t||10;var a=h(e).toHsl();return a.s-=t/100,a.s=j(a.s),h(a)}function p(e,t){t=0===t?0:t||10;var a=h(e).toHsl();return a.s+=t/100,a.s=j(a.s),h(a)}function g(e){return h(e).desaturate(100)}function b(e,t){t=0===t?0:t||10;var a=h(e).toHsl();return a.l+=t/100,a.l=j(a.l),h(a)}function m(e,t){t=0===t?0:t||10;var a=h(e).toRgb();return a.r=f(0,u(255,a.r-i(-t/100*255))),a.g=f(0,u(255,a.g-i(-t/100*255))),a.b=f(0,u(255,a.b-i(-t/100*255))),h(a)}function v(e,t){t=0===t?0:t||10;var a=h(e).toHsl();return a.l-=t/100,a.l=j(a.l),h(a)}function x(e,t){var a=h(e).toHsl(),o=(i(a.h)+t)%360;return a.h=o<0?360+o:o,h(a)}function y(e){var t=h(e).toHsl();return t.h=(t.h+180)%360,h(t)}function T(e){var t=h(e).toHsl(),a=t.h;return[h(e),h({h:(a+120)%360,s:t.s,l:t.l}),h({h:(a+240)%360,s:t.s,l:t.l})]}function w(e){var t=h(e).toHsl(),a=t.h;return[h(e),h({h:(a+90)%360,s:t.s,l:t.l}),h({h:(a+180)%360,s:t.s,l:t.l}),h({h:(a+270)%360,s:t.s,l:t.l})]}function _(e){var t=h(e).toHsl(),a=t.h;return[h(e),h({h:(a+72)%360,s:t.s,l:t.l}),h({h:(a+216)%360,s:t.s,l:t.l})]}function k(e,t,a){t=t||6,a=a||30;var o=h(e).toHsl(),r=360/a,n=[h(e)];for(o.h=(o.h-(r*t>>1)+720)%360;--t;)o.h=(o.h+r)%360,n.push(h(o));return n}function P(e,t){t=t||6;for(var a=h(e).toHsv(),o=a.h,r=a.s,n=a.v,s=[],i=1/t;t--;)s.push(h({h:o,s:r,v:n})),n=(n+i)%1;return s}h.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},setAlpha:function(e){return this._a=M(e),this._roundA=i(1e3*this._a)/1e3,this},toHsv:function(){var e=l(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=l(this._r,this._g,this._b),t=i(360*e.h),a=i(100*e.s),o=i(100*e.v);return 1==this._a?"hsv("+t+", "+a+"%, "+o+"%)":"hsva("+t+", "+a+"%, "+o+"%, "+this._roundA+")"},toHsl:function(){var e=r(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=r(this._r,this._g,this._b),t=i(360*e.h),a=i(100*e.s),o=i(100*e.l);return 1==this._a?"hsl("+t+", "+a+"%, "+o+"%)":"hsla("+t+", "+a+"%, "+o+"%, "+this._roundA+")"},toHex:function(e){return t(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(){return d(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:i(this._r),g:i(this._g),b:i(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+i(this._r)+", "+i(this._g)+", "+i(this._b)+")":"rgba("+i(this._r)+", "+i(this._g)+", "+i(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:i(100*z(this._r,255))+"%",g:i(100*z(this._g,255))+"%",b:i(100*z(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+i(100*z(this._r,255))+"%, "+i(100*z(this._g,255))+"%, "+i(100*z(this._b,255))+"%)":"rgba("+i(100*z(this._r,255))+"%, "+i(100*z(this._g,255))+"%, "+i(100*z(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(S[t(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+d(this._r,this._g,this._b,this._a),a=t,o=this._gradientType?"GradientType = 1, ":"";e&&(a=h(e).toHex8String());return"progid:DXImageTransform.Microsoft.gradient("+o+"startColorstr="+t+",endColorstr="+a+")"},toString:function(e){var t=!!e;e=e||this._format;var a=!1,o=this._a<1&&0<=this._a;return t||!o||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"name"!==e?("rgb"===e&&(a=this.toRgbString()),"prgb"===e&&(a=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(a=this.toHexString()),"hex3"===e&&(a=this.toHexString(!0)),"hex8"===e&&(a=this.toHex8String()),"name"===e&&(a=this.toName()),"hsl"===e&&(a=this.toHslString()),"hsv"===e&&(a=this.toHsvString()),a||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},_applyModification:function(e,t){var a=e.apply(null,[this].concat([].slice.call(t)));return this._r=a._r,this._g=a._g,this._b=a._b,this.setAlpha(a._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(m,arguments)},darken:function(){return this._applyModification(v,arguments)},desaturate:function(){return this._applyModification(a,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(x,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(k,arguments)},complement:function(){return this._applyCombination(y,arguments)},monochromatic:function(){return this._applyCombination(P,arguments)},splitcomplement:function(){return this._applyCombination(_,arguments)},triad:function(){return this._applyCombination(T,arguments)},tetrad:function(){return this._applyCombination(w,arguments)}},h.fromRatio=function(e,t){if("object"==typeof e){var a={};for(var o in e)e.hasOwnProperty(o)&&(a[o]="a"===o?e[o]:F(e[o]));e=a}return h(e,t)},h.equals=function(e,t){return!(!e||!t)&&h(e).toRgbString()==h(t).toRgbString()},h.random=function(){return h.fromRatio({r:e(),g:e(),b:e()})},h.mix=function(e,t,a){a=0===a?0:a||50;var o,r=h(e).toRgb(),n=h(t).toRgb(),s=a/100,i=2*s-1,l=n.a-r.a,c=1-(o=((o=i*l==-1?i:(i+l)/(1+i*l))+1)/2),u={r:n.r*o+r.r*c,g:n.g*o+r.g*c,b:n.b*o+r.b*c,a:n.a*s+r.a*(1-s)};return h(u)},h.readability=function(e,t){var a=h(e),o=h(t),r=a.toRgb(),n=o.toRgb(),s=a.getBrightness(),i=o.getBrightness(),l=Math.max(r.r,n.r)-Math.min(r.r,n.r)+Math.max(r.g,n.g)-Math.min(r.g,n.g)+Math.max(r.b,n.b)-Math.min(r.b,n.b);return{brightness:Math.abs(s-i),color:l}},h.isReadable=function(e,t){var a=h.readability(e,t);return 125<a.brightness&&500<a.color},h.mostReadable=function(e,t){for(var a=null,o=0,r=!1,n=0;n<t.length;n++){var s=h.readability(e,t[n]),i=125<s.brightness&&500<s.color,l=s.brightness/125*3+s.color/500;(i&&!r||i&&r&&o<l||!i&&!r&&o<l)&&(r=i,o=l,a=h(t[n]))}return a};var C=h.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},S=h.hexNames=function(e){var t={};for(var a in e)e.hasOwnProperty(a)&&(t[e[a]]=a);return t}(C);function M(e){return e=parseFloat(e),(isNaN(e)||e<0||1<e)&&(e=1),e}function z(e,t){var a;"string"==typeof(a=e)&&-1!=a.indexOf(".")&&1===parseFloat(a)&&(e="100%");var o,r="string"==typeof(o=e)&&-1!=o.indexOf("%");return e=u(t,f(0,parseFloat(e))),r&&(e=parseInt(e*t,10)/100),c.abs(e-t)<1e-6?1:e%t/parseFloat(t)}function j(e){return u(1,f(0,e))}function A(e){return parseInt(e,16)}function R(e){return 1==e.length?"0"+e:""+e}function F(e){return e<=1&&(e=100*e+"%"),e}var H,L,O,Q=(L="[\\s|\\(]+("+(H="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+H+")[,|\\s]+("+H+")\\s*\\)?",O="[\\s|\\(]+("+H+")[,|\\s]+("+H+")[,|\\s]+("+H+")[,|\\s]+("+H+")\\s*\\)?",{rgb:new RegExp("rgb"+L),rgba:new RegExp("rgba"+O),hsl:new RegExp("hsl"+L),hsla:new RegExp("hsla"+O),hsv:new RegExp("hsv"+L),hsva:new RegExp("hsva"+O),hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});window.tinycolor=h}(),De(function(){De.fn.spectrum.load&&De.fn.spectrum.processNativeColorInputs()})}),jQuery.spectrum.localization.ar={cancelText:"إلغاء",chooseText:"إختار",clearText:"إرجاع الألوان على ما كانت",noColorSelectedText:"لم تختار أي لون",togglePaletteMoreText:"أكثر",togglePaletteLessText:"أقل"},jQuery.spectrum.localization.ca={cancelText:"Cancel·lar",chooseText:"Escollir",clearText:"Esborrar color seleccionat",noColorSelectedText:"Cap color seleccionat",togglePaletteMoreText:"Més",togglePaletteLessText:"Menys"},jQuery.spectrum.localization.cs={cancelText:"zrušit",chooseText:"vybrat",clearText:"Resetovat výměr barev",noColorSelectedText:"Žádná barva nebyla vybrána",togglePaletteMoreText:"více",togglePaletteLessText:"méně"},jQuery.spectrum.localization.de={cancelText:"Abbrechen",chooseText:"Wählen",clearText:"Farbauswahl zurücksetzen",noColorSelectedText:"Keine Farbe ausgewählt",togglePaletteMoreText:"Mehr",togglePaletteLessText:"Weniger"},jQuery.spectrum.localization.dk={cancelText:"annuller",chooseText:"Vælg"},jQuery.spectrum.localization.es={cancelText:"Cancelar",chooseText:"Elegir",clearText:"Borrar color seleccionado",noColorSelectedText:"Ningún color seleccionado",togglePaletteMoreText:"Más",togglePaletteLessText:"Menos"},jQuery.spectrum.localization.et={cancelText:"Katkesta",chooseText:"Vali",clearText:"Tühista värvivalik",noColorSelectedText:"Ühtki värvi pole valitud",togglePaletteMoreText:"Rohkem",togglePaletteLessText:"Vähem"},jQuery.spectrum.localization.fa={cancelText:"لغو",chooseText:"انتخاب",clearText:"تنظیم مجدد رنگ",noColorSelectedText:"هیچ رنگی انتخاب نشده است!",togglePaletteMoreText:"بیشتر",togglePaletteLessText:"کمتر"},jQuery.spectrum.localization.fi={cancelText:"Kumoa",chooseText:"Valitse"},jQuery.spectrum.localization.fr={cancelText:"Annuler",chooseText:"Valider",clearText:"Effacer couleur sélectionnée",noColorSelectedText:"Aucune couleur sélectionnée",togglePaletteMoreText:"Plus",togglePaletteLessText:"Moins"},jQuery.spectrum.localization.gr={cancelText:"Ακύρωση",chooseText:"Επιλογή",clearText:"Καθαρισμός επιλεγμένου χρώματος",noColorSelectedText:"Δεν έχει επιλεχθεί κάποιο χρώμα",togglePaletteMoreText:"Περισσότερα",togglePaletteLessText:"Λιγότερα"},jQuery.spectrum.localization.he={cancelText:"בטל בחירה",chooseText:"בחר צבע",clearText:"אפס בחירה",noColorSelectedText:"לא נבחר צבע",togglePaletteMoreText:"עוד צבעים",togglePaletteLessText:"פחות צבעים"},jQuery.spectrum.localization.hr={cancelText:"Odustani",chooseText:"Odaberi",clearText:"Poništi odabir",noColorSelectedText:"Niti jedna boja nije odabrana",togglePaletteMoreText:"Više",togglePaletteLessText:"Manje"},jQuery.spectrum.localization.hu={cancelText:"Mégsem",chooseText:"Mentés",clearText:"A színválasztás visszaállítása",noColorSelectedText:"Nincs szín kijelölve",togglePaletteMoreText:"Több",togglePaletteLessText:"Kevesebb"},jQuery.spectrum.localization.id={cancelText:"Batal",chooseText:"Pilih",clearText:"Hapus Pilihan Warna",noColorSelectedText:"Warna Tidak Dipilih",togglePaletteMoreText:"tambah",togglePaletteLessText:"kurangi"},jQuery.spectrum.localization.it={cancelText:"annulla",chooseText:"scegli",clearText:"Annulla selezione colore",noColorSelectedText:"Nessun colore selezionato"},jQuery.spectrum.localization.ja={cancelText:"中止",chooseText:"選択"},jQuery.spectrum.localization.ko={cancelText:"취소",chooseText:"선택",clearText:"선택 초기화",noColorSelectedText:"선택된 색상 없음",togglePaletteMoreText:"더보기",togglePaletteLessText:"줄이기"},jQuery.spectrum.localization.lt={cancelText:"Atšaukti",chooseText:"Pasirinkti",clearText:"Išvalyti pasirinkimą",noColorSelectedText:"Spalva nepasirinkta",togglePaletteMoreText:"Daugiau",togglePaletteLessText:"Mažiau"},jQuery.spectrum.localization["nb-no"]={cancelText:"Avbryte",chooseText:"Velg",clearText:"Tilbakestill",noColorSelectedText:"Farge er ikke valgt",togglePaletteMoreText:"Mer",togglePaletteLessText:"Mindre"},jQuery.spectrum.localization["nl-nl"]={cancelText:"Annuleer",chooseText:"Kies",clearText:"Wis kleur selectie",togglePaletteMoreText:"Meer",togglePaletteLessText:"Minder"},jQuery.spectrum.localization.pl={cancelText:"Anuluj",chooseText:"Wybierz",clearText:"Usuń wybór koloru",noColorSelectedText:"Nie wybrano koloru",togglePaletteMoreText:"Więcej",togglePaletteLessText:"Mniej"},jQuery.spectrum.localization["pt-br"]={cancelText:"Cancelar",chooseText:"Escolher",clearText:"Limpar cor selecionada",noColorSelectedText:"Nenhuma cor selecionada",togglePaletteMoreText:"Mais",togglePaletteLessText:"Menos"},jQuery.spectrum.localization["pt-pt"]={cancelText:"Cancelar",chooseText:"Escolher",clearText:"Limpar cor seleccionada",noColorSelectedText:"Nenhuma cor seleccionada",togglePaletteMoreText:"Mais",togglePaletteLessText:"Menos"},jQuery.spectrum.localization.ru={cancelText:"Отмена",chooseText:"Выбрать",clearText:"Сбросить",noColorSelectedText:"Цвет не выбран",togglePaletteMoreText:"Ещё",togglePaletteLessText:"Скрыть"},jQuery.spectrum.localization.sv={cancelText:"Avbryt",chooseText:"Välj"},jQuery.spectrum.localization.tr={cancelText:"iptal",chooseText:"tamam"},jQuery.spectrum.localization["zh-cn"]={cancelText:"取消",chooseText:"选择",clearText:"清除",togglePaletteMoreText:"更多选项",togglePaletteLessText:"隐藏",noColorSelectedText:"尚未选择任何颜色"},jQuery.spectrum.localization["zh-tw"]={cancelText:"取消",chooseText:"選擇",clearText:"清除",togglePaletteMoreText:"更多選項",togglePaletteLessText:"隱藏",noColorSelectedText:"尚未選擇任何顏色"};
\ No newline at end of file
<?php
/*
Plugin Name: Cookie Notice & Compliance for GDPR / CCPA
Description: Cookie Notice allows you to you elegantly inform users that your site uses cookies and helps you comply with GDPR, CCPA and other data privacy laws.
Version: 2.4.10
Author: Hu-manity.co
Author URI: https://hu-manity.co/
Plugin URI: https://cookie-compliance.co/
License: MIT License
License URI: https://opensource.org/licenses/MIT
Text Domain: cookie-notice
Domain Path: /languages
Cookie Notice
Copyright (C) 2023, Hu-manity.co - info@hu-manity.co
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice class.
*
* @class Cookie_Notice
* @version 2.4.10
*/
class Cookie_Notice {
private $status_data = [
'status' => '',
'subscription' => 'basic',
'threshold_exceeded' => false
];
private $x_api_key = 'hudft60djisdusdjwek';
private $app_host_url = 'https://app.hu-manity.co';
private $app_login_url = 'https://app.hu-manity.co/#/en/cc2/login';
private $app_dashboard_url = 'https://app.hu-manity.co/#/en/cc/dashboard';
private $account_api_url = 'https://account-api.hu-manity.co';
private $designer_api_url = 'https://designer-api.hu-manity.co';
private $transactional_api_url = 'https://transactional-api.hu-manity.co';
private $app_widget_url = '//cdn.hu-manity.co/hu-banner.min.js';
private $deactivaion_url = '';
private $network_admin = false;
private $plugin_network_active = false;
private static $_instance;
private $notices = [];
public $options = [];
public $network_options = [];
public $bot_detect;
public $dashboard;
public $frontend;
public $settings;
public $welcome;
public $welcome_api;
public $welcome_frontend;
public $db_version;
/**
* @var $defaults
*/
public $defaults = [
'general' => [
'global_override' => false,
'global_cookie' => false,
'app_id' => '',
'app_key' => '',
'app_blocking' => true,
'conditional_active' => false,
'conditional_display' => 'hide',
'conditional_rules' => [],
'caching_compatibility' => true,
'debug_mode' => false,
'position' => 'bottom',
'message_text' => '',
'css_class' => '',
'accept_text' => '',
'refuse_text' => '',
'refuse_opt' => false,
'refuse_code' => '',
'refuse_code_head' => '',
'revoke_cookies' => false,
'revoke_cookies_opt' => 'automatic',
'revoke_message_text' => '',
'revoke_text' => '',
'redirection' => false,
'see_more' => false,
'link_target' => '_blank',
'link_position' => 'banner',
'time' => 'month',
'time_rejected' => 'month',
'hide_effect' => 'fade',
'on_scroll' => false,
'on_scroll_offset' => 100,
'on_click' => false,
'colors' => [
'text' => '#fff',
'button' => '#00a99d',
'bar' => '#32323a',
'bar_opacity' => 100
],
'see_more_opt' => [
'text' => '',
'link_type' => 'page',
'id' => 0,
'link' => '',
'sync' => false
],
'script_placement' => 'header',
'translate' => true,
'deactivation_delete' => false,
'update_version' => 8,
'update_notice' => true,
'update_notice_diss' => false,
'update_delay_date' => 0,
'update_threshold_date' => 0
],
'data' => [
'status' => '',
'subscription' => 'basic',
'threshold_exceeded' => false
],
'version' => '2.4.10'
];
/**
* Disable object cloning.
*
* @return void
*/
public function __clone() {}
/**
* Disable unserializing of the class.
*
* @return void
*/
public function __wakeup() {}
/**
* Main plugin instance.
*
* @return object
*/
public static function instance() {
if ( self::$_instance === null ) {
self::$_instance = new self();
add_action( 'init', [ self::$_instance, 'load_textdomain' ] );
self::$_instance->includes();
self::$_instance->bot_detect = new Cookie_Notice_Bot_Detect();
self::$_instance->dashboard = new Cookie_Notice_Dashboard();
self::$_instance->frontend = new Cookie_Notice_Frontend();
self::$_instance->settings = new Cookie_Notice_Settings();
self::$_instance->welcome = new Cookie_Notice_Welcome();
self::$_instance->welcome_api = new Cookie_Notice_Welcome_API();
self::$_instance->welcome_frontend = new Cookie_Notice_Welcome_Frontend();
}
return self::$_instance;
}
/**
* Class constructor.
*
* @return void
*/
public function __construct() {
// define plugin constants
$this->define_constants();
// activation hooks
register_activation_hook( __FILE__, [ $this, 'activation' ] );
register_deactivation_hook( __FILE__, [ $this, 'deactivation' ] );
// set network data
$this->set_network_data();
$this->check_legacy_options();
// get options
if ( is_multisite() ) {
// get network options
$this->network_options = get_site_option( 'cookie_notice_options', $this->defaults['general'] );
if ( $this->is_network_admin() ) {
$options = $this->network_options;
} else {
$page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
// settings page?
if ( is_admin() && $page === 'cookie-notice' ) {
// get current url path
$url_path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
if ( is_string( $url_path ) && basename( $url_path ) === 'admin.php' ) {
// get site options
$options = get_option( 'cookie_notice_options', $this->defaults['general'] );
}
} else {
if ( $this->is_plugin_network_active() && $this->network_options['global_override'] )
$options = $this->network_options;
else
$options = get_option( 'cookie_notice_options', $this->defaults['general'] );
}
}
} else
$options = get_option( 'cookie_notice_options', $this->defaults['general'] );
// merge old options with new ones
$this->options['general'] = $this->multi_array_merge( $this->defaults['general'], $options );
if ( ! isset( $this->options['general']['see_more_opt']['sync'] ) )
$this->options['general']['see_more_opt']['sync'] = $this->defaults['general']['see_more_opt']['sync'];
// actions
add_action( 'plugins_loaded', [ $this, 'set_status_data' ] );
add_action( 'init', [ $this, 'register_shortcodes' ] );
add_action( 'init', [ $this, 'wpsc_add_cookie' ] );
add_action( 'init', [ $this, 'set_plugin_links' ] );
add_action( 'admin_init', [ $this, 'update_notice' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
add_action( 'admin_footer', [ $this, 'deactivate_plugin_template' ] );
add_action( 'wp_ajax_cn_dismiss_notice', [ $this, 'ajax_dismiss_admin_notice' ] );
add_action( 'wp_ajax_cn-deactivate-plugin', [ $this, 'deactivate_plugin' ] );
}
/**
* Check legacy options.
*
* @return void
*/
public function check_legacy_options() {
// multisite?
if ( is_multisite() ) {
// get network options
$site_options = get_site_option( 'cookie_notice_options', $this->defaults['general'] );
// update legacy options
$site_options = $this->update_legacy_options( $site_options );
// any changes?
if ( $site_options !== false )
update_site_option( 'cookie_notice_options', $site_options );
}
// get options
$options = get_option( 'cookie_notice_options', $this->defaults['general'] );
// update legacy options
$options = $this->update_legacy_options( $options );
// any changes?
if ( $options !== false )
update_option( 'cookie_notice_options', $options );
}
/**
* Maybe change legacy options.
*
* @param array $options
* @return false|array
*/
public function update_legacy_options( $options ) {
$options_changed = false;
// check legacy parameters that were yes/no strings
foreach ( [ 'refuse_opt', 'on_scroll', 'on_click', 'deactivation_delete', 'see_more' ] as $param ) {
if ( array_key_exists( $param, $options ) && ! is_bool( $options[$param] ) ) {
$options[$param] = $options[$param] === 'yes';
$options_changed = true;
}
}
// check hide banner
if ( isset( $options['hide_banner'] ) ) {
if ( $options['hide_banner'] && ! isset( $options['conditional_active'] ) ) {
$options['conditional_active'] = true;
$options['conditional_display'] = 'hide';
$options['conditional_rules'] = [
1 => [
1 => [
'param' => 'user_type',
'operator' => 'equal',
'value' => 'logged_in'
]
]
];
}
unset( $options['hide_banner'] );
$options_changed = true;
}
if ( $options_changed )
return $options;
else
return false;
}
/**
* Setup plugin constants.
*
* @return void
*/
private function define_constants() {
define( 'COOKIE_NOTICE_URL', plugins_url( '', __FILE__ ) );
define( 'COOKIE_NOTICE_PATH', plugin_dir_path( __FILE__ ) );
define( 'COOKIE_NOTICE_BASENAME', plugin_basename( __FILE__ ) );
}
/**
* Set cookie compliance status data.
*
* @return void
*/
public function set_status_data() {
$default_data = $this->defaults['data'];
if ( is_multisite() ) {
if ( $this->is_plugin_network_active() ) {
// network
if ( $this->is_network_admin() ) {
if ( $this->network_options['global_override'] )
$status_data = get_site_option( 'cookie_notice_status', $default_data );
else
$status_data = $default_data;
// site
} else {
if ( $this->network_options['global_override'] )
$status_data = get_site_option( 'cookie_notice_status', $default_data );
else
$status_data = get_option( 'cookie_notice_status', $default_data );
}
} else {
// network
if ( $this->is_network_admin() )
$status_data = $default_data;
// site
else
$status_data = get_option( 'cookie_notice_status', $default_data );
}
} else
$status_data = get_option( 'cookie_notice_status', $default_data );
// old status format?
if ( ! is_array( $status_data ) ) {
// update config data
$status_data = $this->welcome_api->get_app_config( '', true );
} else {
// merge database data with default data
$status_data = array_merge( $default_data, $status_data );
}
if ( $status_data['threshold_exceeded'] )
$this->options['general']['app_blocking'] = false;
// set status data
$this->status_data = [
'status' => $this->check_status( $status_data['status'] ),
'subscription' => $this->check_subscription( $status_data['subscription'] ),
'threshold_exceeded' => (bool) $status_data['threshold_exceeded']
];
}
/**
* Get cookie compliance status.
*
* @return string
*/
public function get_status() {
return $this->status_data['status'];
}
/**
* Check cookie compliance status.
*
* @param string $status
* @return string
*/
public function check_status( $status ) {
$status = sanitize_key( $status );
return ! empty( $status ) && in_array( $status, [ 'active', 'pending' ], true ) ? $status : $this->defaults['data']['status'];
}
/**
* Get cookie compliance subscription.
*
* @return string
*/
public function get_subscription() {
return $this->status_data['subscription'];
}
/**
* Check cookie compliance subscription.
*
* @param string $subscription
* @return string
*/
public function check_subscription( $subscription ) {
$subscription = sanitize_key( $subscription );
return ! empty( $subscription ) && in_array( $subscription, [ 'basic', 'pro' ], true ) ? $subscription : $this->defaults['data']['subscription'];
}
/**
* Check whether the current threshold is exceeded.
*
* @return bool
*/
public function threshold_exceeded() {
return $this->status_data['threshold_exceeded'];
}
/**
* Get endpoint URL.
*
* @param string $type
* @param string $query
* @return string
*/
public function get_url( $type, $query = '' ) {
if ( $type === 'login' )
$url = $this->app_login_url;
elseif ( $type === 'dashboard' )
$url = $this->app_dashboard_url;
elseif ( $type === 'widget' )
$url = $this->app_widget_url;
elseif ( $type === 'host' )
$url = $this->app_host_url;
elseif ( $type === 'account_api' )
$url = $this->account_api_url;
elseif ( $type === 'designer_api' )
$url = $this->designer_api_url;
elseif ( $type === 'transactional_api' )
$url = $this->transactional_api_url;
return $url . ( $query !== '' ? $query : '' );
}
/**
* Get API key.
*
* @return string
*/
public function get_api_key() {
return $this->x_api_key;
}
/**
* Check whether the current request is for the network administrative interface.
*
* @return bool
*/
public function is_network_admin() {
return $this->network_admin;
}
/**
* Check whether the plugin is active for the entire network.
*
* @return bool
*/
public function is_plugin_network_active() {
return $this->plugin_network_active;
}
/**
* Set network data.
*
* @return void
*/
private function set_network_data() {
// load plugin.php file
if ( ! function_exists( 'is_plugin_active_for_network' ) )
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
$cn_network = isset( $_POST['cn_network'] ) ? (int) $_POST['cn_network'] : false;
// bypass is_network_admin() to handle AJAX requests properly.
$this->network_admin = is_multisite() && ( is_network_admin() || ( wp_doing_ajax() && $cn_network === 1 ) );
// check whether the plugin is active for the entire network.
$this->plugin_network_active = is_plugin_active_for_network( COOKIE_NOTICE_BASENAME );
}
/**
* Include required files.
*
* @return void
*/
private function includes() {
include_once( COOKIE_NOTICE_PATH . 'includes/bot-detect.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/dashboard.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/frontend.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/functions.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/settings.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/welcome.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/welcome-api.php' );
include_once( COOKIE_NOTICE_PATH . 'includes/welcome-frontend.php' );
}
/**
* Load textdomain.
*
* @return void
*/
public function load_textdomain() {
load_plugin_textdomain( 'cookie-notice', false, dirname( COOKIE_NOTICE_BASENAME ) . '/languages/' );
}
/**
* Plugin activation.
*
* @global object $wpdb
*
* @param bool $network
* @return void
*/
public function activation( $network ) {
// network activation?
if ( is_multisite() && $network ) {
// add network options
add_site_option( 'cookie_notice_options', $this->defaults['general'] );
add_site_option( 'cookie_notice_status', $this->defaults['data'] );
add_site_option( 'cookie_notice_version', $this->defaults['version'] );
global $wpdb;
// get all available sites
$blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs );
foreach ( $blogs_ids as $blog_id ) {
// change to another site
switch_to_blog( (int) $blog_id );
// run current site activation process
$this->activate_site();
restore_current_blog();
}
} else
$this->activate_site();
}
/**
* Single site activation.
*
* @return void
*/
public function activate_site() {
// add default options
add_option( 'cookie_notice_options', $this->defaults['general'], '', false );
add_option( 'cookie_notice_status', $this->defaults['data'], '', false );
add_option( 'cookie_notice_version', $this->defaults['version'], '', false );
}
/**
* Plugin deactivation.
*
* @global object $wpdb
*
* @param bool $network
* @return void
*/
public function deactivation( $network ) {
// network deactivation?
if ( is_multisite() && $network ) {
$delete = $this->options['general']['global_override'] && $this->options['general']['deactivation_delete'];
// delete network options?
if ( $delete ) {
delete_site_option( 'cookie_notice_options' );
delete_site_option( 'cookie_notice_status' );
delete_site_option( 'cookie_notice_app_analytics' );
delete_site_option( 'cookie_notice_app_blocking' );
delete_site_option( 'cookie_notice_version' );
}
global $wpdb;
// get all available sites
$blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs );
foreach ( $blogs_ids as $blog_id ) {
// change to another site
switch_to_blog( (int) $blog_id );
// run current site deactivation process
$this->deactivate_site( $delete );
restore_current_blog();
}
} else
$this->deactivate_site();
}
/**
* Single site deactivation.
*
* @param bool $force_deletion
* @return void
*/
public function deactivate_site( $force_deletion = false ) {
// delete settings?
if ( $force_deletion || $this->options['general']['deactivation_delete'] ) {
// delete options
delete_option( 'cookie_notice_options' );
delete_option( 'cookie_notice_status' );
delete_option( 'cookie_notice_app_analytics' );
delete_option( 'cookie_notice_app_blocking' );
delete_option( 'cookie_notice_version' );
// delete transients if any
delete_transient( 'cookie_notice_app_token' );
delete_transient( 'cookie_notice_app_quick_config' );
delete_transient( 'cookie_notice_app_subscriptions' );
}
// remove wp super cache cookie
$this->wpsc_delete_cookie();
}
/**
* Update notice.
*
* @return void
*/
public function update_notice() {
if ( ! current_user_can( 'install_plugins' ) )
return;
// bail an ajax
if ( wp_doing_ajax() )
return;
$network = $this->is_network_admin();
$current_update = 9;
// get current database version
if ( $network )
$current_db_version = get_site_option( 'cookie_notice_version', '1.0.0' );
else
$current_db_version = get_option( 'cookie_notice_version', '1.0.0' );
$this->db_version = $current_db_version;
if ( version_compare( $current_db_version, $this->defaults['version'], '<' ) ) {
if ( $this->options['general']['update_version'] < $current_update ) {
// check version, if update version is lower than plugin version, set update notice to true
$this->options['general']['update_version'] = $current_update;
$this->options['general']['update_notice'] = true;
// update options
if ( $network ) {
$this->options['general']['update_notice_diss'] = false;
update_site_option( 'cookie_notice_options', $this->options['general'] );
} else
update_option( 'cookie_notice_options', $this->options['general'] );
}
// update plugin version
if ( $network )
update_site_option( 'cookie_notice_version', $this->defaults['version'] );
else
update_option( 'cookie_notice_version', $this->defaults['version'], false );
}
// check page
$page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
// if visiting settings, mark notice as read
if ( $page === 'cookie-notice' && ! empty( $_GET['welcome'] ) ) {
$this->options['general']['update_notice'] = false;
if ( $network ) {
$this->options['general']['update_notice_diss'] = true;
update_site_option( 'cookie_notice_options', $this->options['general'] );
} else
update_option( 'cookie_notice_options', $this->options['general'] );
}
if ( is_multisite() && ( ( $this->is_plugin_network_active() && ! $network && $this->network_options['global_override'] ) || ( $network && ! $this->is_plugin_network_active() ) ) )
$this->options['general']['update_notice'] = false;
// get cookie compliance status
$status = $this->get_status();
// show notice, if no compliance only
if ( $this->options['general']['update_notice'] === true && empty( $status ) ) {
$this->add_notice( '<div class="cn-notice-text"><h2>' . esc_html__( 'Facebook Tracking Pixel Illegal in EU?', 'cookie-notice' ) . '</h2><p>' . esc_html__( 'The Austrian Data Protection Authority recently declared that the use of Facebook\'s tracking pixel directly violates the GDPR. This decision could affect many websites in the European Union. To use Facebook Pixel, prior consent from visitors for tracking is required. Click "Run Compliance Check" to check if your website compliance with the latest privacy regulations.', 'cookie-notice' ) . '</p><p class="cn-notice-actions"><a href="' . esc_url( $network ? network_admin_url( 'admin.php?page=cookie-notice&welcome=1' ) : admin_url( 'admin.php?page=cookie-notice&welcome=1' ) ) . '" class="button button-primary cn-button">' . esc_html__( 'Run Compliance Check', 'cookie-notice' ) . '</a> <a href="#" class="button-link cn-notice-dismiss">' . esc_html__( 'Dismiss Notice', 'cookie-notice' ) . '</a></p></div>', 'error', 'div' );
}
// show threshold limit warning, compliance only
if ( $status === 'active' ) {
// get analytics data options
if ( $network )
$analytics = get_site_option( 'cookie_notice_app_analytics', [] );
else
$analytics = get_option( 'cookie_notice_app_analytics', [] );
if ( is_multisite() && ( ( $network && ! $this->is_plugin_network_active() && ! $this->network_options['global_override'] ) || ( ! $network && $this->is_plugin_network_active() && $this->network_options['global_override'] ) ) )
$allow_notice = false;
else
$allow_notice = true;
if ( ! empty( $analytics ) && $allow_notice ) {
// cycle usage data
$cycle_usage = [
'threshold' => ! empty( $analytics['cycleUsage']->threshold ) ? (int) $analytics['cycleUsage']->threshold : 0,
'visits' => ! empty( $analytics['cycleUsage']->visits ) ? (int) $analytics['cycleUsage']->visits : 0,
'end_date' => ! empty( $analytics['cycleUsage']->endDate ) ? date_create_from_format( '!Y-m-d', $analytics['cycleUsage']->endDate ) : date_create_from_format( 'Y-m-d H:i:s', current_time( 'mysql', true ) ),
'last_updated' => ! empty( $analytics['lastUpdated'] ) ? date_create_from_format( 'Y-m-d H:i:s', $analytics['lastUpdated'] ) : date_create_from_format( 'Y-m-d H:i:s', current_time( 'mysql', true ) )
];
// if threshold in use
if ( $cycle_usage['threshold'] ) {
// if threshold exceeded and there was no notice before
if ( $cycle_usage['visits'] >= $cycle_usage['threshold'] && $cycle_usage['last_updated']->getTimestamp() < $cycle_usage['end_date']->getTimestamp() && $this->options['general']['update_threshold_date'] < $cycle_usage['end_date']->getTimestamp() ) {
$date_format = get_option( 'date_format' );
$upgrade_link = $this->get_url( 'dashboard', '?app-id=' . $this->options['general']['app_id'] . '&open-modal=payment' );
$threshold = $cycle_usage['threshold'];
$cycle_date = date_i18n( $date_format, $cycle_usage['end_date']->getTimestamp() );
$this->add_notice( '<div class="cn-notice-text" data-delay="' . esc_attr( $cycle_usage['end_date']->getTimestamp() ) . '"><h2>' . esc_html__( 'Cookie Compliance Warning', 'cookie-notice') . '</h2><p>' . sprintf( __( 'Your website has reached the <b>%1$s visits usage limit for the Cookie Compliance Free Plan</b>. Compliance services such as Consent Record Storage, Autoblocking, and Consent Analytics have been deactivated until current usage cycle ends on %2$s.', 'cookie-notice' ), $threshold, $cycle_date ) . '<br>' . sprintf( __( 'To reactivate compliance services now, <a href="%s" target="_blank">upgrade your domain to a Pro plan.</a>', 'cookie-notice' ) . '</p></div>', $upgrade_link ), 'cn-threshold error is-dismissible', 'div' );
}
}
}
}
}
/**
* Add admin notice.
*
* @param string $html
* @param string $status
* @param string $container
* @return void
*/
private function add_notice( $html = '', $status = 'error', $container = '' ) {
$this->notices[] = [
'html' => $html,
'status' => $status,
'container' => ( ! empty( $container ) && in_array( $container, [ 'p', 'div' ] ) ? $container : '' )
];
add_action( 'admin_notices', [ $this, 'display_notice' ], 0 );
add_action( 'network_admin_notices', [ $this, 'display_notice' ], 0 );
}
/**
* Print admin notices.
*
* @return void
*/
public function display_notice() {
foreach( $this->notices as $notice ) {
echo '
<div id="cn-admin-notice" class="cn-notice notice notice-info ' . esc_attr( $notice['status'] ) . '">
' . ( ! empty( $notice['container'] ) ? '<' . esc_attr( $notice['container'] ) . ' class="cn-notice-container">' : '' ) . '
' . wp_kses_post( $notice['html'] ) . '
' . ( ! empty( $notice['container'] ) ? '</' . esc_attr( $notice['container'] ) . ' class="cn-notice-container">' : '' ) . '
</div>';
}
}
/**
* Dismiss admin notice.
*
* @return void
*/
public function ajax_dismiss_admin_notice() {
if ( ! current_user_can( 'install_plugins' ) )
return;
if ( wp_verify_nonce( $_POST['nonce'], 'cn_dismiss_notice' ) ) {
// get notice action
$notice_action = ! empty( $_POST['notice_action'] ) ? sanitize_key( $_POST['notice_action'] ) : 'dismiss';
$cn_network = isset( $_POST['cn_network'] ) ? (int) $_POST['cn_network'] : false;
// network?
$network = is_multisite() && $cn_network === 1;
switch ( $notice_action ) {
// threshold notice
case 'threshold':
// set delay period last cycle day
$delay = isset( $_POST['param'] ) ? (int) $_POST['param'] : 0;
$this->options['general']['update_threshold_date'] = $delay + DAY_IN_SECONDS;
// update options
if ( $network )
update_site_option( 'cookie_notice_options', $this->options['general'] );
else
update_option( 'cookie_notice_options', $this->options['general'] );
break;
// delay notice
case 'delay':
// set delay period to 1 week from now
$this->options['general']['update_delay_date'] = time() + 1209600;
// update options
if ( $network )
update_site_option( 'cookie_notice_options', $this->options['general'] );
else
update_option( 'cookie_notice_options', $this->options['general'] );
break;
// hide notice
case 'approve':
default:
$this->options['general']['update_notice'] = false;
$this->options['general']['update_delay_date'] = 0;
// update options
if ( $network ) {
$this->options['general']['update_notice_diss'] = true;
update_site_option( 'cookie_notice_options', $this->options['general'] );
} else
update_option( 'cookie_notice_options', $this->options['general'] );
}
}
exit;
}
/**
* Register shortcode.
*
* @return void
*/
public function register_shortcodes() {
add_shortcode( 'cookies_accepted', [ $this, 'cookies_accepted_shortcode' ] );
add_shortcode( 'cookies_revoke', [ $this, 'cookies_revoke_shortcode' ] );
add_shortcode( 'cookies_policy_link', [ $this, 'cookies_policy_link_shortcode' ] );
}
/**
* Register cookies accepted shortcode.
*
* @param array $args
* @param string $content
* @return string
*/
public function cookies_accepted_shortcode( $args, $content ) {
if ( $this->cookies_accepted() ) {
$scripts = html_entity_decode( trim( wp_kses( $content, $this->get_allowed_html() ) ) );
if ( ! empty( $scripts ) ) {
if ( preg_match_all( '/' . get_shortcode_regex() . '/', $content ) )
$scripts = do_shortcode( $scripts );
return $scripts;
}
}
return '';
}
/**
* Register cookies revoke shortcode.
*
* @param array $args
* @param string $content
* @return string
*/
public function cookies_revoke_shortcode( $args, $content ) {
// get options
$options = $this->options['general'];
// WPML >= 3.2
if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) )
$options['revoke_text'] = apply_filters( 'wpml_translate_single_string', $options['revoke_text'], 'Cookie Notice', 'Revoke button text' );
// WPML and Polylang compatibility
elseif ( function_exists( 'icl_t' ) )
$options['revoke_text'] = icl_t( 'Cookie Notice', 'Revoke button text', $options['revoke_text'] );
// defaults
$defaults = [
'title' => $options['revoke_text'],
'class' => $options['css_class']
];
// combine shortcode arguments
$args = shortcode_atts( $defaults, $args );
if ( Cookie_Notice()->get_status() === 'active' )
$shortcode = '<a href="#" class="cn-revoke-cookie cn-button-inline cn-revoke-inline' . esc_attr( $args['class'] !== '' ? ' ' . $args['class'] : '' ) . '" title="' . esc_attr( $args['title'] ) . '" data-hu-action="cookies-notice-revoke">' . esc_html( $args['title'] ) . '</a>';
else
$shortcode = '<a href="#" class="cn-revoke-cookie cn-button-inline cn-revoke-inline' . esc_attr( $args['class'] !== '' ? ' ' . $args['class'] : '' ) . '" title="' . esc_attr( $args['title'] ) . '">' . esc_html( $args['title'] ) . '</a>';
return $shortcode;
}
/**
* Register cookies policy link shortcode.
*
* @param array $args
* @param string $content
* @return string
*/
public function cookies_policy_link_shortcode( $args, $content ) {
// get options
$options = $this->options['general'];
// WPML >= 3.2
if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ) {
$options['see_more_opt']['text'] = apply_filters( 'wpml_translate_single_string', $options['see_more_opt']['text'], 'Cookie Notice', 'Privacy policy text' );
$options['see_more_opt']['link'] = apply_filters( 'wpml_translate_single_string', $options['see_more_opt']['link'], 'Cookie Notice', 'Custom link' );
// WPML and Polylang compatibility
} elseif ( function_exists( 'icl_t' ) ) {
$options['see_more_opt']['text'] = icl_t( 'Cookie Notice', 'Privacy policy text', $options['see_more_opt']['text'] );
$options['see_more_opt']['link'] = icl_t( 'Cookie Notice', 'Custom link', $options['see_more_opt']['link'] );
}
if ( $options['see_more_opt']['link_type'] === 'page' ) {
// multisite with global override?
if ( is_multisite() && $this->is_plugin_network_active() && $this->network_options['global_override'] ) {
// get main site id
$main_site_id = get_main_site_id();
// switch to main site
switch_to_blog( $main_site_id );
// update page id for current language if needed
if ( function_exists( 'icl_object_id' ) )
$options['see_more_opt']['id'] = icl_object_id( $options['see_more_opt']['id'], 'page', true );
// get main site privacy policy link
$permalink = get_permalink( $options['see_more_opt']['id'] );
// restore current site
restore_current_blog();
} else {
// update page id for current language if needed
if ( function_exists( 'icl_object_id' ) )
$options['see_more_opt']['id'] = icl_object_id( $options['see_more_opt']['id'], 'page', true );
// get privacy policy link
$permalink = get_permalink( $options['see_more_opt']['id'] );
}
}
// defaults
$defaults = [
'title' => $options['see_more_opt']['text'] !== '' ? $options['see_more_opt']['text'] : '&#x279c;',
'link' => $options['see_more_opt']['link_type'] === 'custom' ? $options['see_more_opt']['link'] : $permalink,
'class' => $options['css_class']
];
// combine shortcode arguments
$args = shortcode_atts( $defaults, $args );
$shortcode = '<a href="' . esc_url( $args['link'] ) . '" target="' . esc_attr( $options['link_target'] ) . '" id="cn-more-info" class="cn-privacy-policy-link cn-link' . esc_attr( $args['class'] !== '' ? ' ' . $args['class'] : '' ) . '">' . esc_html( $args['title'] ) . '</a>';
return $shortcode;
}
/**
* Check if cookies are accepted.
*
* @return bool
*/
public static function cookies_accepted() {
if ( Cookie_Notice()->get_status() === 'active' ) {
// get cookie
$cookies = isset( $_COOKIE['hu-consent'] ) ? json_decode( stripslashes( $_COOKIE['hu-consent'] ), true ) : [];
// valid cookie?
if ( json_last_error() === JSON_ERROR_NONE && ! empty( $cookies ) && is_array( $cookies ) && isset( $cookies['consent'] ) )
$result = (bool) $cookies['consent'];
else
$result = false;
} else
$result = isset( $_COOKIE['cookie_notice_accepted'] ) && $_COOKIE['cookie_notice_accepted'] === 'true';
return (bool) apply_filters( 'cn_is_cookie_accepted', $result );
}
/**
* Check if cookies are set.
*
* @return bool
*/
public static function cookies_set() {
if ( Cookie_Notice()->get_status() === 'active' )
$result = isset( $_COOKIE['hu-consent'] );
else
$result = isset( $_COOKIE['cookie_notice_accepted'] );
return (bool) apply_filters( 'cn_is_cookie_set', $result );
}
/**
* Add WP Super Cache cookie.
*
* @return void
*/
public function wpsc_add_cookie() {
if ( Cookie_Notice()->get_status() === 'active' )
do_action( 'wpsc_add_cookie', 'hu-consent' );
else
do_action( 'wpsc_add_cookie', 'cookie_notice_accepted' );
}
/**
* Delete WP Super Cache cookie.
*
* @return void
*/
public function wpsc_delete_cookie() {
if ( Cookie_Notice()->get_status() === 'active' )
do_action( 'wpsc_delete_cookie', 'hu-consent' );
else
do_action( 'wpsc_delete_cookie', 'cookie_notice_accepted' );
}
/**
* Enqueue admin scripts and styles.
*
* @param string $page
* @return void
*/
public function admin_enqueue_scripts( $page ) {
// plugins page?
if ( $page === 'plugins.php' ) {
add_thickbox();
wp_enqueue_script( 'cookie-notice-admin-plugins', COOKIE_NOTICE_URL . '/js/admin-plugins.js', [ 'jquery' ], $this->defaults['version'] );
wp_enqueue_style( 'cookie-notice-admin-plugins', COOKIE_NOTICE_URL . '/css/admin-plugins.css', [], $this->defaults['version'] );
// prepare script data
$script_data = [
'deactivate' => esc_html__( 'Cookie Notice & Compliance - Deactivation survey', 'cookie-notice' ),
'nonce' => wp_create_nonce( 'cn-deactivate-plugin' )
];
wp_add_inline_script( 'cookie-notice-admin-plugins', 'var cnArgsPlugins = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
}
// notice js and css
wp_enqueue_script( 'cookie-notice-admin-notice', COOKIE_NOTICE_URL . '/js/admin-notice.js', [ 'jquery' ], Cookie_Notice()->defaults['version'] );
// prepare script data
$script_data = [
'ajaxURL' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'cn_dismiss_notice' ),
'network' => $this->is_network_admin()
];
wp_add_inline_script( 'cookie-notice-admin-notice', 'var cnArgsNotice = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
wp_enqueue_style( 'cookie-notice-admin-notice', COOKIE_NOTICE_URL . '/css/admin-notice.css', [], Cookie_Notice()->defaults['version'] );
}
/**
* Set plugin links.
*
* @return void
*/
public function set_plugin_links() {
// filters
add_filter( 'plugin_action_links', [ $this, 'plugin_action_links' ], 10, 2 );
add_filter( 'network_admin_plugin_action_links', [ $this, 'plugin_action_links' ], 10, 2 );
}
/**
* Add links to settings page.
*
* @param array $links
* @param string $file
* @return array
*/
public function plugin_action_links( $links, $file ) {
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
return $links;
if ( $file === COOKIE_NOTICE_BASENAME ) {
if ( ! empty( $links['deactivate'] ) ) {
// link already contains class attribute?
if ( preg_match( '/<a.*?class=(\'|")(.*?)(\'|").*?>/is', $links['deactivate'], $result ) === 1 )
$links['deactivate'] = preg_replace( '/(<a.*?class=(?:\'|").*?)((?:\'|").*?>)/s', '$1 cn-deactivate-plugin-modal$2', $links['deactivate'] );
else
$links['deactivate'] = preg_replace( '/(<a.*?)>/s', '$1 class="cn-deactivate-plugin-modal">', $links['deactivate'] );
// link already contains href attribute?
if ( preg_match( '/<a.*?href=(\'|")(.*?)(\'|").*?>/is', $links['deactivate'], $result ) === 1 ) {
if ( ! empty( $result[2] ) )
$this->deactivaion_url = $result[2];
}
}
// skip settings link if plugin is activated from main site
if ( ! ( $this->is_network_admin() && ! $this->is_plugin_network_active() ) ) {
$url = $this->is_network_admin() ? network_admin_url( 'admin.php?page=cookie-notice' ) : admin_url( 'admin.php?page=cookie-notice' );
// put settings link at start
array_unshift( $links, sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Settings', 'cookie-notice' ) ) );
}
// get cookie compliance status
$status = $this->get_status();
if ( is_multisite() ) {
$check_status = empty( $status ) && ( ( $this->is_network_admin() && $this->is_plugin_network_active() && $this->network_options['global_override'] ) || ( ! $this->is_network_admin() && ( ( $this->is_plugin_network_active() && ! $this->network_options['global_override'] ) || ! $this->is_plugin_network_active() ) ) );
} else
$check_status = empty( $status );
// add upgrade link
if ( $check_status ) {
$url = $this->is_network_admin() ? network_admin_url( 'admin.php?page=cookie-notice&welcome=1' ) : admin_url( 'admin.php?page=cookie-notice&welcome=1' );
$links[] = sprintf( '<a href="%s" style="color: #20C19E; font-weight: bold">%s</a>', esc_url( $url ), esc_html__( 'Free Upgrade', 'cookie-notice' ) );
}
}
return $links;
}
/**
* Deactivation modal HTML template.
*
* @global string $pagenow
*
* @return void
*/
public function deactivate_plugin_template() {
global $pagenow;
// display only for plugins page
if ( $pagenow !== 'plugins.php' )
return;
echo '
<div id="cn-deactivation-modal" style="display: none">
<div id="cn-deactivation-container">
<div id="cn-deactivation-body">
<div class="cn-deactivation-options">
<p><em>' . esc_html__( "We're sorry to see you go. Could you please tell us what happened?", 'cookie-notice' ) . '</em></p>
<ul>';
foreach ( [
'1' => esc_html__( "I couldn't figure out how to make it work.", 'cookie-notice' ),
'2' => esc_html__( 'I found another plugin to use for the same task.', 'cookie-notice' ),
'3' => esc_html__( 'The Cookie Compliance banner is too big.', 'cookie-notice' ),
'4' => esc_html__( 'The Cookie Compliance consent choices (Silver, Gold, Platinum) are confusing.', 'cookie-notice' ),
'5' => esc_html__( 'The Cookie Compliance default settings are too strict.', 'cookie-notice' ),
'6' => esc_html__( 'The web application user interface is not clear to me.', 'cookie-notice' ),
'7' => esc_html__( "Support isn't timely.", 'cookie-notice' ),
'8' => esc_html__( 'Other', 'cookie-notice' )
] as $option => $text ) {
echo '
<li><label><input type="radio" name="cn_deactivation_option" value="' . esc_attr( $option ) . '" ' . checked( '8', $option, false ) . ' />' . esc_html( $text ) . '</label></li>';
}
echo '
</ul>
</div>
<div class="cn-deactivation-textarea">
<textarea name="cn_deactivation_other"></textarea>
</div>
</div>
<div id="cn-deactivation-footer">
<a href="" class="button cn-deactivate-plugin-cancel">' . esc_html__( 'Cancel', 'cookie-notice' ) . '</a>
<a href="' . esc_url( $this->deactivaion_url ) . '" class="button button-secondary cn-deactivate-plugin-simple">' . esc_html__( 'Deactivate', 'cookie-notice' ) . '</a>
<a href="' . esc_url( $this->deactivaion_url ) . '" class="button button-primary right cn-deactivate-plugin-data">' . esc_html__( 'Deactivate & Submit', 'cookie-notice' ) . '</a>
<span class="spinner"></span>
</div>
</div>
</div>';
}
/**
* Send data about deactivation of the plugin.
*
* @return void
*/
public function deactivate_plugin() {
// check permissions
if ( ! current_user_can( 'install_plugins' ) || wp_verify_nonce( $_POST['nonce'], 'cn-deactivate-plugin' ) === false )
return;
if ( isset( $_POST['option_id'] ) ) {
$option_id = (int) $_POST['option_id'];
// avoid fake submissions
if ( $option_id === 8 ) {
$other = isset( $_POST['other'] ) ? sanitize_textarea_field( $_POST['other'] ) : '';
// no reason?
if ( $other === '' )
wp_send_json_success();
}
wp_remote_post(
'https://hu-manity.co/wp-json/api/v1/forms/',
[
'timeout' => 15,
'blocking' => true,
'headers' => [],
'body' => [
'id' => 1,
'option' => $option_id,
'other' => $other,
'referrer' => get_site_url()
]
]
);
wp_send_json_success();
}
wp_send_json_error();
}
/**
* Get allowed script blocking HTML.
*
* @return array
*/
public function get_allowed_html() {
return apply_filters(
'cn_refuse_code_allowed_html',
array_merge(
wp_kses_allowed_html( 'post' ),
[
'script' => [
'type' => true,
'src' => true,
'charset' => true,
'async' => true
],
'noscript' => [],
'style' => [
'type' => true
],
'iframe' => [
'src' => true,
'height' => true,
'width' => true,
'frameborder' => true,
'allowfullscreen' => true
]
]
)
);
}
/**
* Merge multidimensional associative arrays.
* Works only with strings, integers and arrays as keys. Values can be any type but they have to have same type to be kept in the final array.
* Every array should have the same type of elements. Only keys from $defaults array will be kept in the final array unless $siblings are not empty.
* $siblings examples: array( '=>', 'only_first_level', 'first_level=>second_level', 'first_key=>next_key=>sibling' ) and so on.
* Single '=>' means that all siblings of the highest level will be kept in the final array.
*
* @param array $defaults Array with defaults values
* @param array $array Array to merge
* @param bool|array $siblings Whether to allow "string" siblings to copy from $array if they do not exist in $defaults, false otherwise
* @return array
*/
public function multi_array_merge( $defaults, $array, $siblings = false ) {
// make a copy for better performance and to prevent $default override in foreach
$copy = $defaults;
// prepare siblings for recursive deeper level
$new_siblings = [];
// allow siblings?
if ( ! empty( $siblings ) && is_array( $siblings ) ) {
foreach ( $siblings as $sibling ) {
// highest level siblings
if ( $sibling === '=>' ) {
// copy all non-existent string siblings
foreach( $array as $key => $value ) {
if ( is_string( $key ) && ! array_key_exists( $key, $defaults ) ) {
$defaults[$key] = null;
}
}
// sublevel siblings
} else {
// explode siblings
$ex = explode( '=>', $sibling );
// copy all non-existent siblings
foreach ( array_keys( $array[$ex[0]] ) as $key ) {
if ( ! array_key_exists( $key, $defaults[$ex[0]] ) )
$defaults[$ex[0]][$key] = null;
}
// more than one sibling child?
if ( count( $ex ) > 1 )
$new_siblings[$ex[0]] = [ substr_replace( $sibling, '', 0, strlen( $ex[0] . '=>' ) ) ];
// no more sibling children
else
$new_siblings[$ex[0]] = false;
}
}
}
// loop through first array
foreach ( $defaults as $key => $value ) {
// integer key?
if ( is_int( $key ) ) {
$copy = array_unique( array_merge( $defaults, $array ), SORT_REGULAR );
break;
// string key?
} elseif ( is_string( $key ) && isset( $array[$key] ) ) {
// string, boolean, integer or null values?
if ( ( is_string( $value ) && is_string( $array[$key] ) ) || ( is_bool( $value ) && is_bool( $array[$key] ) ) || ( is_int( $value ) && is_int( $array[$key] ) ) || is_null( $value ) )
$copy[$key] = $array[$key];
// arrays
elseif ( is_array( $value ) && isset( $array[$key] ) && is_array( $array[$key] ) ) {
if ( empty( $value ) )
$copy[$key] = $array[$key];
else
$copy[$key] = $this->multi_array_merge( $defaults[$key], $array[$key], ( isset( $new_siblings[$key] ) ? $new_siblings[$key] : false ) );
}
}
}
return $copy;
}
/**
* Indicate if current page is the Cookie Policy page.
*
* @return bool
*/
public function is_cookie_policy_page() {
// get privacy policy options
$see_more = $this->options['general']['see_more_opt'];
// custom link?
if ( $see_more['link_type'] !== 'page' )
return false;
// get current object
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
// check if current page is privacy policy page
return $current_page->post_name === get_post_field( 'post_name', $see_more['id'] );
}
}
/**
* Initialize Cookie Notice.
*
* @return object
*/
function Cookie_Notice() {
static $instance;
// first call to instance() initializes the plugin
if ( $instance === null || ! ( $instance instanceof Cookie_Notice ) )
$instance = Cookie_Notice::instance();
return $instance;
}
Cookie_Notice();
\ No newline at end of file
.cn-dashboard-container {
min-height: 130px;
margin: 0 -4px;
text-align: center;
position: relative;
display: flex;
flex-direction: column;
}
.cn-dashboard-container .spinner {
position: absolute;
left: 50%;
top: 40%;
margin-left: -10px;
z-index: 10;
}
.cn-dashboard-container.loading {
pointer-events: none;
}
.cn-dashboard-container.loading:after {
position: absolute;
content: '';
display: block;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-color: rgba(255,255,255,0.8);
z-index: 1;
transition: all 0.2s;
}
.cn-dashboard_stats p.sub {
color: #8f8f8f;
font-size: 14px;
text-align: left;
padding-bottom: 3px;
border-bottom: 1px solid #ececec;
}
.cn-table-responsive {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.cn-table {
caption-side: bottom;
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
color: inherit;
vertical-align: top;
border-color: #dee2e6;
text-align: left;
}
.cn-table > thead {
vertical-align: bottom;
color: #212529;
}
.cn-table > tbody {
vertical-align: inherit;
}
.cn-table tbody,
.cn-table td,
.cn-table tfoot,
.cn-table th,
.cn-table thead,
.cn-table tr {
border-color: inherit;
border-style: solid;
border-width: 0;
}
.cn-table th,
.cn-table td {
text-align: inherit;
text-align: -webkit-match-parent;
}
.cn-table th:first-child,
.cn-table td:first-child {
width: 1px;
white-space: nowrap;
}
.cn-table th:last-child,
.cn-table td:last-child {
text-align: right;
}
.cn-table .no-posts :last-child {
text-align: left;
}
.cn-table > :not(caption) > * > * {
padding: .5rem .5rem;
background-color: transparent;
border-bottom-width: 1px;
box-shadow: inset 0 0 0 9999px transparent;
}
#cn_dashboard_stats .inside {
margin: 0;
padding: 0;
}
.cn-accordion-toggle {
cursor: pointer;
line-height: 1;
position: relative;
font-size: 14px;
font-weight: 400;
line-height: 1;
margin: 0;
padding: 15px 15px 0;
color: #23282c;
}
.cn-accordion-title {
display: inline-block;
padding-right: 10px;
}
.cn-accordion-actions {
position: absolute;
top: 0;
right: 0;
z-index: 1;
padding: 11px 30px 11px 0;
height: 14px;
line-height: 1;
}
.cn-accordion-actions .cn-accordion-action,
.cn-accordion-actions .cn-accordion-action::before {
font-size: 14px;
height: 14px;
width: 14px;
color: #72777c;
}
.cn-tooltip {
position: relative;
}
.cn-tooltip-icon {
display: inline-block;
width: 16px;
cursor: help;
}
.cn-tooltip-icon::before {
color: #b4b9be;
content: "\f14c";
display: inline-block;
font: normal 16px/1 dashicons;
position: absolute;
text-decoration: none !important;
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
left: 0;
top: 2px;
}
.cn-according-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.cn-accordion-content {
padding: 20px 20px 15px;
height: 100%;
}
.cn-collapsed .cn-accordion-toggle::before {
transform: rotate(180deg);
}
.cn-collapsed .cn-accordion-content {
display: none;
}
.cn-infobox-container {
display: flex;
flex-wrap: wrap;
border: 1px solid #eee;
}
.cn-infobox-container:not(:first-child) {
border-top-color: transparent;
}
.cn-infobox {
width: 50%;
padding: 12px 10px 10px 15px;
position: relative;
text-align: left;
box-sizing: border-box;
border-left: 1px solid transparent;
min-height: 135px;
}
#cn-visits-infobox-consents {
border-left-color: #eee;
}
#cn-visits-infobox-limits,
#cn-visits-chart-limits {
border-top-color: #eee;
}
.cn-infobox-notice {
width: 100%;
margin: 5px 10px 15px 15px;
padding: 15px 12px;
position: relative;
text-align: left;
box-sizing: border-box;
background: rgba(255, 193, 7, 0.05);
border: 1px solid rgb(255, 193, 7);
}
.cn-infobox-notice p {
margin-top: 0;
}
.cn-infobox-notice p:last-child {
margin-bottom: 0;
}
.cn-infobox-notice p b {
font-size: 15px;
color: #222;
}
.cn-infobox-title {
font-size: 16px;
color: #393f4c;
font-weight: 700;
margin-top: 0;
padding-right: 18px;
text-overflow: ellipsis;
overflow: hidden;
white-space: pre;
line-height: 1.2;
}
.cn-infobox-number {
font-size: 36px;
float: none;
font-weight: 400;
display: inline-block;
line-height: 1;
margin-top: 11px;
color: rgb(32, 193, 158);
}
.cn-infobox-subtitle {
margin-top: 22px;
color: #a4a9ae;
}
.cn-infobox-subtitle p {
margin: 0 0 5px;
}
.cn-infobox-tooltip {
position: absolute;
top: 12px;
right: 15px;
}
.cn-widget-block {
position: relative;
overflow: hidden;
}
#cn-dashboard-upgrade {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow: hidden;
box-sizing: border-box;
background: rgba(255,255,255,0.8);
min-height: 400px;
}
#cn-dashboard-modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 1.5em 3em;
box-shadow: 0 0 25px 10px rgba(0,0,0,0.1);
border-radius: 3px;
background-color: #fff;
text-align: center;
width: 22em;
}
#cn-dashboard-modal p {
margin: 0;
}
#cn-dashboard-modal h2 {
margin-bottom: 10px;
font-size: 21px;
}
.button.cn-button {
margin-top: 25px;
margin-bottom: 10px;
background-color: #20c19e;
border-color: #20c19e;
}
.button.cn-button:hover,
.button.cn-button:active,
.button.cn-button:focus {
background-color: #1ca98a;
border-color: #1ca98a;
}
.button.cn-button:focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px #20c19e;
}
.cn-text-succcess {
color: #20c19e;
}
.cn-text-warning {
color: rgb(255, 193, 7);
}
.cn-text-danger {
color: rgb(200, 35, 51);
}
\ No newline at end of file
#cn-admin-notice.cn-notice {
border-left-color: #20c19e;
}
.cn-notice .cn-notice-container {
padding: 1em;
display: flex;
justify-content: space-between;
align-items: center;
}
.cn-notice .cn-notice-actions {
margin-bottom: 0;
}
.cn-notice .cn-notice-actions .button {
display: inline-block;
margin: 0.5em 0 0;
}
.cn-notice .cn-notice-text h2 {
margin-top: 0;
margin-bottom: 0.5em;
}
.cn-notice .cn-notice-dismiss {
margin-left: 1em;
}
.cn-notice .cn-notice-text strong {
color: #000;
}
.cn-notice .cn-notice-text p:last-child {
margin-bottom: 0;
}
.cn-notice .cn-notice-icon svg path {
fill: #666 !important;
}
@media only screen and (max-width: 960px) {
.cn-notice .cn-notice-container {
flex-direction: column;
align-items: initial;
}
.cn-notice .cn-notice-container .cn-notice-text {
order: 1;
padding-top: 1em;
}
}
\ No newline at end of file
.cn-deactivation-modal {
max-height: 500px;
overflow: hidden;
top: 50% !important;
transform: translateY(-50%);
}
.cn-deactivation-modal #TB_title {
padding: 13px 16px;
background: #f3f3f3;
}
.cn-deactivation-modal #TB_title > div {
padding: 0;
color: #000;
}
.cn-deactivation-modal #TB_ajaxContent {
width: auto !important;
height: calc(100% - 112px) !important;
padding: 0;
}
.cn-deactivation-modal #TB_closeAjaxWindow button {
right: 8px;
}
.cn-deactivation-options p:first-child {
margin-top: 0;
}
#cn-deactivation-container {
width: 100%;
}
#cn-deactivation-container textarea {
width: 100%;
min-height: 100px;
}
#cn-deactivation-body {
padding: 13px 16px;
}
#cn-deactivation-footer {
padding: 13px 16px;
position: absolute;
right: 0;
bottom: 0;
left: 0;
border-top: 1px solid #ddd;
background: #f3f3f3;
}
#cn-deactivation-footer .spinner {
float: none;
}
\ No newline at end of file
.cn-welcome-wrap #wpcontent {
padding-left: 0;
}
.cn-welcome-wrap .update-nag {
display: none;
}
.cn-welcome-wrap * {
box-sizing: border-box;
}
.cn-welcome-wrap #wpbody-content {
padding-bottom: 0;
}
.cn-welcome-wrap #wpfooter {
display: none !important;
}
#cn_upgrade_iframe iframe {
width: 100%;
height: 100%;
margin: 0;
border: 0;
padding: 0;
}
.cn-welcome-wrap {
display: flex;
height: calc(100vh - 32px);
margin: 0;
background: #fff;
color: #191e23;
/*
position: fixed;
width: calc(100% - 160px);
*/
width: 100%;
}
.folded .cn-welcome-wrap {
width: calc(100% - 36px);
}
.cn-welcome-wrap h1,
.cn-welcome-wrap h2,
.cn-welcome-wrap h3,
.cn-welcome-wrap h4,
.cn-welcome-wrap h5 {
margin-top: 0;
}
.cn-content h1,
.cn-content h2,
.cn-content h3,
.cn-content h4,
.cn-content h5 {
color: #191e23;
padding: 0;
}
.cn-content h1,
.cn-content h2,
.cn-content h3,
.cn-content h4,
.cn-content h5 {
color: #191e23;
padding: 0;
}
.cn-sidebar h1,
.cn-sidebar h2,
.cn-sidebar h3,
.cn-sidebar h4,
.cn-sidebar h5 {
color: #fff;
}
.cn-content h1 + h2,
.cn-content h1 + h3 {
margin-top: 0.5em;
}
.cn-welcome-wrap h1 {
font-size: 4em;
line-height: 1.1;
}
.cn-welcome-wrap h2 {
font-size: 2em;
line-height: 1.1;
}
.cn-welcome-wrap h4 {
font-size: 1.5em;
}
.cn-welcome-wrap h5 {
font-size: 1.35em;
}
.cn-welcome-wrap a,
.cn-welcome-wrap .cn-btn {
transition: all 0.2s;
}
.cn-welcome-step-1 h3:first-child {
margin-bottom: 0;
}
.cn-welcome-step-1 .cn-content .cn-lead {
margin-top: 1.5em;
max-width: 100%;
}
.cn-welcome-step-1 .cn-content .cn-lead p:first-child {
margin-bottom: 1em;
}
.cn-welcome-step-1 .cn-content h1 {
margin-bottom: 5px;
}
.cn-welcome-step-1 .cn-content h2 {
margin-bottom: 1em;
}
.cn-welcome-step-1 .cn-content h4 {
margin-top: 1.5em;
}
.cn-welcome-step-1 .cn-sidebar .cn-lead {
margin-bottom: 1em;
}
.cn-welcome-step-1 .cn-sidebar .cn-inner,
.cn-welcome-step-1 .cn-content .cn-inner {
padding: 6em;
}
.cn-welcome-wrap.cn-welcome-step-1 .cn-sidebar {
width: 50%;
}
.cn-welcome-wrap.cn-welcome-step-1 .cn-content.cn-sidebar-visible {
width: 50%;
}
.cn-welcome-wrap .cn-content a.cn-link {
color: #20C19E;
text-decoration: none;
font-style: normal;
outline: none;
box-shadow: none;
}
.cn-welcome-wrap .cn-sidebar {
width: 25%;
min-height: 100%;
background: #35353F;
/*
background: rgba(7,137,145,0.7);
background: linear-gradient(145deg, rgba(7,137,145,.7), rgba(32,193,158,.7));
*/
/*
display: flex;
justify-content: center;
align-items: center;
*/
position: relative;
text-align: left;
overflow-y: scroll;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.cn-welcome-wrap .cn-content {
width: 100%;
min-height: 100%;
background-size: cover;
position: relative;
/*
display: flex;
justify-content: space-between;
align-items: center;
*/
text-align: center;
overflow-y: scroll;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.cn-welcome-wrap .cn-content::-webkit-scrollbar,
.cn-welcome-wrap .cn-sidebar::-webkit-scrollbar {
width: 0;
height: 0;
}
.cn-welcome-wrap .cn-hero-image {
display: flex;
justify-content: center;
align-items: flex-start;
max-width: 70%;
margin: 2em auto;
}
.cn-welcome-wrap .cn-hero-image img {
align-self: center;
max-width: 600px;
}
.cn-welcome-wrap .cn-hero-image .cn-flex-item img {
max-width: 400px;
}
.cn-welcome-wrap .cn-flex-item {
flex-grow: 1;
flex-basis: 0;
}
.cn-welcome-wrap .cn-flex-item:first-child,
.cn-welcome-wrap .cn-flex-item:last-child {
flex-grow: 4;
}
.cn-welcome-wrap .cn-flex-item:nth-child(2) img {
margin-top: 130px;
}
.cn-welcome-wrap .cn-flex-item ul {
padding: 0;
margin: 0;
list-style: none;
font-size: 15px;
}
.cn-welcome-wrap .cn-flex-item ul li {
padding: 0;
font-size: 15px;
line-height: 1.1;
margin: 1em 0;
}
.cn-welcome-wrap .cn-flex-item ul li span {
display: inline-block;
position: relative;
padding-left: 20px;
}
.cn-welcome-wrap .cn-flex-item ul li span::before {
font-family: 'dashicons';
line-height: 1;
font-weight: 400;
font-style: normal;
text-transform: none;
text-rendering: auto;
font-size: 16px;
text-align: center;
display: block;
content: "\f15e";
position: absolute;
top: 2px;
left: 0;
line-height: 1;
width: 16px;
height: 16px;
margin: 0;
color: #20C19E;
background: none;
}
.cn-welcome-wrap .cn-flex-item ul li b {
font-weight: bold;
font-size: 16px;
}
.cn-welcome-wrap .cn-logo-container {
margin-bottom: 1em;
}
.cn-welcome-wrap .cn-logo-container > * {
vertical-align: middle;
margin-bottom: 0.5em;
}
.cn-welcome-wrap .cn-logo-container img {
display: inline-block;
}
.cn-welcome-wrap .cn-badge {
background: #ccc;
color: #191e23;
border-radius: 3px;
text-transform: uppercase;
line-height: 1;
display: inline-block;
padding: 5px;
margin-left: 5px;
margin-right: 5px;
}
.cn-welcome-wrap .cn-pricing-type .cn-badge {
font-size: 14px;
font-weight: bold;
color: #fff;
background: #20c19e;
padding: 2.5px 7.5px;
}
.cn-welcome-wrap .cn-pricing-type div:first-child {
border-right: 1px solid #ccc;
}
.cn-welcome-wrap.cn-welcome-step-2 .cn-content {
background-size: cover;
}
.cn-welcome-wrap.cn-welcome-step-3 .cn-content {
background-size: cover;
}
.cn-welcome-wrap.cn-welcome-step-4 .cn-content {
background-size: cover;
}
.cn-welcome-wrap .cn-content.cn-sidebar-visible {
width: 75%;
}
.cn-welcome-wrap .cn-content-header {
text-align: center;
margin-bottom: 2em;
line-height: 1em;
display: flex;
flex-direction: row;
}
.cn-welcome-wrap .cn-content-header:before,
.cn-welcome-wrap .cn-content-header:after {
content:'';
flex: 1 1;
margin: auto;
border-bottom: 1px solid rgba(255,255,255,.7);
}
.cn-welcome-wrap .cn-content-header:before {
margin-right: 1em;
}
.cn-welcome-wrap .cn-content-header:after {
margin-left: 1em;
}
.cn-welcome-wrap .cn-inner {
position: relative;
z-index: 1;
padding: 4em;
min-height: 100%;
width: 100%;
display: flex;
justify-content: space-between;
}
.cn-sidebar .cn-inner {
flex-direction: column;
justify-content: space-between;
padding-bottom: 2em;
}
.cn-content .cn-inner {
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.cn-content .cn-lead {
margin: 0 auto;
max-width: 75%;
}
.cn-content .cn-lead p {
font-size: 1.3em;
margin: 0.5em 0;
}
.cn-content .cn-lead p:last-child {
margin-bottom: 0;
}
.cn-content .cn-content-full {
width: 100%;
}
.cn-sidebar {
color: #BBBBC0;
}
.cn-sidebar a,
.cn-sidebar em {
color: #20C19E;
text-decoration: none;
font-style: normal;
outline: none;
box-shadow: none;
}
.cn-sidebar a:hover {
text-decoration: underline;
}
.cn-sidebar .cn-lead {
margin-bottom: 2em;
}
.cn-sidebar .cn-lead b {
color: #fff;
font-weight: bold;
font-size: 15px;
}
.cn-sidebar .cn-lead p:last-child {
margin-bottom: 0;
}
.cn-sidebar .cn-buttons,
.cn-content .cn-buttons {
margin-top: 3em;
}
.cn-welcome-step-3 .cn-content .cn-buttons {
margin-top: 0;
}
.cn-header {
margin-bottom: 3em;
}
.cn-footer {
margin-top: 3em;
text-align: left;
}
.cn-footer .cn-btn.cn-skip-button {
color: #86868F;
font-weight: normal;
font-size: inherit;
text-decoration: none;
}
.cn-footer .cn-btn.cn-skip-button:hover {
color: #fff;
text-decoration: none;
}
.cn-footer a:hover {
color: #20C19E;
}
.cn-welcome-wrap .cn-pricing-type {
margin-top: 1em;
font-size: 1.2em;
display: flex;
justify-content: space-evenly;
align-items: baseline;
text-align: left;
}
.cn-welcome-wrap .cn-pricing-type > div {
flex: 1;
padding: 0 1em;
}
.cn-welcome-wrap .cn-pricing-type > div:nth-child(1) {
text-align: right;
}
.cn-welcome-wrap .cn-pricing-type label {
padding: 0;
margin: 0;
text-align: left;
position: relative;
display: inline-block;
}
.cn-welcome-wrap .cn-pricing-type label .cn-pricing-toggle {
margin-left: 1.5em;
}
.cn-welcome-wrap #cn-pricing-plans {
margin-top: 1em;
}
.cn-welcome-wrap .cn-pricing-select {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
.cn-welcome-wrap .cn-pricing-table {
display: flex;
justify-content: center;
align-items: center;
margin-top: 3em;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item {
margin: 0 1.5em 3em;
min-width: 300px;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item h4 {
margin-bottom: 0.5em;
position: relative;
font-size: 1.3em;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item h4:after {
content: '';
display: block;
width: 60px;
border-bottom: 1px solid #86868F;
margin: 1em auto 0;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item button {
pointer-events: none;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item:hover .cn-pricing-info {
border-color: rgba(0, 0, 0, 0.1);
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item .cn-pricing-info {
box-shadow: 0px 0px 13px 0px rgba(236, 236, 241, 1);
border: 1px solid transparent;
border-radius: 5px;
position: relative;
overflow: hidden;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item input {
display: none;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item input:checked + .cn-pricing-info {
border-color: #20C19E;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item .cn-pricing-info > div {
padding: 2em 1.5em;
}
.cn-welcome-wrap .cn-pricing-table input#cn-pricing-plan-free + .cn-pricing-info .cn-plan-price {
color: #515151;
font-size: 1.25em;
line-height: 1.5em;
}
.cn-welcome-wrap .cn-pricing-table input#cn-pricing-plan-pro + .cn-pricing-info {
background-color: rgba(32,193,158,0.05);
}
.cn-welcome-wrap .cn-pricing-table input#cn-pricing-plan-pro + .cn-pricing-info .cn-plan-promo {
color: #fff;
background: #ffc107;
position: absolute;
left: 50%;
top: 0;
font-weight: bold;
font-size: 13px;
line-height: 1.1em;
text-transform: uppercase;
display: inline-block;
letter-spacing: 1px;
border-radius: 0 0 5px 5px;
padding: 0.25em 2em;
transform: translateX(-50%);
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-item .cn-pricing-info .cn-pricing-head {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding: 3em 1.5em 2.5em;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-info div.cn-pricing-body {
padding-bottom: 0;
font-size: 14px;
text-align: left;
}
.cn-welcome-wrap .cn-pricing-table .cn-pricing-info div.cn-pricing-body p {
padding-left: 35px;
line-height: 1.5;
margin: 1em 0;
}
.cn-welcome-wrap .cn-pricing-table .cn-plan-pricing {
display: block;
font-size: 1.5em;
color: #515151;
}
.cn-welcome-wrap .cn-pricing-table .cn-plan-price {
font-size: 1.5em;
font-weight: bold;
line-height: 1.1;
color: #20C19E;
text-transform: uppercase;
}
.cn-welcome-wrap .cn-pricing-table .cn-plan-price sup {
font-weight: normal;
font-size: 0.5em;
color: #515151;
vertical-align: top;
}
.cn-welcome-wrap .cn-pricing-table .cn-plan-price sub {
font-weight: normal;
font-size: 0.5em;
color: #515151;
text-transform: none;
vertical-align: bottom;
}
.cn-welcome-wrap .cn-select-wrapper select {
background: #fff;
border: 1px solid #ccc;
color: #191e23;
border-radius: 25px;
padding: 7.5px 35px 7.5px 20px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 16px 12px;
}
.cn-welcome-wrap .cn-select-wrapper select:hover,
.cn-welcome-wrap .cn-select-wrapper select:focus {
color: inherit;
box-shadow: none;
}
.cn-welcome-wrap .cn-billing-wrapper {
font-weight: normal;
}
.cn-welcome-wrap .cn-billing-wrapper input {
display: none;
}
.cn-welcome-wrap .cn-billing-wrapper label {
position: relative;
display: inline-block;
padding: .5em 1em;
box-sizing: content-box;
}
.cn-welcome-wrap .cn-billing-wrapper input:checked + span {
color: #fff;
}
.cn-welcome-wrap .cn-billing-wrapper input:checked + span .cn-plan-overlay {
background-color: rgba(53,53,63,1);
}
.cn-welcome-wrap .cn-billing-wrapper .cn-plan-overlay {
border: none;
width: 100%;
height: 100%;
border-radius: 3px;
position: absolute;
left: 0;
top: 0;
transition: border-color 0.2s;
z-index: -1;
background-color: rgba(53,53,63,0.1);
}
.cn-welcome-wrap .cn-billing-wrapper :first-child > span .cn-plan-overlay {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.cn-welcome-wrap .cn-billing-wrapper :last-child > span .cn-plan-overlay {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.cn-btn {
border-radius: 3em;
padding: 1em 3em;
box-shadow: none;
border: 2px solid #20C19E;
outline: none;
background: #20C19E;
font-size: 15px;
font-weight: bold;
color: #fff;
cursor: pointer;
display: inline-block;
text-decoration: none;
}
.cn-btn:hover,
.cn-btn:focus {
box-shadow: none;
outline: none;
border: 2px solid #20C19E;
background: #20C19E;
color: #fff;
text-decoration: none !important;
}
.cn-btn.cn-btn-outline {
background: transparent;
color: #20C19E;
box-shadow: 0 0 15px 0 rgba(255,255,255,.4), inset 0 0 15px rgba(255,255,255,.4);
}
.cn-btn.cn-btn-outline:hover {
text-shadow: 0 0 10px rgba(255,255,255,.4), 0 0 20px rgba(255,255,255,.4), 0 0 30px rgba(255,255,255,.4), 0 0 40px rgba(255,255,255,.4);
}
.cn-btn.cn-btn-outline .cn-spinner::after {
border-color: #fff transparent #fff transparent;
}
.cn-btn.cn-btn-transparent,
.cn-btn.cn-btn-transparent:hover,
.cn-btn.cn-btn-transparent:focus {
box-shadow: none;
background: transparent;
color: #BBBBC0;
border-color: transparent;
}
.cn-btn.cn-btn-lg {
border-radius: 4em;
padding: 1.5em 4em;
font-size: 15px;
}
.cn-btn.cn-btn-link {
background: none;
border-color: transparent;
color: inherit;
padding: 0;
}
.cn-btn.cn-btn-secondary {
background-color:#ffc107;
border-color:#ffc107;
color:#3c434a
}
.cn-btn.cn-btn-secondary:active,
.cn-btn.cn-btn-secondary:focus,
.cn-btn.cn-btn-secondary:hover {
background-color:#ffca2c;
border-color:#ffca2c
}
.cn-top-bar {
display: flex;
justify-content: space-between;
align-items: center;
}
.cn-stepper {
padding: 1.5em;
margin: 1.5em -1.5em;
overflow-x: hidden;
overflow-y: auto;
display: flex;
justify-content: space-between;
}
.cn-stepper li {
position: relative;
display: flex;
flex: 1;
align-items: center;
transition: .2s;
margin: 0;
}
.cn-stepper li:not(:last-child):after {
position: relative;
flex: 1;
height: 1px;
margin: .35em 0 0 0;
content: '';
background-color: #86868F;
}
.cn-stepper li .cn-step {
cursor: default;
}
.cn-stepper li .cn-step .cn-circle {
display: inline-block;
width: 2em;
height: 2em;
line-height: 2em;
font-weight: bold;
color: #fff;
text-align: center;
background: #86868F;
border-radius: 50%;
}
.cn-stepper li.cn-completed .cn-step .cn-circle {
color: transparent;
background: #20C19E;
}
.cn-stepper li.cn-completed .cn-step .cn-circle:before{
font-family: dashicons;
line-height: 1;
font-weight: 400;
font-style: normal;
text-transform: none;
text-rendering: auto;
font-size: 14px;
text-align: center;
display: block;
content: "\f15e";
position: absolute;
top: 0;
left: -2px;
line-height: 2em;
width: 2em;
pointer-events: none;
transform: scale(1.25, 1.25);
color: #fff;
}
.cn-stepper li.cn-active .cn-step .cn-circle {
background: #20C19E;
}
.cn-features-list .cn-feature {
display: flex;
margin-bottom: 2em;
padding: 2em;
border: 1px solid rgba(255,255,255,0.1);
border-radius: 3px;
box-sizing: content-box;
background-color: rgba(255,255,255,0.1);
}
.cn-features-list .cn-feature:last-child {
margin-bottom: 0;
}
.cn-features-list .cn-feature img {
width: 48px;
height: 48px;
margin-right: 2em;
}
.cn-features-list .cn-feature h5 {
margin-bottom: 0.5em;
}
.cn-features-list .cn-feature-description p:last-child {
margin-bottom: 0;
}
.cn-form-container {
margin-left: -15px;
margin-right: -15px;
padding-left: 15px;
padding-right: 15px;
background: rgba(255,255,255,0.05);
padding-bottom: 1px;
}
.cn-form-header {
font-size: 15px;
font-style: normal;
font-weight: bold;
color: #fff;
width: 100%;
text-align: left;
margin: 0;
padding: 15px 0;
color: #fff;
}
.cn-small {
font-size: 12px;
}
.cn-form.cn-form-disabled[data-action="payment"] {
pointer-events: none;
opacity: 0.5;
}
.cn-form.cn-form-disabled .cn-accordion-collapse {
pointer-events: none;
}
.cn-welcome-wrap form {
position: relative;
margin: 0;
}
.cn-welcome-wrap form .cn-form-feedback {
position: relative;
margin-bottom: 1.5em;
color: #fff;
overflow-y: hidden;
max-height: 500px; /* approximate max height */
transition: all .3s cubic-bezier(0, 1, 0.5, 1);
transition-delay: 0.3s;
opacity: 1;
}
.cn-welcome-wrap form .cn-form-feedback p {
padding: 15px;
margin: 0;
}
.cn-welcome-wrap form .cn-form-feedback p.cn-error {
border: 1px solid #da2439;
border-radius: 3px;
background: rgba( 218,36,57, 0.5);
}
.cn-welcome-wrap form .cn-form-feedback p.cn-warning {
border: 1px solid #e78d26;
border-radius: 3px;
background: rgba( 231,141,38, 0.5);
}
.cn-welcome-wrap form .cn-form-feedback p.cn-message {
border: 1px solid #008000;
border-radius: 3px;
background: rgba( 0,128,0, 0.5);
}
.cn-welcome-wrap form .cn-form-feedback.cn-hidden {
max-height: 0;
margin-bottom: 0;
opacity: 0;
}
.cn-welcome-wrap form .cn-field:not(:last-child) {
position: relative;
margin: 0 0 0.5em;
}
.cn-welcome-wrap form .cn-field.cn-hidden {
display: none;
}
.cn-welcome-wrap form .cn-field.cn-field-half {
width: calc(50% - 0.5em);
display: inline-block;
margin: auto 0.25em;
}
.cn-welcome-wrap form .cn-field.cn-field-first {
margin-left: 0;
}
.cn-welcome-wrap form .cn-field.cn-field-last {
margin-right: 0;
}
.cn-welcome-wrap form label {
color: #fff;
margin: 0 0 0.5em;
display: block;
}
.cn-welcome-wrap form .cn-field > label {
color: #fff;
margin: 0 0 0.5em;
display: block;
font-weight: 700;
}
.cn-welcome-wrap form .cn-field.cn-field-submit {
margin: 1.5em 0 0 0;
}
.cn-welcome-wrap form input[type="text"],
.cn-welcome-wrap form input[type="password"],
.cn-welcome-wrap form input[type="checkbox"],
.cn-welcome-wrap form input[type="radio"],
.cn-welcome-wrap form select {
background: transparent;
border: 1px solid #86868F;
margin: 0;
padding: 0 15px;
color: #fff;
transition: border-color 0.2s;
}
.cn-welcome-wrap form select#cn-subscription-select option {
color: #35353f;
}
.cn-welcome-wrap form select#cn-subscription-select option:disabled {
background: #666;
}
.cn-welcome-wrap form input[type="checkbox"],
.cn-welcome-wrap form input[type="radio"] {
transition: none;
}
.cn-welcome-wrap form input[type="checkbox"] b,
.cn-welcome-wrap form input[type="radio"] b {
font-weight: 700;
}
.cn-welcome-wrap form input[type="text"],
.cn-welcome-wrap form input[type="password"],
.cn-welcome-wrap form select {
width: 100%;
line-height: 3;
}
.cn-welcome-wrap form .cn-select-wrapper {
position: relative;
margin: 0;
}
.cn-welcome-wrap form .cn-select-wrapper:after {
font-family: dashicons;
line-height: 1;
font-weight: 400;
font-style: normal;
text-transform: none;
text-rendering: auto;
font-size: 18px;
text-align: center;
display: block;
content: "\f347";
position: absolute;
top: 50%;
margin-top: -9px;
right: 15px;
line-height: 1;
pointer-events: none;
color: #fff;
}
.cn-welcome-wrap form .cn-checkbox-wrapper,
.cn-welcome-wrap form .cn-radio-wrapper {
position: relative;
}
.cn-welcome-wrap form .cn-checkbox-wrapper label,
.cn-welcome-wrap form .cn-radio-wrapper label {
color: #BBBBC0;
}
.cn-welcome-wrap form .cn-checkbox-wrapper.cn-horizontal-wrapper label,
.cn-welcome-wrap form .cn-radio-wrapper.cn-horizontal-wrapper label {
display: inline-block;
margin-right: 0.5em;
}
.cn-welcome-wrap form .cn-checkbox-wrapper.cn-horizontal-wrapper label:last-child,
.cn-welcome-wrap form .cn-radio-wrapper.cn-horizontal-wrapper label:last-child {
margin-right: 0;
}
.cn-welcome-wrap .cn-checkbox-wrapper input,
.cn-welcome-wrap .cn-radio-wrapper input {
position: absolute;
margin: 2px 0;
}
.cn-welcome-wrap .cn-checkbox-wrapper input:focus,
.cn-welcome-wrap .cn-radio-wrapper input:focus {
border-color: #86868F;
}
.cn-welcome-wrap .cn-checkbox-wrapper input:checked,
.cn-welcome-wrap .cn-radio-wrapper input:checked {
background: none;
border-color: #20C19E;
}
.cn-welcome-wrap .cn-checkbox-wrapper input:checked,
.cn-welcome-wrap .cn-radio-wrapper input:checked {
background: none;
border-color: #20C19E;
}
.cn-welcome-wrap .cn-checkbox-wrapper input:checked::before {
font-family: dashicons;
line-height: 1;
font-weight: 400;
font-style: normal;
text-transform: none;
text-rendering: auto;
font-size: 14px;
text-align: center;
display: block;
content: "\f15e";
position: absolute;
top: 0;
left: 0;
line-height: 1;
width: 16px;
height: 16px;
margin: 0 auto 0 -1px;
color: #fff;
background: none;
}
.cn-welcome-wrap form .cn-color-picker-wrapper input {
border: none;
}
.cn-welcome-wrap form .cn-color-picker-wrapper .sp-original-input-container {
margin-left: 0;
position: absolute;
border: 1px solid rgba(255,255,255,1);
border-radius: 0;
}
.cn-welcome-wrap form .cn-color-picker-wrapper .sp-colorize-container {
height: 16px;
}
.cn-welcome-wrap form .cn-color-picker-wrapper input:checked::before {
content: '';
}
.cn-welcome-wrap .cn-radio-wrapper label input:checked::before {
text-align: center;
display: block;
position: absolute;
top: 2px;
left: 2px;
line-height: 1;
width: 10px;
height: 10px;
margin: 0 auto;
color: #fff;
background: #20C19E;
}
.cn-welcome-wrap .cn-checkbox-wrapper label > span,
.cn-welcome-wrap .cn-radio-wrapper label > span {
margin-left: 2em;
display: block;
}
.cn-welcome-wrap .cn-field-checkbox > label.cn-asterix::after {
content: '*';
right: 0;
top: 0;
line-height: 8px;
padding-left: 3px;
display: inline-block;
}
.cn-welcome-wrap .cn-checkbox-wrapper label > span.cn-asterix::after,
.cn-welcome-wrap .cn-radio-wrapper label > span.cn-asterix::after {
content: '*';
right: 0;
top: 0;
line-height: 8px;
padding-left: 3px;
display: inline-block;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper label,
.cn-welcome-wrap form .cn-radio-image-wrapper label {
display: inline-block;
margin: 0 0.25em;
position: relative;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper label.cn-asterix,
.cn-welcome-wrap form .cn-radio-image-wrapper label.cn-asterix {
padding-right: 8px;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper label.cn-asterix::after,
.cn-welcome-wrap form .cn-radio-image-wrapper label.cn-asterix::after {
content: '*';
position: absolute;
right: 0;
top: 0;
line-height: 8px;
}
.cn-sidebar form .cn-checkbox-image-wrapper span,
.cn-sidebar form .cn-radio-image-wrapper span {
display: block;
text-align: center;
font-weight: 600;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper label:first-child,
.cn-welcome-wrap form .cn-radio-image-wrapper label:first-child {
margin-left: 0;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper label:last-child,
.cn-welcome-wrap form .cn-radio-image-wrapper label:last-child {
margin-right: 0;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper input,
.cn-welcome-wrap form .cn-radio-image-wrapper input {
display: none;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper input:checked + img,
.cn-welcome-wrap form .cn-radio-image-wrapper input:checked + img {
border-color: #20C19E;
}
.cn-welcome-wrap form .cn-checkbox-image-wrapper img,
.cn-welcome-wrap form .cn-radio-image-wrapper img {
display: inline-block;
padding: 0.5em;
border: 2px solid #86868F;
border-radius: 3px;
box-sizing: content-box;
}
.cn-checkbox-image-wrapper .gdpr {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC/ElEQVRoge2ZzZGjMBCFmcMet4rjHjlsANQmsGRgZ7BkMGRgZ7DOYMhgnME4A08GdgZ2AujbA41HiD8JEOawXUWVXUjd73WLVqsVBB4F+OlTv3cBciB7Ng4nAV6ADHjnSz6A7bOxPQQIh94Dd43AaSFodgKkFmNOGoHEYvwySw1IgJtFFHJgC6RD4GTJnedF2jQSAUfNqzfgMFFnAnxqOi9CvNc5UwzG1CWaQede03f1Bl6MhZqxz5l0Jot97BKBRH5nc3hLCETyO52qr1LqL4wjxWm5Akd/UMaJfOzdjpUs8xvYyXp8k//RcjA7Mf01MMVdE3IjyxyfvZyMLIVEIuoarGcZJhqOgY14bJITqO8VSd/AqobZy6T2UPUbi5RSH0op9EeW5igiguVAWZ50YxKvhRoZJ4MC/maCr56iKN5GEgi139EYHVailDpqYHMgKYpir5S6a5FIvQGYIuL9B3jjXapFYnUpOgiCIAC2mpcT872+lJ4Ab1hkqfQRuHslIB9wNHa+BYHrHAToOprKJuacJSgPLH+M1HmRtLkDdkqp95aU+tqb09tthcC5No/moeLcybKpMO5KmZbPydLON3HwzagSflQD9BIid/BI4gD2OpaA2DIbBan+8qC9sD5cOxD4FADZWAJir72kkAjE8sxN4FEGF0WRT4xAVtl1/X6sCQCZlpH6wDtHYHbpIFDVUskA+HUSUEqd9eKrB/xqCVQkNmb+X4SAy8fhmEYnEbDGJanKavDCBPoPWJSnsIvk2BvlAbr3RAaEssZPYx6blN2BK2obGFGX/bBf/EsLrm7SlL3J5k73ZMGmVS9MT5Qt8T0rulGhLHViyso3sZ20uvbif1kiKl5tuFSqI/WH+Gq78HUR4dytc7CRS86fLwo078YQQ5HFXKtLEOq3NMP53lVaNpPIcs4Fy0YB9S70LNdXpgGqjW5g3AvNlvgd+DUwb6vZmHT72aY8rtY+WgN4YI5+fh3cFPUNynqz8inUt//V7OpWAnwHNuZvH/IPPeDD9c6V9FUAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center center;
}
.cn-checkbox-image-wrapper .ccpa {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAwCAYAAACScGMWAAACPElEQVRYheXYvXHbMBTAcY7AEbSA79Smskp30QiqkyLaQPQE8Qb2BtEG4QZil3Ry5ZZaAO/vAqANIwSJD1LmXXD3ToVE8sf3hEcQRVEUBXADfE+Mu2LOAVSkj/q/xj0sGVcvEgeUGTAvDlgBP4CD+Vyl4HaZuNa9WRH5JSK4oZT6CZQxuN+ZOBzYqQ9mxSkYmAuzcUqpyoE0InIUkWcng1UoLresWFlrOwCwczLa2EAispczWzvcxs5YzzXWDm4bistpwk1RfCypr2yppc3BVUvDXYAtsO7OsSRcbY5bAbfArYicrYu36Ob7Fj297wx8Ncf7JwewScGJSD3S00LjOJa9p0/E1SHlDQWm4rqmHI+LAKbgGsx/y23IMbiQVUos7g2G04yjcOYEObga2InIxQNrc3FjK2MvDtP7DOQYAIvGlcBzYub+WRKNwOJw5oRDvW8Ih4icImDxOHNiX3nHcF0GDwGwZJyvvCG4aZuwB9i31lsMbu/DAXsD9IZS6kEpVQ0FoQvPHlxfaU/jR15peGbuGf3mlhqHKYF95c0dj1MCY5ZV1wUy/uT4dOB2BtykwDmyNw0QOM6EyweS9547L/AKOID7VNwcLcUdf1Jxa3T27MjaDOoZL0m4AXRJ3uZ3Pg69p9fy/pxssVYW6GdxbrvJwjXoUnZh40oTFXrT53q4EXiNtYltkCkTaDoc71v734B9z/ex7WdSXHfxzcBvYsbfKXHlECwAd0H/JZ7MjX6ZDBcy0DPYBmyHbugVe8KbbhsHbZ0AAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center center;
}
.cn-welcome-wrap form .cn-plan-wrapper {
margin-bottom: 1em;
}
.cn-welcome-wrap form .cn-plan-wrapper label > span {
margin-left: 2em;
}
.cn-welcome-wrap form .cn-plan-wrapper label {
position: relative;
display: block;
padding: 1.25em 1em;
box-sizing: content-box;
}
.cn-welcome-wrap form .cn-plan-overlay {
border: 1px solid #86868F;
width: 100%;
height: 100%;
border-radius: 3px;
position: absolute;
left: 0;
top: 0;
transition: border-color 0.2s;
z-index: 0;
background-color: rgba(32,193,158,0);
}
.cn-welcome-wrap form .cn-plan-wrapper .cn-disabled {
pointer-events: none;
opacity: 0.3;
}
.cn-welcome-wrap form .cn-plan-wrapper input:checked + span .cn-plan-overlay {
border-color: #20C19E;
background-color: rgba(32,193,158,.1);
}
.cn-welcome-wrap form .cn-plan-wrapper span .cn-plan-description {
font-weight: normal;
}
.cn-welcome-wrap form .cn-plan-wrapper span .cn-plan-description b {
font-weight: bold;
}
.cn-welcome-wrap form .cn-plan-wrapper input:checked + span {
color: #fff;
}
.cn-welcome-wrap form .cn-plan-name {
display: block;
font-size: 1.1em;
font-weight: bold;
color: #fff;
}
.cn-welcome-wrap form .cn-plan-pricing {
display: inline-block;
font-size: 1.1em;
float: right;
color: #ccc;
}
.cn-welcome-wrap form .cn-price-off {
font-weight: bold;
color: #20C19E;
}
.cn-welcome-wrap form .cn-plan-price {
font-weight: bold;
}
.cn-welcome-wrap form input::placeholder,
.cn-welcome-wrap form select::placeholder {
color: #86868F;
}
.cn-welcome-wrap form input:focus,
.cn-welcome-wrap form select:focus {
border-color: #20C19E;
box-shadow: none;
}
.cn-welcome-wrap form select:focus {
color: #fff;
}
.cn-welcome-wrap form select:hover {
color: #fff;
}
.cn-welcome-wrap .cn-nav {
margin-top: 3em;
}
.cn-welcome-wrap form .cn-nav {
margin-top: 2.5em;
}
.cn-welcome-wrap .cn-nav .cn-btn {
margin: 0 0.25em;
}
.cn-welcome-wrap .cn-nav .cn-btn:first-child {
margin-left: 0;
}
.cn-welcome-wrap .cn-nav .cn-btn:last-child {
margin-right: 0;
}
.cn-welcome-wrap #cn_preview_frame {
width: 100%;
height: 200px;
border: 1px solid #86868F;
margin-top: 2.5em;
box-shadow: 0 0 10px 0 rgba(0,0,0,.3);
position: relative;
overflow: hidden;
}
.cn-welcome-wrap #cn_preview_frame img {
width: 100%;
height: auto;
display: block;
filter: blur(3px) grayscale(100%);
}
.cn-welcome-wrap #cn_preview_frame_wrapper {
width: 400%;
height: 400%;
transform: scale(0.25) translate(-150%,-150%);
pointer-events: none;
}
.cn-welcome-wrap #cn_preview_frame_wrapper::after {
content: '';
display: block;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
position: absolute;
top: 0;
left: 0;
}
.cn-welcome-wrap #cn_preview_frame_wrapper iframe {
width: 100%;
height: 100%;
filter: grayscale(100%);
}
.cn-welcome-wrap #cn_preview_about {
margin-bottom: 1.5em;
}
.cn-welcome-wrap #cn_preview_about p {
margin: 0;
}
.cn-welcome-wrap #cn_preview_about p b {
color: #fff;
}
.cn-comparison {
width: 100%;
}
.cn-comparison tr:not(:last-child) {
box-shadow: 0px 1px 1px rgba(255,255,255,.5);
}
.cn-comparison th,
.cn-comparison td {
padding: 1em;
}
.cn-comparison th {
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.cn-spinner {
display: inline-block;
width: 14px;
height: 14px;
max-width: 0;
opacity: 0;
transition: opacity 0.2s, max-width 0.3s;
}
.cn-spinner.spin {
max-width: 14px;
opacity: 1;
margin-right: 10px;
}
.cn-spinner:after {
content: '';
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
border: 2px solid #fff;
border-color: #fff transparent #fff transparent;
animation: cn-spin 0.8s linear infinite;
}
@keyframes cn-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes cn-fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes cn-fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes cn-slideIn {
from {
transform: translate3d(0, -100%, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes slideOut {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(0, -100%, 0);
}
}
.cn-sidebar.cn-theme-light {
background: linear-gradient(-45deg, rgba(4,134,138,1), rgba(32,193,158,1));
color: #fff;
}
.cn-sidebar.cn-theme-light a,
.cn-sidebar.cn-theme-light em {
color: #fff;
text-decoration: underline;
}
.cn-sidebar.cn-theme-light a:hover,
.cn-sidebar.cn-theme-light em:hover {
text-decoration: none;
}
.cn-sidebar.cn-theme-light .cn-btn:not(.cn-skip-button) {
border-color: #fff;
background-color: #fff;
color: #191e23;
}
.cn-sidebar.cn-theme-light .cn-btn:not(.cn-skip-button) .cn-spinner::after {
border-color: #191e23 transparent #191e23 transparent;
}
.cn-sidebar.cn-theme-light .cn-btn.cn-skip-button {
color: rgba(255,255,255,0.5);
}
.cn-sidebar.cn-theme-light .cn-btn.cn-skip-button:hover {
color: rgba(255,255,255,1);
}
.cn-sidebar.cn-theme-light #cn_iframe_preview {
border-color: #fff;
box-shadow: 0 0 10px 0 rgba(255,255,255,.3);
}
.cn-sidebar.cn-theme-light form input[type="text"],
.cn-sidebar.cn-theme-light form input[type="password"],
.cn-sidebar.cn-theme-light form input[type="checkbox"],
.cn-sidebar.cn-theme-light form input[type="radio"],
.cn-sidebar.cn-theme-light form select {
border-color: #fff;
}
.cn-sidebar.cn-theme-light form .cn-checkbox-wrapper label,
.cn-sidebar.cn-theme-light form .cn-radio-wrapper label {
color: #fff;
}
.cn-sidebar.cn-theme-light .cn-checkbox-image-wrapper input:checked + img,
.cn-sidebar.cn-theme-light .cn-radio-image-wrapper input:checked + img {
border-color: #fff;
}
.cn-sidebar.cn-theme-light form .cn-checkbox-image-wrapper img,
.cn-sidebar.cn-theme-light form .cn-radio-image-wrapper img {
border-color: rgba(255,255,255,0.2);
}
.cn-sidebar.cn-theme-light form .cn-radio-wrapper label input:checked::before {
background-color: #fff;
}
.cn-sidebar.cn-theme-light form input::placeholder,
.cn-sidebar.cn-theme-light form select::placeholder {
color: rgba(255,255,255,0.7);
}
.cn-sidebar.cn-theme-light form input:focus,
.cn-sidebar.cn-theme-light form select:focus {
border-color: #fff;
}
.cn-sidebar.cn-theme-light form .cn-plan-overlay {
border-color: rgba(255,255,255,0.5);
}
.cn-sidebar.cn-theme-light form .cn-plan-wrapper input:checked + span .cn-plan-overlay {
border-color: rgba(255,255,255,1);
background-color: rgba(255,255,255,.2);
}
.cn-sidebar.cn-theme-light .cn-form-container {
background: rgba(0,0,0,0.1);
border: 1px solid rgba(255,255,255,.3);
transition: all 0.2s;
}
.cn-sidebar.cn-theme-light .cn-form-container.cn-collapsed {
border-color: rgba(255,255,255,0);
}
.cn-accordion .cn-accordion-item {
overflow: hidden;
border: 1px solid rgba(255,255,255,0.05);
transition: border-color 0.2s;
}
.cn-accordion .cn-accordion-item:focus {
border-color: #20C19E;
}
.cn-accordion .cn-accordion-item:not(:last-child) {
margin-bottom: 0.5em;
}
.cn-accordion .cn-accordion-item.cn-disabled {
pointer-events: none;
}
.cn-accordion .cn-accordion-item.cn-hidden {
visibility: hidden;
}
.cn-accordion .cn-accordion-item.cn-collapsed .cn-accordion-button {
color: rgba(255,255,255,.7);
}
.cn-accordion .cn-accordion-item.cn-collapsed .cn-accordion-button:hover {
color: #fff;
}
.cn-accordion .cn-accordion-button {
text-align: left;
font-size: 15px;
font-style: normal;
font-weight: bold;
color: #fff;
width: 100%;
position: relative;
border: none;
outline: none;
background: none;
padding: 0;
margin: 0;
cursor: pointer;
}
.cn-accordion .cn-accordion-button:hover {
color: #fff;
}
/*
.cn-accordion .cn-accordion-button:after {
font-family: dashicons;
line-height: 1;
font-weight: 400;
font-style: normal;
text-transform: none;
text-rendering: auto;
font-size: 18px;
text-align: center;
display: block;
content: "\f347";
position: absolute;
top: 50%;
margin-top: -9px;
right: 0;
line-height: 1;
pointer-events: none;
color: #fff;
transform: rotate(180deg);
transition: all 0.3s ease-in-out;
}
.cn-accordion .cn-collapsed .cn-accordion-button:after {
transform: rotate(0);
}*/
.cn-accordion .cn-accordion-collapse {
overflow-y: hidden;
max-height: 1000px; /* approximate max height */
transition-property: all;
transition-duration: .3s;
transition-timing-function: ease-in-out;
}
.cn-accordion .cn-accordion-collapse.cn-form {
margin-bottom: 1.5em;
}
.cn-accordion .cn-collapsed .cn-accordion-collapse {
max-height: 0;
margin-bottom: 0;
}
#cn_card_number, #cn_expiration_date, #cn_cvv {
background: transparent;
border: 1px solid #86868F;
border-radius: 3px;
margin: 0;
padding: 0 15px;
color: #fff;
transition: border-color 0.2s;
height: 3em;
box-shadow: none;
}
#cn_card_number.braintree-hosted-fields-focused, #cn_expiration_date.braintree-hosted-fields-focused, #cn_cvv.braintree-hosted-fields-focused {
border-color: #20C19E;
background-color: transparent;
box-shadow: none;
}
#cn_card_number.braintree-hosted-fields-invalid, #cn_expiration_date.braintree-hosted-fields-invalid, #cn_cvv.braintree-hosted-fields-invalid {
border-color: #DA2439;
background-color: transparent;
box-shadow: none;
}
#cn_card_number.braintree-hosted-fields-valid {
color: #fff;
}
/* Loader */
.cn-welcome-wrap .has-loader:before {
display: block;
content: '';
background: rgba(255,255,255,0);
transition: all 0.2s;
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
}
.cn-welcome-wrap .has-loader.cn-loading:before {
/* background: rgba(32,193,158,.2); */
background: rgba(255,255,255,.2);
z-index: 99;
}
.cn-welcome-wrap .has-loader > .cn-spinner {
position: absolute;
top: 50%;
left: 50%;
width: 21px;
height: 21px;
z-index: 100;
}
.cn-welcome-wrap .has-loader > .cn-spinner:after {
border: 3px solid #20C19E;
border-color: #20C19E transparent #20C19E transparent;
width: 21px;
height: 21px;
border-radius: 50%;
opacity: 0;
transition: all 0.3s;
}
.cn-welcome-wrap .has-loader.cn-loading > .cn-spinner {
max-width: 21px;
opacity: 1;
}
.cn-welcome-wrap .has-loader.cn-loading > .cn-spinner:after {
opacity: 1;
}
/* Progressbar */
.cn-welcome-wrap .cn-compliance-check {
width: 100%;
margin: 0 0 10px 0;
}
.cn-welcome-wrap .cn-compliance-feedback {
position: relative;
margin-bottom: 1.5em;
color: #fff;
overflow-y: hidden;
max-height: 500px; /* approximate max height */
transition: all .3s cubic-bezier(0, 1, 0.5, 1);
transition-delay: 0.3s;
opacity: 1;
}
.cn-welcome-wrap .cn-compliance-feedback p {
padding: 15px;
margin: 0;
}
.cn-welcome-wrap .cn-compliance-feedback p.cn-error {
border: 1px solid #da2439;
border-radius: 3px;
background: rgba( 218,36,57, 0.5);
}
.cn-welcome-wrap .cn-compliance-feedback p.cn-error a {
color: inherit;
text-decoration: underline;
}
.cn-welcome-wrap .cn-compliance-feedback p.cn-warning {
border: 1px solid #e78d26;
border-radius: 3px;
background: rgba( 231,141,38, 0.5);
}
.cn-welcome-wrap .cn-compliance-feedback p.cn-message {
border: 1px solid #008000;
border-radius: 3px;
background: rgba( 0,128,0, 0.5);
}
.cn-welcome-wrap .cn-compliance-feedback.cn-hidden {
max-height: 0;
margin-bottom: 0;
opacity: 0;
}
.cn-welcome-wrap .cn-compliance-feedback em {
font-size: 15px;
font-weight: bold;
display: block;
margin-bottom: 10px;
color: inherit;
}
.cn-welcome-wrap .cn-progressbar {
height: 26px;
margin: 0 0 20px;
width: 100%;
position: relative;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-item:not(:first-child) {
margin-top: 10px;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-item p {
display: flex;
justify-content: space-between;
margin: 0;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-item p:first-child {
font-size: 15px;
color: #fff;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-item p:last-child {
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-label {
}
.cn-welcome-wrap .cn-compliance-info {
font-size: 15px;
line-height: inherit;
opacity: 0.5;
cursor: pointer;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-status.cn-failed {
color: red;
}
.cn-welcome-wrap .cn-compliance-results .cn-compliance-status.cn-passed {
color: #20C19E;
}
.cn-welcome-wrap .cn-progress-label {
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 14px;
font-weight: bold;
top: 3px;
color: #fff;
}
.cn-welcome-wrap .ui-progressbar {
background: rgba(255,255,255,0.1);
border-radius: 3px;
}
.cn-welcome-wrap .ui-progressbar .ui-progressbar-value {
background: #20C19E;
height: 100%;
border: 0 none;
border-radius: 3px;
margin: 3px 0;
color: #fff;
text-align: center;
float: left;
height: 20px;
line-height: 20px;
font-size: 20px;
width: 0;
min-width: 0;
-webkit-transition: width .5s ease;
-o-transition: width .5s ease;
transition: width .5s ease;
}
/* Modaal */
.cn-modal .modaal-content-container {
padding: 0;
}
.cn-modal .modaal-inner-wrapper {
padding: 30px 30px 0;
}
.modaal-overlay {
z-index: 9998 !important;
}
.cn-included,
.cn-excluded {
position: relative;
}
.cn-included .cn-icon,
.cn-excluded .cn-icon {
box-sizing: border-box;
position: absolute;
left: 0;
display: block;
transform: scale(1);
width: 22px;
height: 22px;
border: 2px solid;
}
.cn-included .cn-icon {
border-radius: 100px;
color: #20C19E;
}
.cn-included b {
color: #20C19E;
}
.cn-included .cn-icon::after {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
left: 3px;
top: -1px;
width: 6px;
height: 10px;
border-color: #20C19E;
border-width: 0 2px 2px 0;
border-style: solid;
transform-origin: bottom left;
transform: rotate(45deg);
}
.cn-excluded .cn-icon {
border-radius: 40px;
color: #FF0000;
}
.cn-excluded b {
color: #FF0000;
}
.cn-excluded .cn-icon::after,
.cn-excluded .cn-icon::before {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
width: 12px;
height: 2px;
background: #FF0000;
transform: rotate(45deg);
border-radius: 5px;
top: 8px;
left: 3px;
}
.cn-excluded .cn-icon::after {
transform: rotate(-45deg);
}
\ No newline at end of file
.cookie-notice-sidebar {
float:right;
width:280px;
margin:20px -300px 20px 20px;
position:relative
}
.cookie-notice-sidebar .inner {
padding:2em
}
.cookie-notice-sidebar>div:not(:last-child) {
margin-bottom:3em
}
.cookie-notice-sidebar .inner img {
max-width:80%;
height:auto;
display:block;
margin:20px auto
}
.cookie-notice-credits {
background:#fff;
box-shadow:0 0 0 1px rgba(0,0,0,.05)
}
.cookie-notice-credits .inner {
text-align:center;
margin:0
}
.button.cn-button {
background-color:#20c19e;
border-color:#20c19e
}
.button.cn-button:active,.button.cn-button:focus,.button.cn-button:hover {
background-color:#1ca98a;
border-color:#1ca98a
}
.button.cn-button:focus {
box-shadow:0 0 0 1px #fff,0 0 0 3px #20c19e
}
.button.button-secondary.cn-button {
background-color:#ffc107;
border-color:#ffc107;
color:#3c434a
}
.button.button-secondary.cn-button:active,
.button.button-secondary.cn-button:focus,
.button.button-secondary.cn-button:hover {
background-color:#ffca2c;
border-color:#ffca2c
}
.button.button-secondary.cn-button:focus {
box-shadow:0 0 0 1px #fff,0 0 0 3px #ffc107
}
.cookie-notice-settings .cookie-notice-credits h2 {
border:none;
padding-bottom:0;
margin-top: 0;
}
.cookie-notice-credits h3 {
font-size:14px;
line-height:1.4;
margin:0;
padding:.66em 1.33em;
border-bottom:1px solid #eee
}
.cookie-notice-settings .df-credits form {
min-width:260px;
margin-bottom:1em
}
.cookie-notice-settings .df-credits form input {
margin:0;
padding:0
}
.cookie-notice-settings {
margin-right:300px
}
.cookie-notice-settings hr,.df-credits hr {
border:solid #eee;
border-width:1px 0 0;
clear:both;
height:0
}
.cookie-notice-settings form {
float:left;
min-width:463px;
width:100%
}
.cookie-notice-settings form.cn-options-disabled h2:not(:first-of-type),
.cookie-notice-settings form.cn-options-disabled table:not(:first-of-type),
form.cn-options-submit-disabled .submit {
opacity: 0.5;
pointer-events: none;
}
.cookie-notice-settings form h2 {
margin:1.5em 0;
padding-bottom:1em;
border-bottom:1px solid #ccc
}
.cookie-notice-settings .ui-button {
margin-bottom:5px
}
.cookie-notice-settings .description {
font-size:13px;
margin-bottom:8px
}
.cookie-notice-settings .description strong {
color:#444
}
#cn_colors label {
min-width:10em;
display:inline-block
}
#cn_colors div {
vertical-align:middle
}
#cn_refuse_code .nav-tab-wrapper {
padding-top:0
}
#cn_refuse_code .refuse-code-tab {
display:none
}
#cn_refuse_code .refuse-code-tab.active {
display:block
}
#cn_refuse_code .refuse-code-tab .description {
margin-top:10px
}
.cn_compliance_status {
margin-right:20px;
font-weight:700;
display:inline-block;
}
#cn_app_status {
margin-bottom:30px
}
#cn_app_status .cn-status {
text-transform:uppercase;
font-weight:700;
position:relative;
color:#999;
}
#cn_app_status .cn-status.cn-active {
color:#1ca98a
}
#cn_app_status .cn-status.cn-inactive {
color:red
}
#cn_colors_bar_opacity_range {
vertical-align:middle;
margin-right:10px
}
.cn-toggle-container .cn-toggle-item {
font-size:14px;
display:block;
margin-bottom:20px;
cursor:default
}
.cn-toggle-container .cn-toggle-item input {
display:none
}
.cn-toggle-container .cn-toggle-item span {
display:block
}
.cn-toggle-container .cn-toggle-item .cn-toggle-heading {
color:#2271b1;
transition-property:border,background,color;
transition-duration:.05s;
transition-timing-function:ease-in-out;
text-decoration:underline;
font-weight:600;
cursor:pointer;
position: relative;
padding-left: 20px;
}
.cn-toggle-container .cn-toggle-item .cn-toggle-heading:before {
border-style: solid;
border-width: 2px 2px 0 0;
content: '';
display: inline-block;
height: 6px;
width: 6px;
position: relative;
top: 5px;
left: 0;
vertical-align: top;
transform: rotate(45deg);
transition: transform 0.2s;
position: absolute;
}
.cn-toggle-container .cn-toggle-item .cn-toggle-body {
overflow:hidden;
transition:max-height .3s;
max-height:0;
margin-top:10px;
cursor:default;
padding-left: 20px;
}
.cn-toggle-container .cn-toggle-item input:checked~.cn-toggle-heading:before {
transform: rotate(135deg);
}
.cn-toggle-container .cn-toggle-item input:checked~.cn-toggle-body {
max-height:100vh
}
.cn_fieldset_content {
margin-top: 10px;
}
@media only screen and (max-width:959px) {
.cookie-notice-sidebar {
width:100%;
float:none;
margin:20px 0
}
.cookie-notice-settings {
margin-right:0
}
}
.cn-pricing-info .cn-pricing-head h2 {
font-size: 23px;
font-weight: normal;
margin: 1em 0;
}
.cn-pricing-info .cn-pricing-body {
padding-bottom: 0;
font-size: 14px;
text-align: left;
margin: 2em 0;
}
.cn-pricing-info .cn-pricing-footer {
margin: 1em 0;
}
.cn-pricing-info div.cn-pricing-body p {
padding-left: 30px;
margin: 0.75em 0;
}
.cn-pricing-info div.cn-pricing-body .cn-icon {
position: absolute;
top: 0;
left: 0;
}
.cn-active,
.cn-inactive,
.cn-pending {
position: relative;
}
.cn-active .cn-icon,
.cn-inactive .cn-icon,
.cn-pending .cn-icon {
box-sizing: border-box;
position: relative;
left: 0;
top: 5px;
display: inline-block;
transform: scale(1);
width: 22px;
height: 22px;
border: 2px solid;
border-radius: 44px;
}
.cn-active .cn-icon {
color: #20C19E;
}
.cn-active .cn-icon::after {
border-color: #20C19E;
}
.cn-pending .cn-icon::after {
border-color: #999;
}
.cn-active .cn-icon::after,
.cn-pending .cn-icon::after {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
left: 3px;
top: -1px;
width: 6px;
height: 10px;
border-width: 0 2px 2px 0;
border-style: solid;
transform-origin: bottom left;
transform: rotate(45deg);
}
.cn-inactive .cn-icon {
color: #FF0000;
}
.cn-inactive .cn-icon::after,
.cn-inactive .cn-icon::before {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
width: 12px;
height: 2px;
background: #FF0000;
transform: rotate(45deg);
border-radius: 5px;
top: 8px;
left: 3px;
}
.cn-inactive .cn-icon::after {
transform: rotate(-45deg);
}
.cn-option-disabled label {
opacity: 0.5;
pointer-events: none;
}
.cn-warning {
color: #ffc107;
}
#cookie-notice-conditions .inside {
padding: 0;
margin: 6px 0;
}
#cookie-notice-conditions .widefat {
border: none;
box-shadow: none;
background: none;
}
#cookie-notice-conditions .widefat td.label {
width: 25%;
}
#cookie-notice-conditions .widefat h4 {
margin: 8px 0;
}
#cookie-notice-conditions .widefat h4.or-rules {
margin: 0 5px 0 0;
}
#cookie-notice-conditions .widefat td, #cookie-notice-conditions .widefat th {
padding: 0;
}
#cookie-notice-conditions .widefat .widefat {
margin-bottom: 0;
}
#cookie-notice-conditions .widefat .widefat td {
padding: 5px;
}
#cookie-notice-conditions .widefat .widefat td.param {
width: 30%;
padding-left: 0;
}
#cookie-notice-conditions .widefat .widefat td.value {
width: 30%;
text-align: center;
}
#cookie-notice-conditions .widefat .widefat td.value .spinner {
float: none;
margin: 0;
}
#cookie-notice-conditions .widefat .widefat td.operator {
width: 20%;
}
#cookie-notice-conditions .widefat .widefat td.remove {
min-width: 40px;
text-align: left;
padding: 0;
}
#cookie-notice-conditions .widefat .widefat td.remove a {
vertical-align: middle;
}
#cookie-notice-conditions .widefat .widefat select {
width: 98.95%;
}
#cookie-notice-conditions #rules-groups {
margin-bottom: 10px;
}
#cookie-notice-conditions .rules-group:last-child .or-rules,
#cookie-notice-conditions .rules-group:only-child .or-rules {
display: none;
}
\ No newline at end of file
.cookie-notice-sidebar{float:right;width:280px;margin:20px -300px 20px 20px;position:relative}.cookie-notice-sidebar .inner{padding:2em}.cookie-notice-sidebar>div:not(:last-child){margin-bottom:3em}.cookie-notice-sidebar .inner img{max-width:80%;height:auto;display:block;margin:20px auto}.cookie-notice-credits{background:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.05)}.cookie-notice-credits .inner{text-align:center;margin:0}.button.cn-button{background-color:#20c19e;border-color:#20c19e}.button.cn-button:active,.button.cn-button:focus,.button.cn-button:hover{background-color:#1ca98a;border-color:#1ca98a}.button.cn-button:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #20c19e}.button.button-secondary.cn-button{background-color:#ffc107;border-color:#ffc107;color:#3c434a}.button.button-secondary.cn-button:active,.button.button-secondary.cn-button:focus,.button.button-secondary.cn-button:hover{background-color:#ffca2c;border-color:#ffca2c}.button.button-secondary.cn-button:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #ffc107}.cookie-notice-settings .cookie-notice-credits h2{border:none;padding-bottom:0;margin-top:0}.cookie-notice-credits h3{font-size:14px;line-height:1.4;margin:0;padding:.66em 1.33em;border-bottom:1px solid #eee}.cookie-notice-settings .df-credits form{min-width:260px;margin-bottom:1em}.cookie-notice-settings .df-credits form input{margin:0;padding:0}.cookie-notice-settings{margin-right:300px}.cookie-notice-settings hr,.df-credits hr{border:solid #eee;border-width:1px 0 0;clear:both;height:0}.cookie-notice-settings form{float:left;min-width:463px;width:100%}.cookie-notice-settings form.cn-options-disabled h2:not(:first-of-type),.cookie-notice-settings form.cn-options-disabled table:not(:first-of-type),form.cn-options-submit-disabled .submit{opacity:.5;pointer-events:none}.cookie-notice-settings form h2{margin:1.5em 0;padding-bottom:1em;border-bottom:1px solid #ccc}.cookie-notice-settings .ui-button{margin-bottom:5px}.cookie-notice-settings .description{font-size:13px;margin-bottom:8px}.cookie-notice-settings .description strong{color:#444}#cn_colors label{min-width:10em;display:inline-block}#cn_colors div{vertical-align:middle}#cn_refuse_code .nav-tab-wrapper{padding-top:0}#cn_refuse_code .refuse-code-tab{display:none}#cn_refuse_code .refuse-code-tab.active{display:block}#cn_refuse_code .refuse-code-tab .description{margin-top:10px}.cn_compliance_status{margin-right:20px;font-weight:700;display:inline-block}#cn_app_status{margin-bottom:30px}#cn_app_status .cn-status{text-transform:uppercase;font-weight:700;position:relative;color:#999}#cn_app_status .cn-status.cn-active{color:#1ca98a}#cn_app_status .cn-status.cn-inactive{color:red}#cn_colors_bar_opacity_range{vertical-align:middle;margin-right:10px}.cn-toggle-container .cn-toggle-item{font-size:14px;display:block;margin-bottom:20px;cursor:default}.cn-toggle-container .cn-toggle-item input{display:none}.cn-toggle-container .cn-toggle-item span{display:block}.cn-toggle-container .cn-toggle-item .cn-toggle-heading{color:#2271b1;transition-property:border,background,color;transition-duration:.05s;transition-timing-function:ease-in-out;text-decoration:underline;font-weight:600;cursor:pointer;position:relative;padding-left:20px}.cn-toggle-container .cn-toggle-item .cn-toggle-heading:before{border-style:solid;border-width:2px 2px 0 0;content:'';display:inline-block;height:6px;width:6px;position:relative;top:5px;left:0;vertical-align:top;transform:rotate(45deg);transition:transform 0.2s;position:absolute}.cn-toggle-container .cn-toggle-item .cn-toggle-body{overflow:hidden;transition:max-height .3s;max-height:0;margin-top:10px;cursor:default;padding-left:20px}.cn-toggle-container .cn-toggle-item input:checked~.cn-toggle-heading:before{transform:rotate(135deg)}.cn-toggle-container .cn-toggle-item input:checked~.cn-toggle-body{max-height:100vh}.cn_fieldset_content{margin-top:10px}@media only screen and (max-width:959px){.cookie-notice-sidebar{width:100%;float:none;margin:20px 0}.cookie-notice-settings{margin-right:0}}.cn-pricing-info .cn-pricing-head h2{font-size:23px;font-weight:400;margin:1em 0}.cn-pricing-info .cn-pricing-body{padding-bottom:0;font-size:14px;text-align:left;margin:2em 0}.cn-pricing-info .cn-pricing-footer{margin:1em 0}.cn-pricing-info div.cn-pricing-body p{padding-left:30px;margin:.75em 0}.cn-pricing-info div.cn-pricing-body .cn-icon{position:absolute;top:0;left:0}.cn-active,.cn-inactive,.cn-pending{position:relative}.cn-active .cn-icon,.cn-inactive .cn-icon,.cn-pending .cn-icon{box-sizing:border-box;position:relative;left:0;top:5px;display:inline-block;transform:scale(1);width:22px;height:22px;border:2px solid;border-radius:44px}.cn-active .cn-icon{color:#20C19E}.cn-active .cn-icon::after{border-color:#20C19E}.cn-pending .cn-icon::after{border-color:#999}.cn-active .cn-icon::after,.cn-pending .cn-icon::after{content:"";display:block;box-sizing:border-box;position:absolute;left:3px;top:-1px;width:6px;height:10px;border-width:0 2px 2px 0;border-style:solid;transform-origin:bottom left;transform:rotate(45deg)}.cn-inactive .cn-icon{color:red}.cn-inactive .cn-icon::after,.cn-inactive .cn-icon::before{content:"";display:block;box-sizing:border-box;position:absolute;width:12px;height:2px;background:red;transform:rotate(45deg);border-radius:5px;top:8px;left:3px}.cn-inactive .cn-icon::after{transform:rotate(-45deg)}.cn-option-disabled label{opacity:.5;pointer-events:none}.cn-warning{color:#ffc107}#cookie-notice-conditions .inside{padding:0;margin:6px 0}#cookie-notice-conditions .widefat{border:none;box-shadow:none;background:none}#cookie-notice-conditions .widefat td.label{width:25%}#cookie-notice-conditions .widefat h4{margin:8px 0}#cookie-notice-conditions .widefat h4.or-rules{margin:0 5px 0 0}#cookie-notice-conditions .widefat td,#cookie-notice-conditions .widefat th{padding:0}#cookie-notice-conditions .widefat .widefat{margin-bottom:0}#cookie-notice-conditions .widefat .widefat td{padding:5px}#cookie-notice-conditions .widefat .widefat td.param{width:30%;padding-left:0}#cookie-notice-conditions .widefat .widefat td.value{width:30%;text-align:center}#cookie-notice-conditions .widefat .widefat td.value .spinner{float:none;margin:0}#cookie-notice-conditions .widefat .widefat td.operator{width:20%}#cookie-notice-conditions .widefat .widefat td.remove{min-width:40px;text-align:left;padding:0}#cookie-notice-conditions .widefat .widefat td.remove a{vertical-align:middle}#cookie-notice-conditions .widefat .widefat select{width:98.95%}#cookie-notice-conditions #rules-groups{margin-bottom:10px}#cookie-notice-conditions .rules-group:last-child .or-rules,#cookie-notice-conditions .rules-group:only-child .or-rules{display:none}
\ No newline at end of file
#cookie-notice {
position: fixed;
min-width: 100%;
height: auto;
z-index: 100000;
font-size: 13px;
letter-spacing: 0;
line-height: 20px;
left: 0;
text-align: center;
/* border-top: 2px solid #fbb03b; */
font-weight: normal;
font-family: -apple-system,BlinkMacSystemFont,Arial,Roboto,"Helvetica Neue",sans-serif;
}
#cookie-notice,
#cookie-notice * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#cookie-notice.cn-animated {
-webkit-animation-duration: 0.5s !important;
animation-duration: 0.5s !important;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
#cookie-notice.cn-animated.cn-effect-none {
-webkit-animation-duration: 0.001s !important;
animation-duration: 0.001s !important;
}
#cookie-notice .cookie-notice-container {
display: block;
}
#cookie-notice.cookie-notice-hidden .cookie-notice-container {
display: none;
}
#cookie-notice .cookie-revoke-container {
display: block;
}
#cookie-notice.cookie-revoke-hidden .cookie-revoke-container {
display: none;
}
.cn-position-top {
top: 0;
}
.cn-position-bottom {
bottom: 0;
}
.cookie-notice-container {
padding: 15px 30px;
text-align: center;
width: 100%;
z-index: 2;
}
.cookie-revoke-container {
padding: 15px 30px;
width: 100%;
z-index: 1;
}
.cn-close-icon {
position: absolute;
right: 15px;
top: 50%;
margin-top: -10px;
width: 15px;
height: 15px;
opacity: 0.5;
padding: 10px;
outline: none;
cursor: pointer;
}
.cn-close-icon:hover {
opacity: 1;
}
.cn-close-icon:before,
.cn-close-icon:after {
position: absolute;
content: ' ';
height: 15px;
width: 2px;
top: 3px;
background-color: rgba(128,128,128,1);
}
.cn-close-icon:before {
transform: rotate(45deg);
}
.cn-close-icon:after {
transform: rotate(-45deg);
}
#cookie-notice .cn-revoke-cookie {
margin: 0;
}
#cookie-notice .cn-button {
margin: 0 0 0 10px;
display: inline-block;
}
#cookie-notice .cn-button:not(.cn-button-custom) {
font-family: -apple-system,BlinkMacSystemFont,Arial,Roboto,"Helvetica Neue",sans-serif;
font-weight: normal;
font-size: 13px;
letter-spacing: 0.25px;
line-height: 20px;
margin: 0 0 0 10px;
text-align: center;
text-transform: none;
display: inline-block;
cursor: pointer;
touch-action: manipulation;
white-space: nowrap;
outline: none;
box-shadow: none;
text-shadow: none;
border: none;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-decoration: none;
padding: 8.5px 10px;
line-height: 1;
color: inherit;
}
.cn-text-container {
margin: 0 0 6px 0;
}
.cn-text-container,
.cn-buttons-container {
display: inline-block;
}
#cookie-notice.cookie-notice-visible.cn-effect-none,
#cookie-notice.cookie-revoke-visible.cn-effect-none {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}
#cookie-notice.cn-effect-none {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
#cookie-notice.cookie-notice-visible.cn-effect-fade,
#cookie-notice.cookie-revoke-visible.cn-effect-fade {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}
#cookie-notice.cn-effect-fade {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
#cookie-notice.cookie-notice-visible.cn-effect-slide,
#cookie-notice.cookie-revoke-visible.cn-effect-slide{
-webkit-animation-name: slideInUp;
animation-name: slideInUp;
}
#cookie-notice.cn-effect-slide {
-webkit-animation-name: slideOutDown;
animation-name: slideOutDown;
}
#cookie-notice.cookie-notice-visible.cn-position-top.cn-effect-slide,
#cookie-notice.cookie-revoke-visible.cn-position-top.cn-effect-slide {
-webkit-animation-name: slideInDown;
animation-name: slideInDown;
}
#cookie-notice.cn-position-top.cn-effect-slide {
-webkit-animation-name: slideOutUp;
animation-name: slideOutUp;
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-webkit-keyframes slideInUp {
from {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInUp {
from {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes slideOutDown {
from {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
}
@keyframes slideOutDown {
from {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
}
@-webkit-keyframes slideInDown {
from {
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInDown {
from {
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes slideOutUp {
from {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
}
@keyframes slideOutUp {
from {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
}
@media all and (max-width: 900px) {
.cookie-notice-container #cn-notice-text {
display: block;
}
.cookie-notice-container #cn-notice-buttons {
display: block;
}
#cookie-notice .cn-button {
margin: 0 5px 5px 5px;
}
}
@media all and (max-width: 480px) {
.cookie-notice-container,
.cookie-revoke-container {
padding: 15px 25px;
}
}
\ No newline at end of file
#cookie-notice{position:fixed;min-width:100%;height:auto;z-index:100000;font-size:13px;letter-spacing:0;line-height:20px;left:0;text-align:center;font-weight:400;font-family:-apple-system,BlinkMacSystemFont,Arial,Roboto,"Helvetica Neue",sans-serif}#cookie-notice,#cookie-notice *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cookie-notice.cn-animated{-webkit-animation-duration:0.5s!important;animation-duration:0.5s!important;-webkit-animation-fill-mode:both;animation-fill-mode:both}#cookie-notice.cn-animated.cn-effect-none{-webkit-animation-duration:0.001s!important;animation-duration:0.001s!important}#cookie-notice .cookie-notice-container{display:block}#cookie-notice.cookie-notice-hidden .cookie-notice-container{display:none}#cookie-notice .cookie-revoke-container{display:block}#cookie-notice.cookie-revoke-hidden .cookie-revoke-container{display:none}.cn-position-top{top:0}.cn-position-bottom{bottom:0}.cookie-notice-container{padding:15px 30px;text-align:center;width:100%;z-index:2}.cookie-revoke-container{padding:15px 30px;width:100%;z-index:1}.cn-close-icon{position:absolute;right:15px;top:50%;margin-top:-10px;width:15px;height:15px;opacity:.5;padding:10px;outline:none;cursor:pointer}.cn-close-icon:hover{opacity:1}.cn-close-icon:before,.cn-close-icon:after{position:absolute;content:' ';height:15px;width:2px;top:3px;background-color:rgba(128,128,128,1)}.cn-close-icon:before{transform:rotate(45deg)}.cn-close-icon:after{transform:rotate(-45deg)}#cookie-notice .cn-revoke-cookie{margin:0}#cookie-notice .cn-button{margin:0 0 0 10px;display:inline-block}#cookie-notice .cn-button:not(.cn-button-custom){font-family:-apple-system,BlinkMacSystemFont,Arial,Roboto,"Helvetica Neue",sans-serif;font-weight:400;font-size:13px;letter-spacing:.25px;line-height:20px;margin:0 0 0 10px;text-align:center;text-transform:none;display:inline-block;cursor:pointer;touch-action:manipulation;white-space:nowrap;outline:none;box-shadow:none;text-shadow:none;border:none;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;text-decoration:none;padding:8.5px 10px;line-height:1;color:inherit}.cn-text-container{margin:0 0 6px 0}.cn-text-container,.cn-buttons-container{display:inline-block}#cookie-notice.cookie-notice-visible.cn-effect-none,#cookie-notice.cookie-revoke-visible.cn-effect-none{-webkit-animation-name:fadeIn;animation-name:fadeIn}#cookie-notice.cn-effect-none{-webkit-animation-name:fadeOut;animation-name:fadeOut}#cookie-notice.cookie-notice-visible.cn-effect-fade,#cookie-notice.cookie-revoke-visible.cn-effect-fade{-webkit-animation-name:fadeIn;animation-name:fadeIn}#cookie-notice.cn-effect-fade{-webkit-animation-name:fadeOut;animation-name:fadeOut}#cookie-notice.cookie-notice-visible.cn-effect-slide,#cookie-notice.cookie-revoke-visible.cn-effect-slide{-webkit-animation-name:slideInUp;animation-name:slideInUp}#cookie-notice.cn-effect-slide{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}#cookie-notice.cookie-notice-visible.cn-position-top.cn-effect-slide,#cookie-notice.cookie-revoke-visible.cn-position-top.cn-effect-slide{-webkit-animation-name:slideInDown;animation-name:slideInDown}#cookie-notice.cn-position-top.cn-effect-slide{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeOut{from{opacity:1}to{opacity:0}}@keyframes fadeOut{from{opacity:1}to{opacity:0}}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@media all and (max-width:900px){.cookie-notice-container #cn-notice-text{display:block}.cookie-notice-container #cn-notice-buttons{display:block}#cookie-notice .cn-button{margin:0 5px 5px 5px}}@media all and (max-width:480px){.cookie-notice-container,.cookie-revoke-container{padding:15px 25px}}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 140 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;"><g><rect x="8.75" y="8.732" width="122.5" height="122.5" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.75px;"/><path d="M8.75,96.232l122.5,0" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.75px;"/></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 140 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;"><g><rect x="8.75" y="8.733" width="122.5" height="122.5" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.75px;"/><rect x="39.375" y="39.349" width="61.25" height="61.268" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.8px;"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" viewBox="0 0 140 140" width="140" height="140"><g transform="matrix(5.833333333333333,0,0,5.833333333333333,0,0)"><path d="M1.500 1.497 L22.500 1.497 L22.500 22.497 L1.500 22.497 Z" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M7.5 1.497L7.5 22.497" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 140 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;"><g><rect x="8.75" y="8.733" width="122.5" height="122.5" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.75px;"/><path d="M96.25,8.733l0,122.5" style="fill:none;fill-rule:nonzero;stroke:#000;stroke-width:8.75px;"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" viewBox="0 0 140 140" width="140" height="140"><g transform="matrix(5.833333333333333,0,0,5.833333333333333,0,0)"><path d="M1.500 1.497 L22.500 1.497 L22.500 22.497 L1.500 22.497 Z" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M1.5 7.497L22.5 7.497" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></g></svg>
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Bot_Detect class.
*
* Based on CrawlerDetect php class adjusted to PHP 5.2
* https://github.com/JayBizzle/Crawler-Detect/blob/master/src/CrawlerDetect.php
*
* @since 2.0.0
* @class Cookie_Notice_Bot_Detect
*/
class Cookie_Notice_Bot_Detect {
/**
* The user agent.
*
* @var null
*/
protected $user_agent = null;
/**
* Headers that contain a user agent.
*
* @var array
*/
protected $http_headers = [];
/**
* Store regex matches.
*
* @var array
*/
protected $matches = [];
/**
* Crawlers object.
*
* @var object
*/
protected $crawlers = [];
/**
* Exclusions object.
*
* @var object
*/
protected $exclusions = [];
/**
* Headers object.
*
* @var object
*/
protected $ua_http_headers;
/**
* Class constructor.
*
* @return void
*/
public function __construct() {
$this->crawlers = $this->get_crawlers_list();
$this->exclusions = $this->get_exclusions_list();
add_action( 'after_setup_theme', [ $this, 'init' ] );
}
/**
* Initialize class.
*
* @return void
*/
public function init() {
// break on admin side
if ( is_admin() && ! wp_doing_ajax() )
return;
$this->ua_http_headers = $this->get_headers_list();
$this->set_http_headers();
$this->set_user_agent();
}
/**
* Set HTTP headers.
*
* @param array $http_headers
* @return void
*/
public function set_http_headers( $http_headers = null ) {
// use global _SERVER if $http_headers aren't defined
if ( ! is_array( $http_headers ) || ! count( $http_headers ) )
$http_headers = $_SERVER;
// clear existing headers
$this->http_headers = [];
// only save HTTP headers - in PHP land, that means only _SERVER vars that start with HTTP_.
foreach ( $http_headers as $key => $value ) {
if ( substr( $key, 0, 5 ) === 'HTTP_' )
$this->http_headers[$key] = $value;
}
}
/**
* Return user agent headers.
*
* @return array
*/
public function get_ua_http_headers() {
return $this->ua_http_headers;
}
/**
* Return the user agent.
*
* @return string
*/
public function get_user_agent() {
return $this->user_agent;
}
/**
* Set the user agent.
*
* @param string $user_agent
* @return string
*/
public function set_user_agent( $user_agent = null ) {
if ( false === empty( $user_agent ) )
return $this->user_agent = $user_agent;
else {
$this->user_agent = null;
foreach ( $this->get_ua_http_headers() as $alt_header ) {
if ( false === empty( $this->http_headers[$alt_header] ) ) // @todo: should use get_http_header(), but it would be slow.
$this->user_agent .= $this->http_headers[$alt_header] . ' ';
}
return $this->user_agent = ( ! empty( $this->user_agent ) ? trim( $this->user_agent ) : null );
}
}
/**
* Build the user agent regex.
*
* @return string
*/
public function get_regex() {
return '(' . implode( '|', $this->crawlers ) . ')';
}
/**
* Build the replacement regex.
*
* @return string
*/
public function get_exclusions() {
return '(' . implode( '|', $this->exclusions ) . ')';
}
/**
* Check user agent string against the regex.
*
* @param string $user_agent
* @return bool
*/
public function is_crawler( $user_agent = null ) {
$agent = (string)( is_null( $user_agent ) ? $this->user_agent : $user_agent );
$agent = preg_replace( '/' . $this->get_exclusions() . '/i', '', $agent );
if ( strlen( trim( $agent ) ) === 0 )
return false;
else
$result = preg_match( '/' . $this->get_regex() . '/i', trim( $agent ), $matches );
if ( $matches )
$this->matches = $matches;
return (bool) $result;
}
/**
* Return the matches.
*
* @return string
*/
public function get_matches() {
return isset( $this->matches[0] ) ? $this->matches[0] : null;
}
/**
* Return the regular expressions to match against the user agent.
*
* @return array
*/
protected function get_crawlers_list() {
return [
' YLT',
'^Aether',
'^Amazon Simple Notification Service Agent$',
'^Amazon-Route53-Health-Check-Service',
'^b0t$',
'^bluefish ',
'^Calypso v\/',
'^COMODO DCV',
'^Corax',
'^DangDang',
'^DavClnt',
'^DHSH',
'^docker\/[0-9]',
'^Expanse',
'^FDM ',
'^git\/',
'^Goose\/',
'^Grabber',
'^Gradle\/',
'^HTTPClient\/',
'^HTTPing',
'^Java\/',
'^Jeode\/',
'^Jetty\/',
'^Mail\/',
'^Mget',
'^Microsoft URL Control',
'^Mikrotik\/',
'^Netlab360',
'^NG\/[0-9\.]',
'^NING\/',
'^npm\/',
'^Nuclei',
'^PHP-AYMAPI\/',
'^PHP\/',
'^pip\/',
'^pnpm\/',
'^RMA\/',
'^Ruby|Ruby\/[0-9]',
'^Swurl ',
'^TLS tester ',
'^twine\/',
'^ureq',
'^VSE\/[0-9]',
'^WordPress\.com',
'^XRL\/[0-9]',
'^ZmEu',
'008\/',
'13TABS',
'192\.comAgent',
'2GDPR\/',
'2ip\.ru',
'404enemy',
'7Siters',
'80legs',
'a3logics\.in',
'A6-Indexer',
'Abonti',
'Aboundex',
'aboutthedomain',
'Accoona-AI-Agent',
'acebookexternalhit\/',
'acoon',
'acrylicapps\.com\/pulp',
'Acunetix',
'AdAuth\/',
'adbeat',
'AddThis',
'ADmantX',
'AdminLabs',
'adressendeutschland',
'adreview\/',
'adscanner',
'adstxt-worker',
'Adstxtaggregator',
'adstxt\.com',
'Adyen HttpClient',
'AffiliateLabz\/',
'affilimate-puppeteer',
'agentslug',
'AHC',
'aihit',
'aiohttp\/',
'Airmail',
'akka-http\/',
'akula\/',
'alertra',
'alexa site audit',
'Alibaba\.Security\.Heimdall',
'Alligator',
'allloadin',
'AllSubmitter',
'alyze\.info',
'amagit',
'Anarchie',
'AndroidDownloadManager',
'Anemone',
'AngleSharp',
'annotate_google',
'Anthill',
'Anturis Agent',
'Ant\.com',
'AnyEvent-HTTP\/',
'Apache Ant\/',
'Apache Droid',
'Apache OpenOffice',
'Apache-HttpAsyncClient',
'Apache-HttpClient',
'ApacheBench',
'Apexoo',
'apimon\.de',
'APIs-Google',
'AportWorm\/',
'AppBeat\/',
'AppEngine-Google',
'AppleSyndication',
'Aprc\/[0-9]',
'Arachmo',
'arachnode',
'Arachnophilia',
'aria2',
'Arukereso',
'asafaweb',
'Asana\/',
'Ask Jeeves',
'AskQuickly',
'ASPSeek',
'Asterias',
'Astute',
'asynchttp',
'Attach',
'attohttpc',
'autocite',
'AutomaticWPTester',
'Autonomy',
'awin\.com',
'AWS Security Scanner',
'axios\/',
'a\.pr-cy\.ru',
'B-l-i-t-z-B-O-T',
'Backlink-Ceck',
'backlink-check',
'BacklinkHttpStatus',
'BackStreet',
'BackupLand',
'BackWeb',
'Bad-Neighborhood',
'Badass',
'baidu\.com',
'Bandit',
'basicstate',
'BatchFTP',
'Battleztar Bazinga',
'baypup\/',
'BazQux',
'BBBike',
'BCKLINKS',
'BDFetch',
'BegunAdvertising',
'Bewica-security-scan',
'Bidtellect',
'BigBozz',
'Bigfoot',
'biglotron',
'BingLocalSearch',
'BingPreview',
'binlar',
'biNu image cacher',
'Bitacle',
'Bitrix link preview',
'biz_Directory',
'BKCTwitterUnshortener\/',
'Black Hole',
'Blackboard Safeassign',
'BlackWidow',
'BlockNote\.Net',
'BlogBridge',
'Bloglines',
'Bloglovin',
'BlogPulseLive',
'BlogSearch',
'Blogtrottr',
'BlowFish',
'boitho\.com-dc',
'Boost\.Beast',
'BPImageWalker',
'Braintree-Webhooks',
'Branch Metrics API',
'Branch-Passthrough',
'Brandprotect',
'BrandVerity',
'Brandwatch',
'Brodie\/',
'Browsershots',
'BUbiNG',
'Buck\/',
'Buddy',
'BuiltWith',
'Bullseye',
'BunnySlippers',
'Burf Search',
'Butterfly\/',
'BuzzSumo',
'CAAM\/[0-9]',
'CakePHP',
'Calculon',
'Canary%20Mail',
'CaretNail',
'catexplorador',
'CC Metadata Scaper',
'Cegbfeieh',
'censys',
'centuryb.o.t9[at]gmail.com',
'Cerberian Drtrs',
'CERT\.at-Statistics-Survey',
'cf-facebook',
'cg-eye',
'changedetection',
'ChangesMeter',
'Charlotte',
'chatterino-api-cache',
'CheckHost',
'checkprivacy',
'CherryPicker',
'ChinaClaw',
'Chirp\/',
'chkme\.com',
'Chlooe',
'Chromaxa',
'CirrusExplorer',
'CISPA Vulnerability Notification',
'CISPA Web Analyser',
'Citoid',
'CJNetworkQuality',
'Clarsentia',
'clips\.ua\.ac\.be',
'Cloud mapping',
'CloudEndure',
'CloudFlare-AlwaysOnline',
'Cloudflare-Healthchecks',
'Cloudinary',
'cmcm\.com',
'coccoc',
'cognitiveseo',
'ColdFusion',
'colly -',
'CommaFeed',
'Commons-HttpClient',
'commonscan',
'contactbigdatafr',
'contentkingapp',
'Contextual Code Sites Explorer',
'convera',
'CookieReports',
'copyright sheriff',
'CopyRightCheck',
'Copyscape',
'cortex\/',
'Cosmos4j\.feedback',
'Covario-IDS',
'Craw\/',
'Crescent',
'Criteo',
'Crowsnest',
'CSHttp',
'CSSCheck',
'Cula\/',
'curb',
'Curious George',
'curl',
'cuwhois\/',
'cybo\.com',
'DAP\/NetHTTP',
'DareBoost',
'DatabaseDriverMysqli',
'DataCha0s',
'DatadogSynthetics',
'Datafeedwatch',
'Datanyze',
'DataparkSearch',
'dataprovider',
'DataXu',
'Daum(oa)?[ \/][0-9]',
'dBpoweramp',
'ddline',
'deeris',
'delve\.ai',
'Demon',
'DeuSu',
'developers\.google\.com\/\+\/web\/snippet\/',
'Devil',
'Digg',
'Digincore',
'DigitalPebble',
'Dirbuster',
'Discourse Forum Onebox',
'Dispatch\/',
'Disqus\/',
'DittoSpyder',
'dlvr',
'DMBrowser',
'DNSPod-reporting',
'docoloc',
'Dolphin http client',
'DomainAppender',
'DomainLabz',
'Domains Project\/',
'Donuts Content Explorer',
'dotMailer content retrieval',
'dotSemantic',
'downforeveryoneorjustme',
'Download Wonder',
'downnotifier',
'DowntimeDetector',
'Drip',
'drupact',
'Drupal \(\+http:\/\/drupal\.org\/\)',
'DTS Agent',
'dubaiindex',
'DuplexWeb-Google',
'DynatraceSynthetic',
'EARTHCOM',
'Easy-Thumb',
'EasyDL',
'Ebingbong',
'ec2linkfinder',
'eCairn-Grabber',
'eCatch',
'ECCP',
'eContext\/',
'Ecxi',
'EirGrabber',
'ElectricMonk',
'elefent',
'EMail Exractor',
'EMail Wolf',
'EmailWolf',
'Embarcadero',
'Embed PHP Library',
'Embedly',
'endo\/',
'europarchive\.org',
'evc-batch',
'EventMachine HttpClient',
'Everwall Link Expander',
'Evidon',
'Evrinid',
'ExactSearch',
'ExaleadCloudview',
'Excel\/',
'exif',
'ExoRank',
'Exploratodo',
'Express WebPictures',
'Extreme Picture Finder',
'EyeNetIE',
'ezooms',
'facebookexternalhit',
'facebookexternalua',
'facebookplatform',
'fairshare',
'Faraday v',
'fasthttp',
'Faveeo',
'Favicon downloader',
'faviconarchive',
'faviconkit',
'FavOrg',
'Feed Wrangler',
'Feedable\/',
'Feedbin',
'FeedBooster',
'FeedBucket',
'FeedBunch\/',
'FeedBurner',
'feeder',
'Feedly',
'FeedshowOnline',
'Feedshow\/',
'Feedspot',
'FeedViewer\/',
'Feedwind\/',
'FeedZcollector',
'feeltiptop',
'Fetch API',
'Fetch\/[0-9]',
'Fever\/[0-9]',
'FHscan',
'Fiery%20Feeds',
'Filestack',
'Fimap',
'findlink',
'findthatfile',
'FlashGet',
'FlipboardBrowserProxy',
'FlipboardProxy',
'FlipboardRSS',
'Flock\/',
'Florienzh\/',
'fluffy',
'Flunky',
'flynxapp',
'forensiq',
'ForusP',
'FoundSeoTool',
'fragFINN\.de',
'free thumbnails',
'Freeuploader',
'FreshRSS',
'frontman',
'Funnelback',
'Fuzz Faster U Fool',
'G-i-g-a-b-o-t',
'g00g1e\.net',
'ganarvisitas',
'gdnplus\.com',
'geek-tools',
'Genieo',
'GentleSource',
'GetCode',
'Getintent',
'GetLinkInfo',
'getprismatic',
'GetRight',
'getroot',
'GetURLInfo\/',
'GetWeb',
'Geziyor',
'Ghost Inspector',
'GigablastOpenSource',
'GIS-LABS',
'github-camo',
'GitHub-Hookshot',
'github\.com',
'Go http package',
'Go [\d\.]* package http',
'Go!Zilla',
'Go-Ahead-Got-It',
'Go-http-client',
'go-mtasts\/',
'gobuster',
'gobyus',
'Gofeed',
'gofetch',
'Goldfire Server',
'GomezAgent',
'gooblog',
'Goodzer\/',
'Google AppsViewer',
'Google Desktop',
'Google favicon',
'Google Keyword Suggestion',
'Google Keyword Tool',
'Google Page Speed Insights',
'Google PP Default',
'Google Search Console',
'Google Web Preview',
'Google-Ads-Creatives-Assistant',
'Google-Ads-Overview',
'Google-Adwords',
'Google-Apps-Script',
'Google-Calendar-Importer',
'Google-HotelAdsVerifier',
'Google-HTTP-Java-Client',
'Google-InspectionTool',
'Google-Podcast',
'Google-Publisher-Plugin',
'Google-Read-Aloud',
'Google-SearchByImage',
'Google-Site-Verification',
'Google-SMTP-STS',
'Google-speakr',
'Google-Structured-Data-Testing-Tool',
'Google-Transparency-Report',
'google-xrawler',
'Google-Youtube-Links',
'GoogleDocs',
'GoogleHC\/',
'GoogleProber',
'GoogleProducer',
'GoogleSites',
'Gookey',
'GoSpotCheck',
'gosquared-thumbnailer',
'Gotit',
'GoZilla',
'grabify',
'GrabNet',
'Grafula',
'Grammarly',
'GrapeFX',
'GreatNews',
'Gregarius',
'GRequests',
'grokkit',
'grouphigh',
'grub-client',
'gSOAP\/',
'GT::WWW',
'GTmetrix',
'GuzzleHttp',
'gvfs\/',
'HAA(A)?RTLAND http client',
'Haansoft',
'hackney\/',
'Hadi Agent',
'HappyApps-WebCheck',
'Hardenize',
'Hatena',
'Havij',
'HaxerMen',
'HeadlessChrome',
'HEADMasterSEO',
'HeartRails_Capture',
'help@dataminr\.com',
'heritrix',
'Hexometer',
'historious',
'hkedcity',
'hledejLevne\.cz',
'Hloader',
'HMView',
'Holmes',
'HonesoSearchEngine',
'HootSuite Image proxy',
'Hootsuite-WebFeed',
'hosterstats',
'HostTracker',
'ht:\/\/check',
'htdig',
'HTMLparser',
'htmlyse',
'HTTP Banner Detection',
'http-get',
'HTTP-Header-Abfrage',
'http-kit',
'http-request\/',
'HTTP-Tiny',
'HTTP::Lite',
'http:\/\/www.neomo.de\/',
'HttpComponents',
'httphr',
'HTTPie',
'HTTPMon',
'httpRequest',
'httpscheck',
'httpssites_power',
'httpunit',
'HttpUrlConnection',
'http\.rb\/',
'HTTP_Compression_Test',
'http_get',
'http_request2',
'http_requester',
'httrack',
'huaweisymantec',
'HubSpot ',
'HubSpot-Link-Resolver',
'Humanlinks',
'i2kconnect\/',
'Iblog',
'ichiro',
'Id-search',
'IdeelaborPlagiaat',
'IDG Twitter Links Resolver',
'IDwhois\/',
'Iframely',
'igdeSpyder',
'iGooglePortal',
'IlTrovatore',
'Image Fetch',
'Image Sucker',
'ImageEngine\/',
'ImageVisu\/',
'Imagga',
'imagineeasy',
'imgsizer',
'InAGist',
'inbound\.li parser',
'InDesign%20CC',
'Indy Library',
'InetURL',
'infegy',
'infohelfer',
'InfoTekies',
'InfoWizards Reciprocal Link',
'inpwrd\.com',
'instabid',
'Instapaper',
'Integrity',
'integromedb',
'Intelliseek',
'InterGET',
'Internet Ninja',
'InternetSeer',
'internetVista monitor',
'internetwache',
'internet_archive',
'intraVnews',
'IODC',
'IOI',
'Inboxb0t',
'iplabel',
'ips-agent',
'IPS\/[0-9]',
'IPWorks HTTP\/S Component',
'iqdb\/',
'Iria',
'Irokez',
'isitup\.org',
'iskanie',
'isUp\.li',
'iThemes Sync\/',
'IZaBEE',
'iZSearch',
'JAHHO',
'janforman',
'Jaunt\/',
'Java.*outbrain',
'javelin\.io',
'Jbrofuzz',
'Jersey\/',
'JetCar',
'Jigsaw',
'Jobboerse',
'JobFeed discovery',
'Jobg8 URL Monitor',
'jobo',
'Jobrapido',
'Jobsearch1\.5',
'JoinVision Generic',
'JolokiaPwn',
'Joomla',
'Jorgee',
'JS-Kit',
'JungleKeyThumbnail',
'JustView',
'Kaspersky Lab CFR link resolver',
'Kelny\/',
'Kerrigan\/',
'KeyCDN',
'Keyword Density',
'Keywords Research',
'khttp\/',
'KickFire',
'KimonoLabs\/',
'Kml-Google',
'knows\.is',
'KOCMOHABT',
'kouio',
'kube-probe',
'kubectl',
'kulturarw3',
'KumKie',
'Larbin',
'Lavf\/',
'leakix\.net',
'LeechFTP',
'LeechGet',
'letsencrypt',
'Lftp',
'LibVLC',
'LibWeb',
'Libwhisker',
'libwww',
'Licorne',
'Liferea\/',
'Lighthouse',
'Lightspeedsystems',
'Likse',
'limber\.io',
'Link Valet',
'LinkAlarm\/',
'LinkAnalyser',
'linkCheck',
'linkdex',
'LinkExaminer',
'linkfluence',
'linkpeek',
'LinkPreview',
'LinkScan',
'LinksManager',
'LinkTiger',
'LinkWalker',
'link_thumbnailer',
'Lipperhey',
'Litemage_walker',
'livedoor ScreenShot',
'LoadImpactRload',
'localsearch-web',
'LongURL API',
'longurl-r-package',
'looid\.com',
'looksystems\.net',
'ltx71',
'lua-resty-http',
'Lucee \(CFML Engine\)',
'Lush Http Client',
'lwp-request',
'lwp-trivial',
'LWP::Simple',
'lycos',
'LYT\.SR',
'L\.webis',
'mabontland',
'MacOutlook\/',
'Mag-Net',
'MagpieRSS',
'Mail::STS',
'MailChimp',
'Mail\.Ru',
'Majestic12',
'makecontact\/',
'Mandrill',
'MapperCmd',
'marketinggrader',
'MarkMonitor',
'MarkWatch',
'Mass Downloader',
'masscan\/',
'Mata Hari',
'mattermost',
'Mediametric',
'Mediapartners-Google',
'mediawords',
'MegaIndex\.ru',
'MeltwaterNews',
'Melvil Rawi',
'MemGator',
'Metaspinner',
'MetaURI',
'MFC_Tear_Sample',
'Microsearch',
'Microsoft Data Access',
'Microsoft Office',
'Microsoft Outlook',
'Microsoft Windows Network Diagnostics',
'Microsoft-WebDAV-MiniRedir',
'Microsoft\.Data\.Mashup',
'MIDown tool',
'MIIxpc',
'Mindjet',
'Miniature\.io',
'Miniflux',
'mio_httpc',
'Miro-HttpClient',
'Mister PiX',
'mixdata dot com',
'mixed-content-scan',
'mixnode',
'Mnogosearch',
'mogimogi',
'Mojeek',
'Mojolicious \(Perl\)',
'Mollie',
'monitis',
'Monitority\/',
'Monit\/',
'montastic',
'MonTools',
'Moreover',
'Morfeus Fucking Scanner',
'Morning Paper',
'MovableType',
'mowser',
'Mrcgiguy',
'Mr\.4x3 Powered',
'MS Web Services Client Protocol',
'MSFrontPage',
'mShots',
'MuckRack\/',
'muhstik-scan',
'MVAClient',
'MxToolbox\/',
'myseosnapshot',
'nagios',
'Najdi\.si',
'Name Intelligence',
'NameFo\.com',
'Nameprotect',
'nationalarchives',
'Navroad',
'NearSite',
'Needle',
'Nessus',
'Net Vampire',
'NetAnts',
'NETCRAFT',
'NetLyzer',
'NetMechanic',
'NetNewsWire',
'Netpursual',
'netresearch',
'NetShelter ContentScan',
'Netsparker',
'NetSystemsResearch',
'nettle',
'NetTrack',
'Netvibes',
'NetZIP',
'Neustar WPM',
'NeutrinoAPI',
'NewRelicPinger',
'NewsBlur .*Finder',
'NewsGator',
'newsme',
'newspaper\/',
'Nexgate Ruby Client',
'NG-Search',
'nghttp2',
'Nibbler',
'NICErsPRO',
'NihilScio',
'Nikto',
'nineconnections',
'NLNZ_IAHarvester',
'Nmap Scripting Engine',
'node-fetch',
'node-superagent',
'node-urllib',
'Nodemeter',
'NodePing',
'node\.io',
'nominet\.org\.uk',
'nominet\.uk',
'Norton-Safeweb',
'Notifixious',
'notifyninja',
'NotionEmbedder',
'nuhk',
'nutch',
'Nuzzel',
'nWormFeedFinder',
'nyawc\/',
'Nymesis',
'NYU',
'Observatory\/',
'Ocelli\/',
'Octopus',
'oegp',
'Offline Explorer',
'Offline Navigator',
'OgScrper',
'okhttp',
'omgili',
'OMSC',
'Online Domain Tools',
'Open Source RSS',
'OpenCalaisSemanticProxy',
'Openfind',
'OpenLinkProfiler',
'Openstat\/',
'OpenVAS',
'OPPO A33',
'Optimizer',
'Orbiter',
'OrgProbe\/',
'orion-semantics',
'Outlook-Express',
'Outlook-iOS',
'Owler',
'Owlin',
'ownCloud News',
'ow\.ly',
'OxfordCloudService',
'page scorer',
'Page Valet',
'page2rss',
'PageFreezer',
'PageGrabber',
'PagePeeker',
'PageScorer',
'Pagespeed\/',
'PageThing',
'page_verifier',
'Panopta',
'panscient',
'Papa Foto',
'parsijoo',
'Pavuk',
'PayPal IPN',
'pcBrowser',
'Pcore-HTTP',
'PDF24 URL To PDF',
'Pearltrees',
'PECL::HTTP',
'peerindex',
'Peew',
'PeoplePal',
'Perlu -',
'PhantomJS Screenshoter',
'PhantomJS\/',
'Photon\/',
'php-requests',
'phpservermon',
'Pi-Monster',
'Picscout',
'Picsearch',
'PictureFinder',
'Pimonster',
'Pingability',
'PingAdmin\.Ru',
'Pingdom',
'Pingoscope',
'PingSpot',
'ping\.blo\.gs',
'pinterest\.com',
'Pixray',
'Pizilla',
'Plagger\/',
'Pleroma ',
'Ploetz \+ Zeller',
'Plukkie',
'plumanalytics',
'PocketImageCache',
'PocketParser',
'Pockey',
'PodcastAddict\/',
'POE-Component-Client-HTTP',
'Polymail\/',
'Pompos',
'Porkbun',
'Port Monitor',
'postano',
'postfix-mta-sts-resolver',
'PostmanRuntime',
'postplanner\.com',
'PostPost',
'postrank',
'PowerPoint\/',
'Prebid',
'Prerender',
'Priceonomics Analysis Engine',
'PrintFriendly',
'PritTorrent',
'Prlog',
'probethenet',
'Project ?25499',
'Project-Resonance',
'prospectb2b',
'Protopage',
'ProWebWalker',
'proximic',
'PRTG Network Monitor',
'pshtt, https scanning',
'PTST ',
'PTST\/[0-9]+',
'Pump',
'Python-httplib2',
'python-httpx',
'python-requests',
'Python-urllib',
'Qirina Hurdler',
'QQDownload',
'QrafterPro',
'Qseero',
'Qualidator',
'QueryN Metasearch',
'queuedriver',
'quic-go-HTTP\/',
'QuiteRSS',
'Quora Link Preview',
'Qwantify',
'Radian6',
'RadioPublicImageResizer',
'Railgun\/',
'RankActive',
'RankFlex',
'RankSonicSiteAuditor',
'RapidLoad\/',
'Re-re Studio',
'ReactorNetty',
'Readability',
'RealDownload',
'RealPlayer%20Downloader',
'RebelMouse',
'Recorder',
'RecurPost\/',
'redback\/',
'ReederForMac',
'Reeder\/',
'ReGet',
'RepoMonkey',
'request\.js',
'reqwest\/',
'ResponseCodeTest',
'RestSharp',
'Riddler',
'Rival IQ',
'Robosourcer',
'Robozilla',
'ROI Hunter',
'RPT-HTTPClient',
'RSSMix\/',
'RSSOwl',
'RyowlEngine',
'safe-agent-scanner',
'SalesIntelligent',
'Saleslift',
'SAP NetWeaver Application Server',
'SauceNAO',
'SBIder',
'sc-downloader',
'scalaj-http',
'Scamadviser-Frontend',
'ScanAlert',
'scan\.lol',
'Scoop',
'scooter',
'ScopeContentAG-HTTP-Client',
'ScoutJet',
'ScoutURLMonitor',
'ScrapeBox Page Scanner',
'Scrapy',
'Screaming',
'ScreenShotService',
'Scrubby',
'Scrutiny\/',
'Search37',
'searchenginepromotionhelp',
'Searchestate',
'SearchExpress',
'SearchSight',
'SearchWP',
'search\.thunderstone',
'Seeker',
'semanticdiscovery',
'semanticjuice',
'Semiocast HTTP client',
'Semrush',
'Sendsay\.Ru',
'sentry\/',
'SEO Browser',
'Seo Servis',
'seo-nastroj\.cz',
'seo4ajax',
'Seobility',
'SEOCentro',
'SeoCheck',
'seocompany',
'SEOkicks',
'SEOlizer',
'Seomoz',
'SEOprofiler',
'seoscanners',
'SEOsearch',
'seositecheckup',
'SEOstats',
'servernfo',
'sexsearcher',
'Seznam',
'Shelob',
'Shodan',
'Shoppimon',
'ShopWiki',
'ShortLinkTranslate',
'shortURL lengthener',
'shrinktheweb',
'Sideqik',
'Siege',
'SimplePie',
'SimplyFast',
'Siphon',
'SISTRIX',
'Site Sucker',
'Site-Shot\/',
'Site24x7',
'SiteBar',
'Sitebeam',
'Sitebulb\/',
'SiteCondor',
'SiteExplorer',
'SiteGuardian',
'Siteimprove',
'SiteIndexed',
'Sitemap(s)? Generator',
'SitemapGenerator',
'SiteMonitor',
'Siteshooter B0t',
'SiteSnagger',
'SiteSucker',
'SiteTruth',
'Sitevigil',
'sitexy\.com',
'SkypeUriPreview',
'Slack\/',
'sli-systems\.com',
'slider\.com',
'slurp',
'SlySearch',
'SmartDownload',
'SMRF URL Expander',
'SMUrlExpander',
'Snake',
'Snappy',
'SnapSearch',
'Snarfer\/',
'SniffRSS',
'sniptracker',
'Snoopy',
'SnowHaze Search',
'sogou web',
'SortSite',
'Sottopop',
'sovereign\.ai',
'SpaceBison',
'SpamExperts',
'Spammen',
'Spanner',
'Spawning-AI',
'spaziodati',
'SPDYCheck',
'Specificfeeds',
'SpeedKit',
'speedy',
'SPEng',
'Spinn3r',
'spray-can',
'Sprinklr ',
'spyonweb',
'sqlmap',
'Sqlworm',
'Sqworm',
'SSL Labs',
'ssl-tools',
'StackRambler',
'Statastico\/',
'Statically-',
'StatusCake',
'Steeler',
'Stratagems Kumo',
'Stripe\/',
'Stroke\.cz',
'StudioFACA',
'StumbleUpon',
'suchen',
'Sucuri',
'summify',
'SuperHTTP',
'Surphace Scout',
'Suzuran',
'swcd ',
'Symfony BrowserKit',
'Symfony2 BrowserKit',
'Synapse\/',
'Syndirella\/',
'SynHttpClient-Built',
'Sysomos',
'sysscan',
'Szukacz',
'T0PHackTeam',
'tAkeOut',
'Tarantula\/',
'Taringa UGC',
'TarmotGezgin',
'tchelebi\.io',
'techiaith\.cymru',
'Teleport',
'Telesoft',
'Telesphoreo',
'Telesphorep',
'Tenon\.io',
'teoma',
'terrainformatica',
'Test Certificate Info',
'testuri',
'Tetrahedron',
'TextRazor Downloader',
'The Drop Reaper',
'The Expert HTML Source Viewer',
'The Intraformant',
'The Knowledge AI',
'theinternetrules',
'TheNomad',
'Thinklab',
'Thumbor',
'Thumbshots',
'ThumbSniper',
'timewe\.net',
'TinEye',
'Tiny Tiny RSS',
'TLSProbe\/',
'Toata',
'topster',
'touche\.com',
'Traackr\.com',
'tracemyfile',
'Trackuity',
'TrapitAgent',
'Trendiction',
'Trendsmap',
'trendspottr',
'truwoGPS',
'TryJsoup',
'TulipChain',
'Turingos',
'Turnitin',
'tweetedtimes',
'Tweetminster',
'Tweezler\/',
'twibble',
'Twice',
'Twikle',
'Twingly',
'Twisted PageGetter',
'Typhoeus',
'ubermetrics-technologies',
'uclassify',
'UdmSearch',
'ultimate_sitemap_parser',
'unchaos',
'unirest-java',
'UniversalFeedParser',
'unshortenit',
'Unshorten\.It',
'Untiny',
'UnwindFetchor',
'updated',
'updown\.io daemon',
'Upflow',
'Uptimia',
'URL Verifier',
'Urlcheckr',
'URLitor',
'urlresolver',
'Urlstat',
'URLTester',
'UrlTrends Ranking Updater',
'URLy Warning',
'URLy\.Warning',
'URL\/Emacs',
'Vacuum',
'Vagabondo',
'VB Project',
'vBSEO',
'VCI',
'via ggpht\.com GoogleImageProxy',
'Virusdie',
'visionutils',
'Visual Rights Group',
'vkShare',
'VoidEYE',
'Voil',
'voltron',
'voyager\/',
'VSAgent\/',
'VSB-TUO\/',
'Vulnbusters Meter',
'VYU2',
'w3af\.org',
'W3C-checklink',
'W3C-mobileOK',
'W3C_Unicorn',
'WAC-OFU',
'WakeletLinkExpander',
'WallpapersHD',
'Wallpapers\/[0-9]+',
'wangling',
'Wappalyzer',
'WatchMouse',
'WbSrch\/',
'WDT\.io',
'Web Auto',
'Web Collage',
'Web Enhancer',
'Web Fetch',
'Web Fuck',
'Web Pix',
'Web Sauger',
'Web spyder',
'Web Sucker',
'web-capture\.net',
'Web-sniffer',
'Webalta',
'Webauskunft',
'WebAuto',
'WebCapture',
'WebClient\/',
'webcollage',
'WebCookies',
'WebCopier',
'WebCorp',
'WebDataStats',
'WebDoc',
'WebEnhancer',
'WebFetch',
'WebFuck',
'WebGazer',
'WebGo IS',
'WebImageCollector',
'WebImages',
'WebIndex',
'webkit2png',
'WebLeacher',
'webmastercoffee',
'webmon ',
'WebPix',
'WebReaper',
'WebSauger',
'webscreenie',
'Webshag',
'Webshot',
'Website Quester',
'websitepulse agent',
'WebsiteQuester',
'Websnapr',
'WebSniffer',
'Webster',
'WebStripper',
'WebSucker',
'webtech\/',
'WebThumbnail',
'Webthumb\/',
'WebWhacker',
'WebZIP',
'WeLikeLinks',
'WEPA',
'WeSEE',
'wf84',
'Wfuzz\/',
'wget',
'WhatCMS',
'WhatsApp',
'WhatsMyIP',
'WhatWeb',
'WhereGoes\?',
'Whibse',
'WhoAPI\/',
'WhoRunsCoinHive',
'Whynder Magnet',
'Windows-RSS-Platform',
'WinHttp-Autoproxy-Service',
'WinHTTP\/',
'WinPodder',
'wkhtmlto',
'wmtips',
'Woko',
'Wolfram HTTPClient',
'woorankreview',
'WordupinfoSearch',
'Word\/',
'worldping-api',
'wotbox',
'WP Engine Install Performance API',
'wpif',
'wprecon\.com survey',
'WPScan',
'wscheck',
'Wtrace',
'WWW-Collector-E',
'WWW-Mechanize',
'WWW::Document',
'WWW::Mechanize',
'WWWOFFLE',
'www\.monitor\.us',
'x09Mozilla',
'x22Mozilla',
'XaxisSemanticsClassifier',
'XenForo\/',
'Xenu Link Sleuth',
'XING-contenttabreceiver',
'xpymep([0-9]?)\.exe',
'Y!J-[A-Z][A-Z][A-Z]',
'Yaanb',
'yacy',
'Yahoo Link Preview',
'YahooCacheSystem',
'YahooMailProxy',
'YahooYSMcm',
'YandeG',
'Yandex(?!Search)',
'yanga',
'yeti',
'Yo-yo',
'Yoleo Consumer',
'yomins\.com',
'yoogliFetchAgent',
'YottaaMonitor',
'Your-Website-Sucks',
'yourls\.org',
'YoYs\.net',
'YP\.PL',
'Zabbix',
'Zade',
'Zao',
'Zauba',
'Zemanta Aggregator',
'Zend\\Http\\Client',
'Zend_Http_Client',
'Zermelo',
'Zeus ',
'zgrab',
'ZnajdzFoto',
'ZnHTTP',
'Zombie\.js',
'Zoom\.Mac',
'ZoteroTranslationServer',
'ZyBorg',
'[a-z0-9\-_]*(bot|crawl|archiver|transcoder|spider|uptime|validator|fetcher|cron|checker|reader|extractor|monitoring|analyzer|scraper)'
];
}
/**
* Return the list of strings to remove from the user agent before running the crawler regex.
*
* @return array
*/
public function get_exclusions_list() {
return [
'Safari.[\d\.]*',
'Firefox.[\d\.]*',
' Chrome.[\d\.]*',
'Chromium.[\d\.]*',
'MSIE.[\d\.]',
'Opera\/[\d\.]*',
'Mozilla.[\d\.]*',
'AppleWebKit.[\d\.]*',
'Trident.[\d\.]*',
'Windows NT.[\d\.]*',
'Android [\d\.]*',
'Macintosh.',
'Ubuntu',
'Linux',
'[ ]Intel',
'Mac OS X [\d_]*',
'(like )?Gecko(.[\d\.]*)?',
'KHTML,',
'CriOS.[\d\.]*',
'CPU iPhone OS ([0-9_])* like Mac OS X',
'CPU OS ([0-9_])* like Mac OS X',
'iPod',
'compatible',
'x86_..',
'i686',
'x64',
'X11',
'rv:[\d\.]*',
'Version.[\d\.]*',
'WOW64',
'Win64',
'Dalvik.[\d\.]*',
' \.NET CLR [\d\.]*',
'Presto.[\d\.]*',
'Media Center PC',
'BlackBerry',
'Build',
'Opera Mini\/\d{1,2}\.\d{1,2}\.[\d\.]*\/\d{1,2}\.',
'Opera',
' \.NET[\d\.]*',
'cubot',
'; M bot',
'; CRONO',
'; B bot',
'; IDbot',
'; ID bot',
'; POWER BOT',
'OCTOPUS-CORE',
'htc_botdugls',
'super\/\d+\/Android\/\d+',
];
}
/**
* Return all possible HTTP headers that represent the User-Agent string.
*
* @return array
*/
public function get_headers_list() {
return [
// The default User-Agent string.
'HTTP_USER_AGENT',
// Header can occur on devices using Opera Mini.
'HTTP_X_OPERAMINI_PHONE_UA',
// Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
'HTTP_X_DEVICE_USER_AGENT',
'HTTP_X_ORIGINAL_USER_AGENT',
'HTTP_X_SKYFIRE_PHONE',
'HTTP_X_BOLT_PHONE_UA',
'HTTP_DEVICE_STOCK_UA',
'HTTP_X_UCBROWSER_DEVICE_UA',
// Sometimes, bots (especially Google) use a genuine user agent, but fill this header in with their email address
'HTTP_FROM',
'HTTP_X_SCANNER' // Seen in use by Netsparker
];
}
}
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Dashboard class.
*
* @class Cookie_Notice_Dashboard
*/
class Cookie_Notice_Dashboard {
/**
* Class constructor.
*
* @return void
*/
public function __construct() {
// actions
add_action( 'wp_dashboard_setup', [ $this, 'wp_dashboard_setup' ], 11 );
add_action( 'wp_network_dashboard_setup', [ $this, 'wp_dashboard_setup' ], 11 );
add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts_styles' ] );
// site status
add_filter( 'site_status_tests', [ $this, 'add_tests' ] );
}
/**
* Initialize widget.
*
* @global array $wp_meta_boxes
*
* @return void
*/
public function wp_dashboard_setup() {
// filter user_can_see_stats
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
return;
// get main instance
$cn = Cookie_Notice();
// check when to hide widget
if ( is_multisite() ) {
// site dashboard
if ( current_action() === 'wp_dashboard_setup' && $cn->is_plugin_network_active() && $cn->network_options['global_override'] )
return;
// network dashboard
if ( current_action() === 'wp_network_dashboard_setup' ) {
if ( $cn->is_plugin_network_active() ) {
if ( ! $cn->network_options['global_override'] )
return;
} else
return;
}
}
// check is it network admin
if ( $cn->is_network_admin() )
$dashboard_key = 'dashboard-network';
else
$dashboard_key = 'dashboard';
global $wp_meta_boxes;
// set widget key
$widget_key = 'cn_dashboard_stats';
// add dashboard chart widget
wp_add_dashboard_widget( $widget_key, __( 'Cookie Compliance', 'cookie-notice' ), [ $this, 'dashboard_widget' ] );
// get widgets
$normal_dashboard = $wp_meta_boxes[$dashboard_key]['normal']['core'];
// attempt to place the widget at the top
$widget_instance = [
$widget_key => $normal_dashboard[ $widget_key ]
];
// remove new widget
unset( $normal_dashboard[ $widget_key ] );
// merge widgets
$sorted_dashboard = array_merge( $widget_instance, $normal_dashboard );
// update widgets
$wp_meta_boxes[$dashboard_key]['normal']['core'] = $sorted_dashboard;
}
/**
* Enqueue admin scripts and styles.
*
* @param string $pagenow
* @return void
*/
public function admin_scripts_styles( $pagenow ) {
if ( $pagenow !== 'index.php' )
return;
// filter user_can_see_stats
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
return;
// get main instance
$cn = Cookie_Notice();
$date_format = get_option( 'date_format' );
if ( is_multisite() && $cn->is_network_admin() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] )
$analytics = get_site_option( 'cookie_notice_app_analytics', [] );
else
$analytics = get_option( 'cookie_notice_app_analytics', [] );
// styles
wp_enqueue_style( 'cookie-notice-admin-dashboard', COOKIE_NOTICE_URL . '/css/admin-dashboard.css', [], $cn->defaults['version'] );
wp_enqueue_style( 'cookie-notice-microtip', COOKIE_NOTICE_URL . '/assets/microtip/microtip.min.css', [], $cn->defaults['version'] );
// bail if compliance is not active
if ( $cn->get_status() !== 'active' )
return;
// scripts
wp_register_script( 'cookie-notice-admin-chartjs', COOKIE_NOTICE_URL . '/assets/chartjs/chart.min.js', [ 'jquery' ], '4.3.2', true );
wp_enqueue_script( 'cookie-notice-admin-dashboard', COOKIE_NOTICE_URL . '/js/admin-dashboard.js', [ 'jquery', 'cookie-notice-admin-chartjs' ], $cn->defaults['version'], true );
// cycle usage data
$cycle_usage = [
'threshold' => ! empty( $analytics['cycleUsage']->threshold ) ? (int) $analytics['cycleUsage']->threshold : 0,
'visits' => ! empty( $analytics['cycleUsage']->visits ) ? (int) $analytics['cycleUsage']->visits : 0
];
// available visits, -1 for no pro plans
$cycle_usage['visits_available'] = $cycle_usage['threshold'] ? $cycle_usage['threshold'] - $cycle_usage['visits'] : -1;
// get used threshold info
if ( $cycle_usage['threshold'] > 0 ) {
$threshold_used = ( $cycle_usage['visits'] / $cycle_usage['threshold'] ) * 100;
if ( $threshold_used > 100 )
$threshold_used = 100;
} else
$threshold_used = 0;
$chartdata = [
'usage' => [
'type' => 'doughnut',
'data' => [
'labels' => [
_x( 'Used', 'threshold limit', 'cookie-notice' ),
_x( 'Free', 'threshold limit', 'cookie-notice' )
],
'datasets' => [
[
'data' => [ $cycle_usage['visits'], $cycle_usage['visits_available'] ],
'backgroundColor' => [
'rgb(32, 193, 158)',
'rgb(235, 233, 235)'
]
]
]
]
],
'consent-activity' => [
'type' => 'line'
]
];
// warning usage color
if ( $threshold_used > 80 && $threshold_used < 100 )
$chartdata['usage']['data']['datasets'][0]['backgroundColor'][0] = 'rgb(255, 193, 7)';
// danger usage color
elseif ( $threshold_used == 100 )
$chartdata['usage']['data']['datasets'][0]['backgroundColor'][0] = 'rgb(220, 53, 69)';
$data = [
'labels' => [],
'datasets' => [
0 => [
'label' => sprintf( __( 'Level %s', 'cookie-notice' ), 1 ),
'data' => [],
'fill' => true,
'backgroundColor' => 'rgba(196, 196, 196, 0.3)',
'borderColor' => 'rgba(196, 196, 196, 1)',
'borderWidth' => 1.2,
'borderDash' => [],
'pointBorderColor' => 'rgba(196, 196, 196, 1)',
'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
'pointBorderWidth' => 1.2
],
1 => [
'label' => sprintf( __( 'Level %s', 'cookie-notice' ), 2 ),
'data' => [],
'fill' => true,
'backgroundColor' => 'rgba(213, 181, 101, 0.3)',
'borderColor' => 'rgba(213, 181, 101, 1)',
'borderWidth' => 1.2,
'borderDash' => [],
'pointBorderColor' => 'rgba(213, 181, 101, 1)',
'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
'pointBorderWidth' => 1.2
],
2 => [
'label' => sprintf( __( 'Level %s', 'cookie-notice' ), 3 ),
'data' => [],
'fill' => true,
'backgroundColor' => 'rgba(152, 145, 177, 0.3)',
'borderColor' => 'rgba(152, 145, 177, 1)',
'borderWidth' => 1.2,
'borderDash' => [],
'pointBorderColor' => 'rgba(152, 145, 177, 1)',
'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
'pointBorderWidth' => 1.2
]
]
];
// generate chart days
$chart_date_format = 'j/m';
for ( $i = 30; $i >= 0; $i-- ) {
// set label
$data['labels'][] = date( $chart_date_format, strtotime( '-'. $i .' days' ) );
// reset datasets
$data['datasets'][0]['data'][] = 0;
$data['datasets'][1]['data'][] = 0;
$data['datasets'][2]['data'][] = 0;
}
if ( ! empty( $analytics['consentActivities'] ) && is_array( $analytics['consentActivities'] ) ) {
// set consent records in charts days
foreach ( $analytics['consentActivities'] as $index => $entry ) {
$time = date_i18n( $chart_date_format, strtotime( $entry->eventdt ) );
$i = array_search( $time, $data['labels'] );
if ( $i )
$data['datasets'][(int) $entry->consentlevel - 1]['data'][$i] = (int) $entry->totalrecd;
}
}
$chartdata['consent-activity']['data'] = $data;
// prepare script data
$script_data = [
'ajaxURL' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'cn-dashboard-widget' ),
'nonceUser' => wp_create_nonce( 'cn-dashboard-user-options' ),
'charts' => $chartdata
];
wp_add_inline_script( 'cookie-notice-admin-dashboard', 'var cnDashboardArgs = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
}
/**
* Render dashboard widget.
*
* @return void
*/
public function dashboard_widget() {
// get main instance
$cn = Cookie_Notice();
if ( $cn->is_network_admin() )
$upgrade_url = network_admin_url( 'admin.php?page=cookie-notice&welcome=1' );
else
$upgrade_url = admin_url( 'admin.php?page=cookie-notice&welcome=1' );
$html = '';
// compliance active, display chart
if ( $cn->get_status() === 'active' ) {
// get user options
$user_options = get_user_meta( get_current_user_id(), 'pvc_dashboard', true );
// empty options?
if ( empty( $user_options ) || ! is_array( $user_options ) )
$user_options = [];
// sanitize options
$user_options = map_deep( $user_options, 'sanitize_text_field' );
// get menu items
$menu_items = ! empty( $user_options['menu_items'] ) ? $user_options['menu_items'] : [];
$items = [
[
'id' => 'visits',
'title' => esc_html__( 'Traffic Overview', 'cookie-notice' ),
'description' => esc_html__( 'Displays the general visits information for your domain.', 'cookie-notice' )
],
[
'id' => 'consent-activity',
'title' => esc_html__( 'Consent Activity', 'cookie-notice' ),
'description' => esc_html__( 'Displays the chart of the domain consent activity in the last 30 days.', 'cookie-notice' )
]
];
$html .= '
<div id="cn-dashboard-accordion" class="cn-accordion">';
foreach ( $items as $item ) {
$html .= $this->widget_item( $item, $menu_items );
}
$html .= '
</div>';
// compliance inactive, display image
} else {
$html .= '
<div id="cn-dashboard-accordion" class="cn-accordion cn-widget-block">
<img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-compliance-widget.png" alt="Cookie Compliance widget" />
<div id="cn-dashboard-upgrade">
<div id="cn-dashboard-modal">
<h2>' . esc_html__( 'View consent activity inside WordPress Dashboard', 'cookie-notice' ) . '</h2>
<p>' . esc_html__( 'Display information about the visits.', 'cookie-notice' ) . '</p>
<p>' . esc_html__( 'Get Consent logs data for the last 30 days.', 'cookie-notice' ) . '</p>
<p>' . esc_html__( 'Enable consent purpose categories, automatic cookie blocking and more.', 'cookie-notice' ) . '</p>
<p><a href="' . esc_url( $upgrade_url ) . '" class="button button-primary button-hero cn-button">' . esc_html__( 'Upgrade to Cookie Compliance', 'cookie-notice' ) . '</a></p>
</div>
</div>
</div>';
}
// allows a list of html entities such as
$allowed_html = wp_kses_allowed_html( 'post' );
$allowed_html['canvas'] = [
'id' => true,
'height' => true
];
echo wp_kses( $html, $allowed_html );
}
/**
* Generate dashboard widget item HTML.
*
* @param array $item
* @param array $menu_items
* @return string
*/
public function widget_item( $item, $menu_items ) {
return '
<div id="cn-' . esc_attr( $item['id'] ) . '" class="cn-accordion-item' . ( in_array( $item['id'], $menu_items, true ) ? ' cn-collapsed' : '' ) . '">
<div class="cn-accordion-header">
<div class="cn-accordion-toggle"><span class="cn-accordion-title">' . esc_html( $item['title'] ) . '</span><span class="cn-tooltip" aria-label="' . esc_attr( $item['description'] ) . '" data-microtip-position="top" data-microtip-size="large" role="tooltip"><span class="cn-tooltip-icon"></span></span></div>
</div>
<div class="cn-accordion-content">
<div class="cn-dashboard-container">
<div class="cn-data-container">
' . $this->widget_item_content( $item['id'] ) . '
<span class="spinner"></span>
</div>
</div>
</div>
</div>';
}
/**
* Generate dashboard widget item content HTML.
*
* @param array $item
* @return void
*/
public function widget_item_content( $item ) {
$html = '';
switch ( $item ) {
case 'visits':
// get main instance
$cn = Cookie_Notice();
$date_format = get_option( 'date_format' );
// get analytics data options
if ( is_multisite() && $cn->is_network_admin() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] )
$analytics = get_site_option( 'cookie_notice_app_analytics', [] );
else
$analytics = get_option( 'cookie_notice_app_analytics', [] );
// thirty days data
$thirty_days_usage = [
'visits' => ! empty( $analytics['thirtyDaysUsage']->visits ) ? (int) $analytics['thirtyDaysUsage']->visits : 0,
'consents' => 0,
'consents_updated' => ! empty( $analytics['lastUpdated'] ) ? date_create_from_format( 'Y-m-d H:i:s', $analytics['lastUpdated'] ) : date_create_from_format( 'Y-m-d H:i:s', current_time( 'mysql', true ) )
];
// set current timezone
$current_timezone = new DateTimeZone( $this->timezone_string() );
// update date
$thirty_days_usage['consents_updated']->setTimezone( $current_timezone );
if ( ! empty( $analytics['consentActivities'] ) ) {
foreach ( $analytics['consentActivities'] as $index => $entry ) {
$thirty_days_usage['consents'] += (int) $entry->totalrecd;
}
}
// cycle usage data
$cycle_usage = [
'threshold' => ! empty( $analytics['cycleUsage']->threshold ) ? (int) $analytics['cycleUsage']->threshold : 0,
'visits' => ! empty( $analytics['cycleUsage']->visits ) ? (int) $analytics['cycleUsage']->visits : 0,
'days_to_go' => ! empty( $analytics['cycleUsage']->daysToGo ) ? (int) $analytics['cycleUsage']->daysToGo : 0,
'start_date' => ! empty( $analytics['cycleUsage']->startDate ) ? date_create_from_format( '!Y-m-d', $analytics['cycleUsage']->startDate ) : ''
];
// get used threshold info
if ( $cycle_usage['threshold'] > 0 ) {
$threshold_used = ( $cycle_usage['visits'] / $cycle_usage['threshold'] ) * 100;
if ( $threshold_used > 100 )
$threshold_used = 100;
} else
$threshold_used = 0;
$html .= '
<div id="cn-dashboard-' . esc_attr( $item ) . '">
<div id="cn-' . esc_attr( $item ) . '-infobox-traffic-overview" class="cn-infobox-container">
<div id="cn-' . esc_attr( $item ) . '-infobox-visits" class="cn-infobox">
<div class="cn-infobox-title">' . esc_html__( 'Total Visits', 'cookie-notice' ) . '</div>
<div class="cn-infobox-number">' . esc_html( number_format_i18n( $thirty_days_usage['visits'], 0 ) ) . '</div>
<div class="cn-infobox-subtitle">' . esc_html__( 'Last 30 days', 'cookie-notice' ) . '</div>
</div>
<div id="cn-' . esc_attr( $item ) . '-infobox-consents" class="cn-infobox">
<div class="cn-infobox-title">' . esc_html__( 'Consent Logs', 'cookie-notice' ) . '</div>
<div class="cn-infobox-number">' . esc_html( number_format_i18n( $thirty_days_usage['consents'], 0 ) ) . '</div>
<div class="cn-infobox-subtitle">' . esc_html( sprintf( __( 'Updated %s', 'cookie-notice' ), date_i18n( $date_format, $thirty_days_usage['consents_updated']->getTimestamp() ) ) ) . '</div>
</div>
</div>';
if ( $cycle_usage['threshold'] ) {
$usage_class = 'success';
// warning usage color
if ( $threshold_used > 80 && $threshold_used < 100 )
$usage_class = 'warning';
// danger usage color
elseif ( $threshold_used === 100 )
$usage_class = 'danger';
$html .= '
<div id="cn-' . esc_attr( $item ) . '-infobox-traffic-usage" class="cn-infobox-container">
<div id="cn-' . esc_attr( $item ) . '-infobox-limits" class="cn-infobox">
<div class="cn-infobox-title">' . esc_html__( 'Traffic Usage', 'cookie-notice' ) . '</div>
<div class="cn-infobox-number cn-text-' . esc_attr( $usage_class ) . '">' . esc_html( number_format_i18n( $threshold_used, 1 ) ) . ' %</div>
<div class="cn-infobox-subtitle">
<p>' . esc_html( sprintf( __( 'Visits usage: %1$s / %2$s', 'cookie-notice' ), $cycle_usage['visits'], $cycle_usage['threshold'] ) ) . '</p>
<p>' . esc_html( sprintf( __( 'Cycle started: %s', 'cookie-notice' ), date_i18n( $date_format, $cycle_usage['start_date']->getTimestamp() ) ) ) . '</p>
<p>' . esc_html( sprintf( __( 'Days to go: %s', 'cookie-notice' ), $cycle_usage['days_to_go'] ) ) . '</p>
</div>
</div>
<div id="cn-' . esc_attr( $item ) . '-chart-limits" class="cn-infobox cn-chart-container">
<canvas id="cn-usage-chart" style="height: 100px"></canvas>
</div>';
/*
<div id="cn-' . $item . '-traffic-notice" class="cn-infobox-notice cn-traffic-' . $usage_class . '">
<p><b>' . __( 'Your domain has exceeded 90% of the usage limit.', 'cookie-notice' ) . '</b></p>
<p>' . sprintf(__( 'The banner will still display properly and consent record will be set in the browser. However the Autoblocking will be disabled and Consent Records will not be stored in the application until the current visits cycle resets (in %s days).', 'cookie-notice' ), $cycle_usage['days_to_go'] ) . '</p>
</div>
*/
$html .= '
</div>';
}
$html .= '
</div>';
break;
case 'consent-activity':
$html .= '
<div id="cn-dashboard-' . esc_attr( $item ) . '">
<div id="cn-' . esc_attr( $item ) . '-chart-container cn-chart-container">
<canvas id="cn-' . esc_attr( $item ) . '-chart" style="height: 300px"></canvas>
</div>
</div>';
break;
}
return $html;
}
/**
* Add site test.
*
* @param array $tests
* @return array
*/
public function add_tests( $tests ) {
$tests['direct']['cookie_compliance_status'] = [
'label' => esc_html__( 'Cookie Compliance Status', 'cookie-notice' ),
'test' => [ $this, 'test_cookie_compliance' ]
];
return $tests;
}
/**
* Test for Cookie Compliance.
*
* @return array|void
*/
public function test_cookie_compliance() {
if ( Cookie_Notice()->get_status() !== 'active' ) {
return [
'label' => esc_html__( 'Your site does not have Cookie Compliance', 'cookie-notice' ),
'status' => 'recommended',
'description' => esc_html__( "Run Compliance Check to determine your site's compliance with updated data processing and consent rules under GDPR, CCPA and other international data privacy laws.", 'cookie-notice' ),
'actions' => sprintf( '<p><a href="%s" target="_blank" rel="noopener noreferrer">%s</a></p>', admin_url( 'admin.php?page=cookie-notice&welcome=1' ), esc_html__( 'Run Compliance Check', 'cookie-notice' ) ),
'test' => 'cookie_compliance_status',
'badge' => [
'label' => esc_html__( 'Cookie Notice', 'cookie-notice' ),
'color' => 'blue'
]
];
}
}
/**
* Retrieve the timezone of the site as a string.
*
* @return string
*/
public function timezone_string() {
if ( function_exists( 'wp_timezone_string' ) )
return wp_timezone_string();
$timezone_string = get_option( 'timezone_string' );
if ( $timezone_string )
return $timezone_string;
$offset = (float) get_option( 'gmt_offset' );
$hours = (int) $offset;
$minutes = ( $offset - $hours );
$sign = ( $offset < 0 ) ? '-' : '+';
$abs_hour = abs( $hours );
$abs_mins = abs( $minutes * 60 );
$tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
return $tz_offset;
}
}
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Frontend class.
*
* @class Cookie_Notice_Frontend
*/
class Cookie_Notice_Frontend {
/**
* Class constructor.
*
* @return void
*/
public function __construct() {
// actions
add_action( 'init', [ $this, 'early_init' ], 9 );
add_action( 'wp', [ $this, 'init' ] );
}
/**
* Early initialization.
*
* @return void
*/
public function early_init() {
// get main instance
$cn = Cookie_Notice();
// cookie compliance initialization
if ( $cn->get_status() === 'active' && $cn->options['general']['caching_compatibility'] ) {
// litespeed cache 3.0.0+ compatibility
if ( cn_is_plugin_active( 'litespeed' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/litespeed-cache/litespeed-cache.php' );
// sg optimizer 5.5.0+ compatibility
if ( cn_is_plugin_active( 'sgoptimizer' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/sg-optimizer/sg-optimizer.php' );
// wp rocket 3.8.0+ compatibility
if ( cn_is_plugin_active( 'wprocket' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/wp-rocket/wp-rocket.php' );
}
}
/**
* Initialize plugin.
*
* @return void
*/
public function init() {
if ( is_admin() )
return;
// purge cache
if ( isset( $_GET['hu_purge_cache'] ) )
$this->purge_cache();
// get main instance
$cn = Cookie_Notice();
// is banner allowed to display?
if ( $this->maybe_display_banner() ) {
// cookie compliance initialization
if ( $cn->get_status() === 'active' ) {
add_action( 'wp_head', [ $this, 'add_cookie_compliance' ], 0 );
// is caching compatibility active?
if ( $cn->options['general']['caching_compatibility'] ) {
// autoptimize 2.4.0+
if ( cn_is_plugin_active( 'autoptimize' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/autoptimize/autoptimize.php' );
}
// is blocking active?
if ( $cn->options['general']['app_blocking'] ) {
// contact form 7 5.1.0+ recaptcha v3 compatibility
if ( cn_is_plugin_active( 'contactform7' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/contact-form-7/contact-form-7.php' );
}
// cookie notice initialization
} else {
// actions
add_action( 'wp_enqueue_scripts', [ $this, 'wp_enqueue_notice_scripts' ] );
add_action( 'wp_head', [ $this, 'wp_print_header_scripts' ] );
add_action( 'wp_print_footer_scripts', [ $this, 'wp_print_footer_scripts' ] );
add_action( 'wp_footer', [ $this, 'add_cookie_notice' ], 1000 );
// filters
add_filter( 'script_loader_tag', [ $this, 'wp_enqueue_script_async' ], 10, 3 );
add_filter( 'body_class', [ $this, 'change_body_class' ] );
}
}
}
/**
* Whether banner is allowed to display.
*
* @return bool
*/
public function maybe_display_banner() {
// get main instance
$cn = Cookie_Notice();
// is cookie compliance active?
if ( $cn->get_status() === 'active' ) {
// elementor 1.3.0+ compatibility, needed early for is_preview_mode
if ( cn_is_plugin_active( 'elementor' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/elementor/elementor.php' );
}
// is it preview mode?
if ( $this->is_preview_mode() )
return false;
// is it a bot?
if ( $cn->bot_detect->is_crawler() )
return false;
// final check for conditional display
return $this->check_conditions();
}
/**
* Whether preview mode is active.
*
* @return bool
*/
public function is_preview_mode() {
return isset( $_GET['cn_preview_mode'] ) || is_preview() || is_customize_preview() || defined( 'IFRAME_REQUEST' ) || ( function_exists( 'wp_is_json_request' ) && wp_is_json_request() ) || apply_filters( 'cn_is_preview_mode', false );
}
/**
* Check whether banner should be displayed based on specified conditions.
*
* @return bool
*/
public function check_conditions() {
// get main instance
$cn = Cookie_Notice();
if ( ! $cn->options['general']['conditional_active'] )
return true;
// get conditions
$rules = $cn->options['general']['conditional_rules'];
// set access type
$access_type = $cn->options['general']['conditional_display'] === 'show';
// get object
$object = get_queried_object();
// no rules?
if ( empty( $rules ) )
$final_access = true;
else {
// check the rules
foreach( $rules as $index => $group ) {
$give_group_access = true;
foreach ( $group as $rule ) {
$give_rule_access = false;
switch ( $rule['param'] ) {
case 'page_type':
if ( ( $rule['operator'] === 'equal' && $rule['value'] === 'front' && is_front_page() ) || ( $rule['operator'] === 'not_equal' && $rule['value'] === 'front' && ! is_front_page() ) || ( $rule['operator'] === 'equal' && $rule['value'] === 'home' && is_home() ) || ( $rule['operator'] === 'not_equal' && $rule['value'] === 'home' && ! is_home() ) )
$give_rule_access = true;
break;
case 'page':
if ( ( $rule['operator'] === 'equal' && ! empty( $object ) && is_page( $object->ID ) && (int) $object->ID === (int) $rule['value'] ) || ( $rule['operator'] === 'not_equal' && ( empty( $object ) || ! is_page() || ( is_page() && ! empty( $object ) && $object->ID !== (int) $rule['value'] ) ) ) )
$give_rule_access = true;
break;
case 'post_type':
if ( ( $rule['operator'] === 'equal' && is_singular( $rule['value'] ) ) || ( $rule['operator'] === 'not_equal' && ! is_singular( $rule['value'] ) ) )
$give_rule_access = true;
break;
case 'post_type_archive':
if ( ( $rule['operator'] === 'equal' && is_post_type_archive( $rule['value'] ) ) || ( $rule['operator'] === 'not_equal' && ! is_post_type_archive( $rule['value'] ) ) )
$give_rule_access = true;
break;
case 'user_type':
if ( ( $rule['operator'] === 'equal' && $rule['value'] === 'logged_in' && is_user_logged_in() ) || ( $rule['operator'] === 'equal' && $rule['value'] === 'guest' && ! is_user_logged_in() ) || ( $rule['operator'] === 'not_equal' && $rule['value'] === 'logged_in' && ! is_user_logged_in() ) || ( $rule['operator'] === 'not_equal' && $rule['value'] === 'guest' && is_user_logged_in() ) )
$give_rule_access = true;
break;
}
// condition failed?
if ( ! $give_rule_access ) {
// group failed
$give_group_access = false;
// finish group checking
break;
}
}
// whole group successful?
if ( $give_group_access ) {
// set final access
$final_access = $access_type;
// finish rules checking
break;
} else
$final_access = ! $access_type;
}
}
return (bool) apply_filters( 'cn_conditional_display', $final_access, $object );
}
/**
* Run Cookie Compliance.
*
* @return void
*/
public function add_cookie_compliance() {
// get main instance
$cn = Cookie_Notice();
// get site language
$locale = get_locale();
$locale_code = explode( '_', $locale );
// exceptions, norwegian
if ( in_array( $locale_code, [ 'nb', 'nn' ] ) )
$locale_code = 'no';
$options = apply_filters(
'cn_cookie_compliance_args',
[
'appID' => $cn->options['general']['app_id'],
'currentLanguage' => $locale_code[0],
'blocking' => ! is_user_logged_in() ? $cn->options['general']['app_blocking'] : false,
'globalCookie' => is_multisite() && $cn->options['general']['global_cookie'] && is_subdomain_install()
]
);
// debug mode
if ( $cn->options['general']['debug_mode'] )
$options['debugMode'] = true;
// custom scripts?
if ( $cn->options['general']['app_blocking'] ) {
if ( is_multisite() && $cn->is_network_admin() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] )
$blocking = get_site_option( 'cookie_notice_app_blocking' );
else
$blocking = get_option( 'cookie_notice_app_blocking' );
$providers = ! empty( $blocking[ 'providers'] ) && is_array( $blocking[ 'providers'] ) ? $this->get_custom_items( $blocking[ 'providers'] ) : [];
$patterns = ! empty( $blocking[ 'patterns'] ) && is_array( $blocking[ 'patterns'] ) ? $this->get_custom_items( $blocking[ 'patterns' ] ) : [];
$options['customProviders'] = ! empty( $providers ) ? $providers : [];
$options['customPatterns'] = ! empty( $patterns ) ? $patterns : [];
}
// message output
$output = '
<!-- Cookie Compliance -->
<script type="text/javascript">
var huOptions = ' . wp_json_encode( $options ) . ';
</script>
<script type="text/javascript" src="' . esc_url( $cn->get_url( 'widget' ) ) . '"></script>';
echo apply_filters( 'cn_cookie_compliance_output', $output, $options );
}
/**
* Cookie notice output.
*
* @return void
*/
public function add_cookie_notice() {
// get main instance
$cn = Cookie_Notice();
// WPML >= 3.2
if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ) {
$cn->options['general']['message_text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['message_text'], 'Cookie Notice', 'Message in the notice' );
$cn->options['general']['accept_text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['accept_text'], 'Cookie Notice', 'Button text' );
$cn->options['general']['refuse_text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['refuse_text'], 'Cookie Notice', 'Refuse button text' );
$cn->options['general']['revoke_message_text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['revoke_message_text'], 'Cookie Notice', 'Revoke message text' );
$cn->options['general']['revoke_text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['revoke_text'], 'Cookie Notice', 'Revoke button text' );
$cn->options['general']['see_more_opt']['text'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['see_more_opt']['text'], 'Cookie Notice', 'Privacy policy text' );
$cn->options['general']['see_more_opt']['link'] = apply_filters( 'wpml_translate_single_string', $cn->options['general']['see_more_opt']['link'], 'Cookie Notice', 'Custom link' );
// WPML and Polylang compatibility
} elseif ( function_exists( 'icl_t' ) ) {
$cn->options['general']['message_text'] = icl_t( 'Cookie Notice', 'Message in the notice', $cn->options['general']['message_text'] );
$cn->options['general']['accept_text'] = icl_t( 'Cookie Notice', 'Button text', $cn->options['general']['accept_text'] );
$cn->options['general']['refuse_text'] = icl_t( 'Cookie Notice', 'Refuse button text', $cn->options['general']['refuse_text'] );
$cn->options['general']['revoke_message_text'] = icl_t( 'Cookie Notice', 'Revoke message text', $cn->options['general']['revoke_message_text'] );
$cn->options['general']['revoke_text'] = icl_t( 'Cookie Notice', 'Revoke button text', $cn->options['general']['revoke_text'] );
$cn->options['general']['see_more_opt']['text'] = icl_t( 'Cookie Notice', 'Privacy policy text', $cn->options['general']['see_more_opt']['text'] );
$cn->options['general']['see_more_opt']['link'] = icl_t( 'Cookie Notice', 'Custom link', $cn->options['general']['see_more_opt']['link'] );
}
if ( $cn->options['general']['see_more_opt']['link_type'] === 'page' ) {
// multisite with global override?
if ( is_multisite() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
// get main site id
$main_site_id = get_main_site_id();
// switch to main site
switch_to_blog( $main_site_id );
// update page id for current language if needed
if ( function_exists( 'icl_object_id' ) )
$cn->options['general']['see_more_opt']['id'] = icl_object_id( $cn->options['general']['see_more_opt']['id'], 'page', true );
// get main site privacy policy link
$permalink = get_permalink( $cn->options['general']['see_more_opt']['id'] );
// restore current site
restore_current_blog();
} else {
// update page id for current language if needed
if ( function_exists( 'icl_object_id' ) )
$cn->options['general']['see_more_opt']['id'] = icl_object_id( $cn->options['general']['see_more_opt']['id'], 'page', true );
// get privacy policy link
$permalink = get_permalink( $cn->options['general']['see_more_opt']['id'] );
}
}
// get cookie container args
$options = apply_filters( 'cn_cookie_notice_args', [
'position' => $cn->options['general']['position'],
'css_class' => $cn->options['general']['css_class'],
'button_class' => 'cn-button',
'colors' => $cn->options['general']['colors'],
'message_text' => $cn->options['general']['message_text'],
'accept_text' => $cn->options['general']['accept_text'],
'refuse_text' => $cn->options['general']['refuse_text'],
'revoke_message_text' => $cn->options['general']['revoke_message_text'],
'revoke_text' => $cn->options['general']['revoke_text'],
'refuse_opt' => $cn->options['general']['refuse_opt'],
'revoke_cookies' => $cn->options['general']['revoke_cookies'],
'see_more' => $cn->options['general']['see_more'],
'see_more_opt' => $cn->options['general']['see_more_opt'],
'link_target' => $cn->options['general']['link_target'],
'link_position' => $cn->options['general']['link_position'],
'aria_label' => 'Cookie Notice'
] );
// message output
$output = '
<!-- Cookie Notice plugin v' . esc_attr( $cn->defaults['version'] ) . ' by Hu-manity.co https://hu-manity.co/ -->
<div id="cookie-notice" role="dialog" class="cookie-notice-hidden cookie-revoke-hidden cn-position-' . esc_attr( $options['position'] ) . '" aria-label="' . esc_attr( $options['aria_label'] ) . '" style="background-color: __CN_BG_COLOR__">'
. '<div class="cookie-notice-container" style="color: ' . esc_attr( $options['colors']['text'] ) . '">'
. '<span id="cn-notice-text" class="cn-text-container">'. ( $options['see_more'] ? do_shortcode( $options['message_text'] ) : $options['message_text'] ) . '</span>'
. '<span id="cn-notice-buttons" class="cn-buttons-container"><a href="#" id="cn-accept-cookie" data-cookie-set="accept" class="cn-set-cookie ' . esc_attr( $options['button_class'] ) . ( $options['css_class'] !== '' ? ' cn-button-custom ' . esc_attr( $options['css_class'] ) : '' ) . '" aria-label="' . esc_attr( $options['accept_text'] ) . '"' . ( $options['css_class'] == '' ? ' style="background-color: ' . esc_attr( $options['colors']['button'] ) . '"' : '' ) . '>' . esc_html( $options['accept_text'] ) . '</a>'
. ( $options['refuse_opt'] ? '<a href="#" id="cn-refuse-cookie" data-cookie-set="refuse" class="cn-set-cookie ' . esc_attr( $options['button_class'] ) . ( $options['css_class'] !== '' ? ' cn-button-custom ' . esc_attr( $options['css_class'] ) : '' ) . '" aria-label="' . esc_attr( $options['refuse_text'] ) . '"' . ( $options['css_class'] == '' ? ' style="background-color: ' . esc_attr( $options['colors']['button'] ) . '"' : '' ) . '>' . esc_html( $options['refuse_text'] ) . '</a>' : '' )
. ( $options['see_more'] && $options['link_position'] === 'banner' ? '<a href="' . esc_url( $options['see_more_opt']['link_type'] === 'custom' ? $options['see_more_opt']['link'] : $permalink ) . '" target="' . esc_attr( $options['link_target'] ) . '" id="cn-more-info" class="cn-more-info ' . esc_attr( $options['button_class'] ) . ( $options['css_class'] !== '' ? ' cn-button-custom ' . esc_attr( $options['css_class'] ) : '' ) . '" aria-label="' . esc_attr( $options['see_more_opt']['text'] ) . '"' . ( $options['css_class'] == '' ? ' style="background-color: ' . esc_attr( $options['colors']['button'] ) . '"' : '' ) . '>' . esc_html( $options['see_more_opt']['text'] ) . '</a>' : '' )
. '</span><span id="cn-close-notice" data-cookie-set="accept" class="cn-close-icon" title="' . esc_attr( $options['refuse_text'] ) . '"></span>'
. '</div>
' . ( $options['refuse_opt'] && $options['revoke_cookies'] ?
'<div class="cookie-revoke-container" style="color: ' . esc_attr( $options['colors']['text'] ) . '">'
. ( ! empty( $options['revoke_message_text'] ) ? '<span id="cn-revoke-text" class="cn-text-container">' . $options['revoke_message_text'] . '</span>' : '' )
. '<span id="cn-revoke-buttons" class="cn-buttons-container"><a href="#" class="cn-revoke-cookie ' . esc_attr( $options['button_class'] ) . ( $options['css_class'] !== '' ? ' cn-button-custom ' . esc_attr( $options['css_class'] ) : '' ) . '" aria-label="' . esc_attr( $options['revoke_text'] ) . '"' . ( $options['css_class'] == '' ? ' style="background-color: ' . esc_attr( $options['colors']['button'] ) . '"' : '' ) . '>' . esc_html( $options['revoke_text'] ) . '</a></span>
</div>' : '' ) . '
</div>
<!-- / Cookie Notice plugin -->';
add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
$output = apply_filters( 'cn_cookie_notice_output', wp_kses_post( $output ), $options );
remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
// convert rgb color to hex
$bg_rgb_color = $this->hex2rgb( $options['colors']['bar'] );
// invalid color? use default
if ( $bg_rgb_color === false )
$bg_rgb_color = $this->hex2rgb( $cn->defaults['general']['colors']['bar'] );
// allow rgba background
echo str_replace( '__CN_BG_COLOR__', esc_attr( 'rgba(' . implode( ',', $bg_rgb_color ) . ',' . ( (int) $options['colors']['bar_opacity'] ) * 0.01 . ');' ), $output );
}
/**
* Add new properties to style safe list.
*
* @param array $styles
* @return array
*/
public function allow_style_attributes( $styles ) {
$styles[] = 'display';
return $styles;
}
/**
* Convert HEX to RGB color.
*
* @param string $color
* @return bool|array
*/
public function hex2rgb( $color ) {
if ( ! is_string( $color ) )
return false;
// with hash?
if ( $color[0] === '#' )
$color = substr( $color, 1 );
if ( sanitize_hex_color_no_hash( $color ) !== $color )
return false;
// 6 hex digits?
if ( strlen( $color ) === 6 )
list( $r, $g, $b ) = [ $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] ];
// 3 hex digits?
elseif ( strlen( $color ) === 3 )
list( $r, $g, $b ) = [ $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] ];
else
return false;
return [ 'r' => hexdec( $r ), 'g' => hexdec( $g ), 'b' => hexdec( $b ) ];
}
/**
* Load notice scripts and styles - frontend.
*
* @return void
*/
public function wp_enqueue_notice_scripts() {
// get main instance
$cn = Cookie_Notice();
wp_enqueue_script( 'cookie-notice-front', COOKIE_NOTICE_URL . '/js/front' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.js', [], $cn->defaults['version'], isset( $cn->options['general']['script_placement'] ) && $cn->options['general']['script_placement'] === 'footer' );
// prepare script data
$script_data = [
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'cn_save_cases' ),
'hideEffect' => $cn->options['general']['hide_effect'],
'position' => $cn->options['general']['position'],
'onScroll' => $cn->options['general']['on_scroll'],
'onScrollOffset' => (int) $cn->options['general']['on_scroll_offset'],
'onClick' => $cn->options['general']['on_click'],
'cookieName' => 'cookie_notice_accepted',
'cookieTime' => $cn->settings->times[$cn->options['general']['time']][1],
'cookieTimeRejected' => $cn->settings->times[$cn->options['general']['time_rejected']][1],
'globalCookie' => is_multisite() && $cn->options['general']['global_cookie'] && is_subdomain_install(),
'redirection' => $cn->options['general']['redirection'],
'cache' => defined( 'WP_CACHE' ) && WP_CACHE,
'revokeCookies' => $cn->options['general']['revoke_cookies'],
'revokeCookiesOpt' => $cn->options['general']['revoke_cookies_opt']
];
wp_add_inline_script( 'cookie-notice-front', 'var cnArgs = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
wp_enqueue_style( 'cookie-notice-front', COOKIE_NOTICE_URL . '/css/front' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.css' );
}
/**
* Make a JavaScript Asynchronous.
*
* @param string $tag The original enqueued script tag
* @param string $handle The registered unique name of the script
* @param string $src
* @return string $tag
*/
public function wp_enqueue_script_async( $tag, $handle, $src ) {
if ( $handle === 'cookie-notice-front' )
$tag = str_replace( '<script', '<script async', $tag );
return $tag;
}
/**
* Print non functional JavaScript in body.
*
* @return void
*/
public function wp_print_footer_scripts() {
// get main instance
$cn = Cookie_Notice();
if ( $cn->cookies_accepted() ) {
$scripts = apply_filters( 'cn_refuse_code_scripts_html', $cn->options['general']['refuse_code'], 'body' );
if ( ! empty( $scripts ) )
echo html_entity_decode( wp_kses( $scripts, $cn->get_allowed_html() ) );
}
}
/**
* Print non functional JavaScript in header.
*
* @return void
*/
public function wp_print_header_scripts() {
// get main instance
$cn = Cookie_Notice();
if ( $cn->cookies_accepted() ) {
$scripts = apply_filters( 'cn_refuse_code_scripts_html', $cn->options['general']['refuse_code_head'], 'head' );
if ( ! empty( $scripts ) )
echo html_entity_decode( wp_kses( $scripts, $cn->get_allowed_html() ) );
}
}
/**
* Get custom providers or patterns.
*
* @param array $items
* @return array
*/
public function get_custom_items( $items ) {
$result = [];
if ( ! empty( $items ) && is_array( $items ) ) {
foreach ( $items as $index => $item ) {
if ( isset( $item->IsCustom ) && $item->IsCustom == true ) {
$sanitized_item = [];
foreach ( $item as $key => $value ) {
$sanitized_item[$key] = $this->sanitize_field( $value, $key );
}
$result[] = (object) $sanitized_item;
}
}
}
return $result;
}
/**
* Sanitize field.
*
* @param mixed $value
* @param string $key
* @return mixed
*/
private function sanitize_field( $value, $key ) {
$sanitized_value = $value;
switch ( $key ) {
case 'CategoryID':
$sanitized_value = (int) $value;
break;
case 'IsCustom':
$sanitized_value = (bool) $value;
break;
}
return $sanitized_value;
}
/**
* Add new body classes.
*
* @param array $classes Body classes
* @return array
*/
public function change_body_class( $classes ) {
if ( is_admin() )
return $classes;
if ( Cookie_Notice()->cookies_set() ) {
$classes[] = 'cookies-set';
if ( Cookie_Notice()->cookies_accepted() )
$classes[] = 'cookies-accepted';
else
$classes[] = 'cookies-refused';
} else
$classes[] = 'cookies-not-set';
return $classes;
}
/**
* Purge config cache.
*
* @return void
*/
public function purge_cache() {
// get main instance
$cn = Cookie_Notice();
if ( is_multisite() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
$app_id = $cn->network_options['app_id'];
$app_key = $cn->network_options['app_key'];
} else {
$app_id = $cn->options['general']['app_id'];
$app_key = $cn->options['general']['app_key'];
}
// compliance active only
if ( $app_id !== '' && $app_key !== '' ) {
// request for new config data too
$cn->welcome_api->get_app_config( $app_id, true );
}
}
}
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Check if cookies are accepted.
*
* @return bool Whether cookies are accepted
*/
if ( ! function_exists( 'cn_cookies_accepted' ) ) {
function cn_cookies_accepted() {
return (bool) Cookie_Notice::cookies_accepted();
}
}
/**
* Check if cookies are set.
*
* @return bool Whether cookies are set
*/
if ( ! function_exists( 'cn_cookies_set' ) ) {
function cn_cookies_set() {
return (bool) Cookie_Notice::cookies_set();
}
}
/**
* Get active caching plugins.
*
* @param array $args
* @return array
*/
function cn_get_active_caching_plugins( $args = [] ) {
if ( isset( $args['versions'] ) && $args['versions'] === true )
$version = true;
else
$version = false;
$active_plugins = [];
// autoptimize 2.4.0+
if ( cn_is_plugin_active( 'autoptimize' ) ) {
if ( $version )
$active_plugins['Autoptimize'] = '2.4.0';
else
$active_plugins[] = 'Autoptimize';
}
// litespeed 3.0.0+
if ( cn_is_plugin_active( 'litespeed' ) ) {
if ( $version )
$active_plugins['LiteSpeed Cache'] = '3.0.0';
else
$active_plugins[] = 'LiteSpeed Cache';
}
// siteground optimizer 5.5.0+
if ( cn_is_plugin_active( 'sgoptimizer' ) ) {
if ( $version )
$active_plugins['SiteGround Optimizer'] = '5.5.0';
else
$active_plugins[] = 'SiteGround Optimizer';
}
// wp fastest cache 1.0.0+
if ( cn_is_plugin_active( 'wpfastestcache' ) ) {
if ( $version )
$active_plugins['WP Fastest Cache'] = '1.0.0';
else
$active_plugins[] = 'WP Fastest Cache';
}
// wp rocket 3.8.0+
if ( cn_is_plugin_active( 'wprocket' ) ) {
if ( $version )
$active_plugins['WP Rocket'] = '3.8.0';
else
$active_plugins[] = 'WP Rocket';
}
// wp super cache 1.6.9+
// if ( cn_is_plugin_active( 'wpsupercache' ) ) {
// if ( $version )
// $active_plugins['WP Super Cache'] = '1.6.9';
// else
// $active_plugins[] = 'WP Super Cache';
// }
return $active_plugins;
}
/**
* Check whether specified plugin is active.
*
* @global object $siteground_optimizer_loader
* @global int $wpsc_version
*
* @return bool
*/
function cn_is_plugin_active( $plugin = '' ) {
// no valid plugin?
if ( ! in_array( $plugin, [ 'autoptimize', 'litespeed', 'sgoptimizer', 'wpfastestcache', 'wprocket', 'wpsupercache', 'contactform7', 'elementor' ], true ) )
return false;
global $siteground_optimizer_loader;
global $wpsc_version;
// autoptimize 2.4.0+
if ( $plugin === 'autoptimize' && function_exists( 'autoptimize' ) && defined( 'AUTOPTIMIZE_PLUGIN_VERSION' ) && version_compare( AUTOPTIMIZE_PLUGIN_VERSION, '2.4', '>=' ) )
return true;
// litespeed 3.0.0+
elseif ( $plugin === 'litespeed' && class_exists( 'LiteSpeed\Core' ) && defined( 'LSCWP_CUR_V' ) && version_compare( LSCWP_CUR_V, '3.0', '>=' ) )
return true;
// siteground optimizer 5.5.0+
elseif ( $plugin === 'sgoptimizer' && ! empty( $siteground_optimizer_loader ) && is_object( $siteground_optimizer_loader ) && is_a( $siteground_optimizer_loader, 'SiteGround_Optimizer\Loader\Loader' ) && defined( '\SiteGround_Optimizer\VERSION' ) && version_compare( \SiteGround_Optimizer\VERSION, '5.5', '>=' ) )
return true;
// wp fastest cache 1.0.0+
elseif ( $plugin === 'wpfastestcache' && function_exists( 'wpfc_clear_all_cache' ) )
return true;
// wp rocket 3.8.0+
elseif ( $plugin === 'wprocket' && function_exists( 'rocket_init' ) && defined( 'WP_ROCKET_VERSION' ) && version_compare( WP_ROCKET_VERSION, '3.8', '>=' ) )
return true;
// wp super cache 1.6.9+
// elseif ( $plugin === 'wpsupercache' && ( ( ! empty( $wpsc_version ) && $wpsc_version >= 169 ) || ( defined( 'WPSC_VERSION' ) && version_compare( WPSC_VERSION, '1.6.9', '>=' ) ) ) )
// return true;
// contact form 5.1.0+
elseif ( $plugin === 'contactform7' && class_exists( 'WPCF7' ) && class_exists( 'WPCF7_RECAPTCHA' ) && defined( 'WPCF7_VERSION' ) && version_compare( WPCF7_VERSION, '5.1', '>=' ) )
return true;
// elementor 1.3.0+
elseif ( $plugin === 'elementor' && did_action( 'elementor/loaded' ) && defined( 'ELEMENTOR_VERSION' ) && version_compare( ELEMENTOR_VERSION, '1.3', '>=' ) )
return true;
return false;
}
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules Autoptimize class.
*
* Compatibility since: 2.4.0
*
* @class Cookie_Notice_Modules_Autoptimize
*/
class Cookie_Notice_Modules_Autoptimize {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_filter( 'autoptimize_filter_js_exclude', [ $this, 'exclude' ] );
}
/**
* Exclude JavaScript files or inline code.
*
* @param string $excludes
* @return string
*/
function exclude( $excludes ) {
if ( empty( $excludes ) )
$new_excludes = [];
else {
$new_excludes = explode( ',', $excludes );
$new_excludes = array_filter( $new_excludes );
$new_excludes = array_map( 'trim', $new_excludes );
}
// not found huOptions?
if ( strpos( $excludes, 'huOptions' ) === false )
$new_excludes[] = 'huOptions';
// get widget url
$widget_url = basename( Cookie_Notice()->get_url( 'widget' ) );
// not found widget url?
if ( strpos( $excludes, $widget_url ) === false )
$new_excludes[] = $widget_url;
return implode( ', ', $new_excludes );
}
}
new Cookie_Notice_Modules_Autoptimize();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules Contact Form 7 class.
*
* Compatibility since: 5.1.0 (recaptcha v3 only)
*
* @class Cookie_Notice_Modules_ContactForm7
*/
class Cookie_Notice_Modules_ContactForm7 {
private $service;
/**
* Constructor.
*
* @return void
*/
public function __construct() {
$this->service = WPCF7_RECAPTCHA::get_instance();
if ( $this->service->is_active() )
add_action( 'wp_enqueue_scripts', [ $this, 'contact_form_7_recaptcha' ], 21 );
}
/**
* Replace original recaptcha script from Contact Form 7.
*
* @return void
*/
public function contact_form_7_recaptcha() {
// deregister original script
wp_deregister_script( 'wpcf7-recaptcha' );
// register new script
wp_register_script(
'wpcf7-recaptcha',
COOKIE_NOTICE_URL . '/includes/modules/contact-form-7/recaptcha.js',
[
'google-recaptcha',
'wp-polyfill'
],
WPCF7_VERSION,
true
);
wp_enqueue_script( 'wpcf7-recaptcha' );
wp_localize_script(
'wpcf7-recaptcha',
'wpcf7_recaptcha',
[
'sitekey' => $this->service->get_sitekey(),
'actions' => apply_filters(
'wpcf7_recaptcha_actions',
[
'homepage' => 'homepage',
'contactform' => 'contactform'
]
)
]
);
}
}
new Cookie_Notice_Modules_ContactForm7();
\ No newline at end of file
( function( window, document, undefined ) {
'use strict';
/**
* Initialize recaptcha.
*
* @return {void}
*/
function initRecaptcha() {
wpcf7_recaptcha = {
...( wpcf7_recaptcha ?? {} )
};
const siteKey = wpcf7_recaptcha.sitekey;
const { homepage, contactform } = wpcf7_recaptcha.actions;
const execute = options => {
const { action, func, params } = options;
grecaptcha.execute( siteKey, {
action,
} ).then( token => {
const event = new CustomEvent( 'wpcf7grecaptchaexecuted', {
detail: {
action,
token
}
} );
document.dispatchEvent( event );
} ).then( () => {
if ( typeof func === 'function' ) {
func( ...params );
}
} ).catch( error => console.error( error ) );
};
grecaptcha.ready( () => {
execute( {
action: homepage
} );
} );
document.addEventListener( 'change', event => {
execute( {
action: contactform
} );
} );
if ( typeof wpcf7 !== 'undefined' && typeof wpcf7.submit === 'function' ) {
const submit = wpcf7.submit;
wpcf7.submit = ( form, options = {} ) => {
execute( {
action: contactform,
func: submit,
params: [ form, options ]
} );
};
}
document.addEventListener( 'wpcf7grecaptchaexecuted', event => {
const fields = document.querySelectorAll( 'form.wpcf7-form input[name="_wpcf7_recaptcha_response"]' );
for ( let i = 0; i < fields.length; i++ ) {
let field = fields[ i ];
field.setAttribute( 'value', event.detail.token );
}
} );
}
/**
* Handle cookies-unblocked event.
*
* @return {void}
*/
document.addEventListener( 'cookies-unblocked.hu', function( e ) {
e.detail.data.scripts.forEach( function( script ) {
// find google recaptcha in valid category
if ( script.id === 'google-recaptcha-js' && e.detail.categories[script.dataset.huCategory] === true ) {
script.onload = initRecaptcha;
script.onreadystatechange = initRecaptcha;
}
} );
}, false );
} )( window, document );
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules Elementor class.
*
* Compatibility since: 1.3.0
*
* @class Cookie_Notice_Modules_Elementor
*/
class Cookie_Notice_Modules_Elementor {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_filter( 'cn_is_preview_mode', [ $this, 'is_preview_mode' ] );
}
/**
* Whether elementor editor is active.
*
* @return bool
*/
function is_preview_mode() {
return \Elementor\Plugin::$instance->preview->is_preview_mode();
}
}
new Cookie_Notice_Modules_Elementor();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules LiteSpeed Cache class.
*
* Compatibility since: 3.0.0
*
* @class Cookie_Notice_Modules_LiteSpeedCache
*/
class Cookie_Notice_Modules_LiteSpeedCache {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_filter( 'litespeed_optimize_js_excludes', [ $this, 'exclude_js' ] );
add_filter( 'litespeed_optm_js_defer_exc ', [ $this, 'exclude_js' ] );
}
/**
* Exclude JavaScript external file and inline code.
*
* @param array $excludes
* @return array
*/
function exclude_js( $excludes ) {
// add widget url
$excludes[] = basename( Cookie_Notice()->get_url( 'widget' ) );
// add widget inline code
$excludes[] = 'huOptions';
return $excludes;
}
}
new Cookie_Notice_Modules_LiteSpeedCache();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules SiteGround Optimizer class.
*
* Compatibility since: 5.5.0
*
* @class Cookie_Notice_Modules_SGOptimizer
*/
class Cookie_Notice_Modules_SGOptimizer {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_filter( 'sgo_javascript_combine_excluded_external_paths', [ $this, 'exclude_script' ] );
add_filter( 'sgo_javascript_combine_excluded_inline_content', [ $this, 'exclude_code' ] );
}
/**
* Exclude JavaScript file.
*
* @param array $excludes
* @return array
*/
function exclude_script( $excludes ) {
// add widget url
$excludes[] = basename( Cookie_Notice()->get_url( 'widget' ) );
return $excludes;
}
/**
* Exclude JavaScript inline code.
*
* @param array $excludes
* @return array
*/
function exclude_code( $excludes ) {
// add widget inline code
$excludes[] = 'huOptions';
return $excludes;
}
}
new Cookie_Notice_Modules_SGOptimizer();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules WP Fastest Cache class.
*
* Compatibility since: 1.0.0
*
* @class Cookie_Notice_Modules_WPFastestCache
*/
class Cookie_Notice_Modules_WPFastestCache {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_action( 'admin_init', [ $this, 'check_wpfc' ], 11 );
}
/**
* Compatibility with WP Fastest Cache plugin.
*
* @return void
*/
public function check_wpfc() {
// is preloading enabled?
if ( isset( $GLOBALS['wp_fastest_cache_options']->wpFastestCachePreload ) )
$this->disable_preload( $GLOBALS['wp_fastest_cache_options'] );
// is caching enabled?
if ( isset( $GLOBALS['wp_fastest_cache_options']->wpFastestCacheStatus ) ) {
// update 2.4.9+
if ( version_compare( Cookie_Notice()->db_version, '2.4.9', '<=' ) )
$this->delete_cache();
add_action( 'updated_option', [ $this, 'check_updated_option' ], 10, 3 );
}
}
/**
* Delete cache files after updating Cookie Notice settings or status.
*
* @return void
*/
public function check_updated_option( $option, $old_value, $new_value ) {
if ( $option === 'cookie_notice_status' || $option === 'cookie_notice_options' )
$this->delete_cache();
}
/**
* Disable preloading.
*
* @param object $options
* @return void
*/
private function disable_preload( $options ) {
// disable preload
unset( $options->wpFastestCachePreload );
// delete preload option
delete_option( 'WpFastestCachePreLoad' );
// clear preload hook
wp_clear_scheduled_hook( 'wp_fastest_cache_Preload' );
// update options
update_option( 'WpFastestCache', json_encode( $options ) );
}
/**
* Delete all cache files.
*
* @return void
*/
private function delete_cache() {
// check constant and function existence
if ( defined( 'WPFC_DISABLE_HOOK_CLEAR_ALL_CACHE' ) && WPFC_DISABLE_HOOK_CLEAR_ALL_CACHE && isset( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) {
// bypass constant and call function directly
$GLOBALS['wp_fastest_cache']->deleteCache( true );
} else {
// call function normally
wpfc_clear_all_cache( true );
}
}
}
new Cookie_Notice_Modules_WPFastestCache();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie Notice Modules WP Rocket Optimizer class.
*
* Compatibility since: 3.8.0
*
* @class Cookie_Notice_Modules_WPRocket
*/
class Cookie_Notice_Modules_WPRocket {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_filter( 'rocket_exclude_defer_js', [ $this, 'exclude_script' ] );
add_filter( 'rocket_defer_inline_exclusions ', [ $this, 'exclude_code' ] );
}
/**
* Exclude JavaScript file.
*
* @param array $excludes
* @return array
*/
function exclude_script( $excludes ) {
// add widget url
$excludes[] = basename( Cookie_Notice()->get_url( 'widget' ) );
return $excludes;
}
/**
* Exclude JavaScript inline code.
*
* @param array $excludes
* @return array
*/
function exclude_code( $excludes ) {
// add widget inline code
$excludes[] = 'huOptions';
return $excludes;
}
}
new Cookie_Notice_Modules_WPRocket();
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Settings class.
*
* @class Cookie_Notice_Settings
*/
class Cookie_Notice_Settings {
public $parameters = [];
public $operators = [];
public $conditional_display_types = [];
public $positions = [];
public $styles = [];
public $revoke_opts = [];
public $links = [];
public $link_targets = [];
public $link_positions = [];
public $colors = [];
public $times = [];
public $effects = [];
public $script_placements = [];
public $level_names = [];
public $text_strings = [];
private $analytics_app_data = [];
/**
* Class constructor.
*
* @return void
*/
public function __construct() {
// actions
add_action( 'admin_menu', [ $this, 'admin_menu_options' ] );
add_action( 'network_admin_menu', [ $this, 'admin_menu_options' ] );
add_action( 'after_setup_theme', [ $this, 'load_defaults' ] );
add_action( 'admin_init', [ $this, 'load_modules' ] );
add_action( 'admin_init', [ $this, 'validate_network_options' ], 9 );
add_action( 'admin_init', [ $this, 'register_settings' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
add_action( 'admin_print_styles', [ $this, 'admin_print_styles' ] );
add_action( 'wp_ajax_cn_purge_cache', [ $this, 'ajax_purge_cache' ] );
add_action( 'wp_ajax_cn-get-group-rules-values', [ $this, 'get_group_rule_values' ] );
add_action( 'admin_notices', [ $this, 'settings_errors' ] );
add_action( 'network_admin_notices', [ $this, 'settings_errors' ] );
}
/**
* Load additional modules.
*
* @return void
*/
public function load_modules() {
if ( Cookie_Notice()->options['general']['caching_compatibility'] ) {
// wp fastest cache
if ( cn_is_plugin_active( 'wpfastestcache' ) )
include_once( COOKIE_NOTICE_PATH . 'includes/modules/wp-fastest-cache/wp-fastest-cache.php' );
}
}
/**
* Load plugin defaults.
*
* @return void
*/
public function load_defaults() {
$this->parameters = [
'page_type' => __( 'Page Type', 'cookie-notice' ),
'page' => __( 'Page', 'cookie-notice' ),
'post_type' => __( 'Post Type', 'cookie-notice' ),
'post_type_archive' => __( 'Post Type Archive', 'cookie-notice' ),
'user_type' => __( 'User Type', 'cookie-notice' )
];
$this->operators = [
'equal' => __( 'is equal to', 'cookie-notice' ),
'not_equal' => __( 'is not equal to', 'cookie-notice' )
];
$this->conditional_display_types = [
'hide' => __( 'Hide the banner', 'cookie-notice' ),
'show' => __( 'Show the banner', 'cookie-notice' )
];
$this->positions = [
'top' => __( 'Top', 'cookie-notice' ),
'bottom' => __( 'Bottom', 'cookie-notice' )
];
$this->styles = [
'none' => __( 'None', 'cookie-notice' ),
'wp-default' => __( 'Light', 'cookie-notice' ),
'bootstrap' => __( 'Dark', 'cookie-notice' )
];
$this->revoke_opts = [
'automatic' => __( 'Automatic', 'cookie-notice' ),
'manual' => __( 'Manual', 'cookie-notice' )
];
$this->links = [
'page' => __( 'Page link', 'cookie-notice' ),
'custom' => __( 'Custom link', 'cookie-notice' )
];
$this->link_targets = [ '_blank', '_self' ];
$this->link_positions = [
'banner' => __( 'Banner', 'cookie-notice' ),
'message' => __( 'Message', 'cookie-notice' )
];
$this->colors = [
'text' => __( 'Text color', 'cookie-notice' ),
'button' => __( 'Button color', 'cookie-notice' ),
'bar' => __( 'Bar color', 'cookie-notice' )
];
$this->times = apply_filters(
'cn_cookie_expiry',
[
'hour' => [ __( 'An hour', 'cookie-notice' ), 3600 ],
'day' => [ __( '1 day', 'cookie-notice' ), 86400 ],
'week' => [ __( '1 week', 'cookie-notice' ), 604800 ],
'month' => [ __( '1 month', 'cookie-notice' ), 2592000 ],
'3months' => [ __( '3 months', 'cookie-notice' ), 7862400 ],
'6months' => [ __( '6 months', 'cookie-notice' ), 15811200 ],
'year' => [ __( '1 year', 'cookie-notice' ), 31536000 ],
'infinity' => [ __( 'infinity', 'cookie-notice' ), 2147483647 ]
]
);
$this->effects = [
'none' => __( 'None', 'cookie-notice' ),
'fade' => __( 'Fade', 'cookie-notice' ),
'slide' => __( 'Slide', 'cookie-notice' )
];
$this->script_placements = [
'header' => __( 'Header', 'cookie-notice' ),
'footer' => __( 'Footer', 'cookie-notice' )
];
$this->level_names = [
1 => [
1 => __( 'Silver', 'cookie-notice' ),
2 => __( 'Gold', 'cookie-notice' ),
3 => __( 'Platinum', 'cookie-notice' )
],
2 => [
1 => __( 'Private', 'cookie-notice' ),
2 => __( 'Balanced', 'cookie-notice' ),
3 => __( 'Personalized', 'cookie-notice' )
],
3 => [
1 => __( 'Reject All', 'cookie-notice' ),
2 => __( 'Accept Some', 'cookie-notice' ),
3 => __( 'Accept All', 'cookie-notice' )
]
];
$this->text_strings = [
'saveBtnText' => __( 'Save my preferences', 'cookie-notice' ),
'privacyBtnText' => __( 'Privacy policy', 'cookie-notice' ),
'dontSellBtnText' => __( 'Do Not Sell', 'cookie-notice' ),
'customizeBtnText' => __( 'Preferences', 'cookie-notice' ),
'headingText' => __( "We believe your data is your property and support your right to privacy and transparency.", 'cookie-notice' ),
'bodyText' => __( "Select a Data Access Level and Duration to choose how we use and share your data.", 'cookie-notice' ),
'levelBodyText_1' => __( 'Highest level of privacy. Data accessed for necessary site operations only. Data shared with 3rd parties to ensure the site is secure and works on your device.', 'cookie-notice' ),
'levelBodyText_2' => __( 'Balanced experience. Data accessed for content personalisation and site optimisation. Data shared with 3rd parties may be used to track and store your preferences for this site.', 'cookie-notice' ),
'levelBodyText_3' => __( 'Highest level of personalisation. Data accessed to make ads and media more relevant. Data shared with 3rd parties may be use to track you on this site and other sites you visit.', 'cookie-notice' ),
'levelNameText_1' => $this->level_names[1][1],
'levelNameText_2' => $this->level_names[1][2],
'levelNameText_3' => $this->level_names[1][3],
'monthText' => __( 'month', 'cookie-notice' ),
'monthsText' => __( 'months', 'cookie-notice' )
];
// get main instance
$cn = Cookie_Notice();
// set default text strings
$cn->defaults['general']['message_text'] = __( 'We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.', 'cookie-notice' );
$cn->defaults['general']['accept_text'] = __( 'Ok', 'cookie-notice' );
$cn->defaults['general']['refuse_text'] = __( 'No', 'cookie-notice' );
$cn->defaults['general']['revoke_message_text'] = __( 'You can revoke your consent any time using the Revoke consent button.', 'cookie-notice' );
$cn->defaults['general']['revoke_text'] = __( 'Revoke consent', 'cookie-notice' );
$cn->defaults['general']['see_more_opt']['text'] = __( 'Privacy policy', 'cookie-notice' );
// set translation strings on plugin activation
if ( $cn->options['general']['translate'] === true ) {
$cn->options['general']['translate'] = false;
$cn->options['general']['message_text'] = $cn->defaults['general']['message_text'];
$cn->options['general']['accept_text'] = $cn->defaults['general']['accept_text'];
$cn->options['general']['refuse_text'] = $cn->defaults['general']['refuse_text'];
$cn->options['general']['revoke_message_text'] = $cn->defaults['general']['revoke_message_text'];
$cn->options['general']['revoke_text'] = $cn->defaults['general']['revoke_text'];
$cn->options['general']['see_more_opt']['text'] = $cn->defaults['general']['see_more_opt']['text'];
if ( $cn->is_network_admin() )
update_site_option( 'cookie_notice_options', $cn->options['general'] );
else
update_option( 'cookie_notice_options', $cn->options['general'] );
}
// WPML >= 3.2
if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ) {
$this->register_wpml_strings();
// WPML and Polylang compatibility
} elseif ( function_exists( 'icl_register_string' ) ) {
icl_register_string( 'Cookie Notice', 'Message in the notice', $cn->options['general']['message_text'] );
icl_register_string( 'Cookie Notice', 'Button text', $cn->options['general']['accept_text'] );
icl_register_string( 'Cookie Notice', 'Refuse button text', $cn->options['general']['refuse_text'] );
icl_register_string( 'Cookie Notice', 'Revoke message text', $cn->options['general']['revoke_message_text'] );
icl_register_string( 'Cookie Notice', 'Revoke button text', $cn->options['general']['revoke_text'] );
icl_register_string( 'Cookie Notice', 'Privacy policy text', $cn->options['general']['see_more_opt']['text'] );
icl_register_string( 'Cookie Notice', 'Custom link', $cn->options['general']['see_more_opt']['link'] );
}
}
/**
* Add submenu.
*
* @return void
*/
public function admin_menu_options() {
if ( current_action() === 'network_admin_menu' && ! Cookie_Notice()->is_plugin_network_active() )
return;
add_menu_page( __( 'Cookie Notice', 'cookie-notice' ), __( 'Cookies', 'cookie-notice' ), apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ), 'cookie-notice', [ $this, 'options_page' ], 'none', '99.300' );
}
/**
* Options page output.
*
* @return void
*/
public function options_page() {
// get main instance
$cn = Cookie_Notice();
// get cookie compliance status
$status = $cn->get_status();
$subscription = $cn->get_subscription();
$upgrade_link = $cn->get_url( 'host', '?utm_campaign=upgrade+to+pro&utm_source=wordpress&utm_medium=link#/en/cc/dashboard?app-id=' . $cn->options['general']['app_id'] . '&open-modal=payment' );
echo '
<div class="wrap">
<h2>' . esc_html__( 'Cookie Notice & Compliance for GDPR/CCPA', 'cookie-notice' ) . '</h2>
<div class="cookie-notice-settings">
<div class="cookie-notice-sidebar">
<div class="cookie-notice-credits">
<div class="inside">
<div class="inner">';
// compliance enabled
if ( $status === 'active' ) {
echo '
<div class="cn-pricing-info">
<div class="cn-pricing-head">
<p>' . esc_html__( 'Your Cookie Compliance plan:', 'cookie-notice' ) . '</p>
<h2>' . esc_html( $subscription === 'pro' ? __( 'Professional', 'cookie-notice' ) : __( 'Basic', 'cookie-notice' ) ) . '</h2>
</div>
<div class="cn-pricing-body">
<p class="cn-active"><span class="cn-icon"></span>' . esc_html__( 'GDPR, CCPA, LGPD, PECR requirements', 'cookie-notice' ) . '</p>
<p class="cn-active"><span class="cn-icon"></span>' . esc_html__( 'Consent Analytics Dashboard', 'cookie-notice' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sUnlimited%s visits', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sLifetime%s consent storage', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGoogle & Facebook%s consent modes', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGeolocation%s support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sUnlimited%s languages', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="' . ( $subscription === 'pro' ? 'cn-active' : 'cn-inactive' ) . '"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sPriority%s Support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
</div>';
if ( $subscription !== 'pro' ) {
echo ' <div class="cn-pricing-footer">
<a href="' . esc_url( $upgrade_link ) . '" class="button button-secondary button-hero cn-button" target="_blank">' . esc_html__( 'Upgrade to Pro', 'cookie-notice' ) . '</a>
</div>';
}
echo ' </div>';
// compliance disabled
} else {
echo ' <h1><b>' . esc_html__( 'Protect your business', 'cookie-notice' ) . '</b></h1>
<h2>' . esc_html__( 'with Cookie Compliance&trade;', 'cookie-notice' ) . '</h2>
<div class="cn-lead">
<p>' . esc_html__( 'Deliver better consent experiences and comply with GDPR, CCPA and other data privacy laws more effectively.', 'cookie-notice' ) . '</p>
</div>
<img alt="' . esc_html__( 'Cookie Compliance dashboard', 'cookie-notice' ) . '" src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/screen-compliance.png">
<p><a href="https://cookie-compliance.co/?utm_campaign=learn+more&utm_source=wordpress&utm_medium=banner" class="button button-secondary button-hero cn-button" target="_blank">' . esc_html__( 'Learn more', 'cookie-notice' ) . '</a></p>';
}
echo '
</div>
</div>
</div>';
echo '
<div class="cookie-notice-faq">
<h2>' . esc_html__( 'F.A.Q.', 'cookie-notice' ) . '</h2>
<div class="cn-toggle-container">
<label for="cn-faq-1" class="cn-toggle-item">
<input id="cn-faq-1" type="checkbox" />
<span class="cn-toggle-heading">' . esc_html__( 'Does the Cookie Notice make my site fully compliant with GDPR?', 'cookie-notice' ) . '</span>
<span class="cn-toggle-body">' . esc_html__( 'It is not possible to provide the required technical compliance features using only a WordPress plugin. Features like consent record storage, purpose categories and script blocking that bring your site into full compliance with GDPR are only available through the Cookie Compliance integration.', 'cookie-notice' ) . '
</label>
<label for="cn-faq-2" class="cn-toggle-item">
<input id="cn-faq-2" type="checkbox" />
<span class="cn-toggle-heading">' . esc_html__( 'Does the Cookie Compliance integration make my site fully compliant with GDPR?', 'cookie-notice' ) . '</span>
<span class="cn-toggle-body">' . esc_html__( 'Yes! The plugin + web application version includes technical compliance features to meet requirements for over 100 countries and legal jurisdictions.', 'cookie-notice' ) . '</span>
</label>
<label for="cn-faq-3" class="cn-toggle-item">
<input id="cn-faq-3" type="checkbox" />
<span class="cn-toggle-heading">' . esc_html__( 'Is Cookie Compliance free?', 'cookie-notice' ) . '</span>
<span class="cn-toggle-body">' . esc_html__( 'Yes, but with limits. Cookie Compliance includes both free and paid plans to choose from depending on your needs and your website monthly traffic.', 'cookie-notice' ) . '</span>
</label>
<label for="cn-faq-4" class="cn-toggle-item">
<input id="cn-faq-4" type="checkbox" />
<span class="cn-toggle-heading">' . esc_html__( 'Where can I find pricing options?', 'cookie-notice' ) . '</span>
<span class="cn-toggle-body">' . esc_html__( 'You can learn more about the features and pricing by visiting the Cookie Compliance website here:', 'cookie-notice' ) . ' <a href="https://cookie-compliance.co/?utm_campaign=pricing+options&utm_source=wordpress&utm_medium=textlink" target="_blank">https://cookie-compliance.co</a></span>
</label>
</div>
</div>';
echo '
</div>';
// multisite?
if ( is_multisite() ) {
// network admin?
if ( $cn->is_network_admin() ) {
$form_class = ( $cn->is_plugin_network_active() && ! $cn->options['general']['global_override'] ? 'cn-options-disabled' : '' );
$form_page = 'admin.php?page=cookie-notice';
$hidden_input = '<input type="hidden" name="cn-network-settings" value="true" />';
// single network site
} else {
$form_class = ( $cn->is_plugin_network_active() && $cn->network_options['global_override'] ? 'cn-options-disabled cn-options-submit-disabled' : '' );
$form_page = 'options.php';
$hidden_input = '';
}
// single site
} else {
$form_class = '';
$form_page = 'options.php';
$hidden_input = '';
}
echo '
<form action="' . esc_attr( $form_page ) . '" method="post"' . ( $form_class !== '' ? ' class="' . esc_attr( $form_class ) . '"' : '' ) . '>';
settings_fields( 'cookie_notice_options' );
if ( $hidden_input !== '' ) {
$allowed_html = [
'input' => [
'type' => true,
'name' => true,
'value' => true
]
];
echo wp_kses( $hidden_input, $allowed_html );
}
echo '
<div class="cn-options">';
do_settings_sections( 'cookie_notice_options' );
echo ' </div>
<p class="submit">';
submit_button( '', 'primary', 'save_cookie_notice_options', false );
echo ' ';
submit_button( esc_html__( 'Reset to defaults', 'cookie-notice' ), 'secondary', 'reset_cookie_notice_options', false );
echo '
</p>
</form>
</div>
<div class="clear"></div>
</div>';
}
/**
* Regiseter plugin settings.
*
* @return void
*/
public function register_settings() {
register_setting( 'cookie_notice_options', 'cookie_notice_options', [ $this, 'validate_options' ] );
// get main instance
$cn = Cookie_Notice();
$status = $cn->get_status();
// multisite?
if ( is_multisite() ) {
// network admin?
if ( $cn->is_network_admin() ) {
// network section
add_settings_section( 'cookie_notice_network', esc_html__( 'Network Settings', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_global_override', esc_html__( 'Global Settings Override', 'cookie-notice' ), [ $this, 'cn_global_override' ], 'cookie_notice_options', 'cookie_notice_network' );
add_settings_field( 'cn_global_cookie', esc_html__( 'Global Cookie', 'cookie-notice' ), [ $this, 'cn_global_cookie' ], 'cookie_notice_options', 'cookie_notice_network' );
} elseif ( $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
// network section
add_settings_section( 'cookie_notice_network', esc_html__( 'Network Settings', 'cookie-notice' ), [ $this, 'cn_network_section' ], 'cookie_notice_options' );
add_settings_field( 'cn_dummy', '', '__return_empty_string', 'cookie_notice_options', 'cookie_notice_network' );
// get default status data
$default_data = $cn->defaults['data'];
// get real status of current site, not network since global_override is on
$status_data = get_option( 'cookie_notice_status', $default_data );
// old status format?
if ( ! is_array( $status_data ) ) {
// old value saved as string
if ( is_string( $status_data ) && $cn->check_status( $status_data ) ) {
// update status
$default_data['status'] = $status_data;
}
// set data
$status_data = $default_data;
}
// get valid status
$status = $cn->check_status( $status_data['status'] );
}
}
// compliance enabled
if ( $status === 'active' ) {
// compliance section
add_settings_section( 'cookie_notice_compliance', esc_html__( 'Compliance Settings', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_app_status', esc_html__( 'Compliance status', 'cookie-notice' ), [ $this, 'cn_app_status' ], 'cookie_notice_options', 'cookie_notice_compliance' );
add_settings_field( 'cn_app_id', esc_html__( 'App ID', 'cookie-notice' ), [ $this, 'cn_app_id' ], 'cookie_notice_options', 'cookie_notice_compliance' );
add_settings_field( 'cn_app_key', esc_html__( 'App Key', 'cookie-notice' ), [ $this, 'cn_app_key' ], 'cookie_notice_options', 'cookie_notice_compliance' );
// configuration section
add_settings_section( 'cookie_notice_configuration', esc_html__( 'Miscellaneous Settings', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_app_blocking', esc_html__( 'Autoblocking', 'cookie-notice' ), [ $this, 'cn_app_blocking' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_debug_mode', esc_html__( 'Debug mode', 'cookie-notice' ), [ $this, 'cn_debug_mode' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_caching_compatibility', esc_html__( 'Caching compatibility', 'cookie-notice' ), [ $this, 'cn_caching_compatibility' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_app_purge_cache', esc_html__( 'Cache', 'cookie-notice' ), [ $this, 'cn_app_purge_cache' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_conditional_display', esc_html__( 'Conditional display', 'cookie-notice' ), [ $this, 'cn_conditional_display' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_deactivation_delete', esc_html__( 'Deactivation', 'cookie-notice' ), [ $this, 'cn_deactivation_delete' ], 'cookie_notice_options', 'cookie_notice_configuration' );
// compliance disabled
} else {
// compliance section
add_settings_section( 'cookie_notice_compliance', esc_html__( 'Compliance Settings', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_app_status', esc_html__( 'Compliance status', 'cookie-notice' ), [ $this, 'cn_app_status' ], 'cookie_notice_options', 'cookie_notice_compliance' );
add_settings_field( 'cn_app_id', esc_html__( 'App ID', 'cookie-notice' ), [ $this, 'cn_app_id' ], 'cookie_notice_options', 'cookie_notice_compliance' );
add_settings_field( 'cn_app_key', esc_html__( 'App Key', 'cookie-notice' ), [ $this, 'cn_app_key' ], 'cookie_notice_options', 'cookie_notice_compliance' );
// configuration section
add_settings_section( 'cookie_notice_configuration', esc_html__( 'Notice Settings', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_message_text', esc_html__( 'Message', 'cookie-notice' ), [ $this, 'cn_message_text' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_accept_text', esc_html__( 'Button text', 'cookie-notice' ), [ $this, 'cn_accept_text' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_see_more', esc_html__( 'Privacy policy', 'cookie-notice' ), [ $this, 'cn_see_more' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_refuse_opt', esc_html__( 'Refuse consent', 'cookie-notice' ), [ $this, 'cn_refuse_opt' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_revoke_opt', esc_html__( 'Revoke consent', 'cookie-notice' ), [ $this, 'cn_revoke_opt' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_refuse_code', esc_html__( 'Script blocking', 'cookie-notice' ), [ $this, 'cn_refuse_code' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_redirection', esc_html__( 'Reloading', 'cookie-notice' ), [ $this, 'cn_redirection' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_on_scroll', esc_html__( 'On scroll', 'cookie-notice' ), [ $this, 'cn_on_scroll' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_on_click', esc_html__( 'On click', 'cookie-notice' ), [ $this, 'cn_on_click' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_time', esc_html__( 'Accepted expiry', 'cookie-notice' ), [ $this, 'cn_time' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_time_rejected', esc_html__( 'Rejected expiry', 'cookie-notice' ), [ $this, 'cn_time_rejected' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_conditional_display', esc_html__( 'Conditional display', 'cookie-notice' ), [ $this, 'cn_conditional_display' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_script_placement', esc_html__( 'Script placement', 'cookie-notice' ), [ $this, 'cn_script_placement' ], 'cookie_notice_options', 'cookie_notice_configuration' );
add_settings_field( 'cn_deactivation_delete', esc_html__( 'Deactivation', 'cookie-notice' ), [ $this, 'cn_deactivation_delete' ], 'cookie_notice_options', 'cookie_notice_configuration' );
// design section
add_settings_section( 'cookie_notice_design', esc_html__( 'Notice Design', 'cookie-notice' ), '', 'cookie_notice_options' );
add_settings_field( 'cn_position', esc_html__( 'Position', 'cookie-notice' ), [ $this, 'cn_position' ], 'cookie_notice_options', 'cookie_notice_design' );
add_settings_field( 'cn_hide_effect', esc_html__( 'Animation', 'cookie-notice' ), [ $this, 'cn_hide_effect' ], 'cookie_notice_options', 'cookie_notice_design' );
add_settings_field( 'cn_colors', esc_html__( 'Colors', 'cookie-notice' ), [ $this, 'cn_colors' ], 'cookie_notice_options', 'cookie_notice_design' );
add_settings_field( 'cn_css_class', esc_html__( 'Button class', 'cookie-notice' ), [ $this, 'cn_css_class' ], 'cookie_notice_options', 'cookie_notice_design' );
}
}
/**
* Network settings override option.
*
* @return void
*/
public function cn_global_override() {
echo '
<div id="cn_global_override">
<label><input type="checkbox" name="cookie_notice_options[global_override]" value="1" ' . checked( true, Cookie_Notice()->options['general']['global_override'], false ) . ' />' . esc_html__( 'Enable global network settings override.', 'cookie-notice' ) . '</label>
<p class="description">' . esc_html__( 'Every site in the network will use the same settings. Site administrators will not be able to change them.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Network cookie acceptance option.
*
* @return void
*/
public function cn_global_cookie() {
$multi_folders = is_multisite() && ! is_subdomain_install();
// multisite with path-based network?
if ( $multi_folders )
$desc = __( 'This option works only for domain-based networks.', 'cookie-notice' );
else
$desc = '';
echo '
<div id="cn_global_cookie">
<label><input type="checkbox" name="cookie_notice_options[global_cookie]" value="1" ' . checked( true, Cookie_Notice()->options['general']['global_cookie'], false ) . ' ' . disabled( $multi_folders, true, false ) . ' />' . esc_html__( 'Enable global network cookie consent.', 'cookie-notice' ) . '</label>
<p class="description">' . esc_html__( 'Cookie consent in one of the network sites results in a consent in all of the sites on the network.', 'cookie-notice' ) . ( $desc !== '' ? ' ' . esc_html( $desc ) : '' ) . '</p>
</div>';
}
/**
* Network settings section.
*
* @return void
*/
public function cn_network_section() {
echo '
<p>' . esc_html__( 'Global network settings override is active. Every site will use the same network settings. Please contact super administrator if you want to have more control over the settings.', 'cookie-notice' ) . '</p>';
}
/**
* Compliance status.
*
* @return void
*/
public function cn_app_status() {
// get main instance
$cn = Cookie_Notice();
// get cookie compliance status
$app_status = $cn->get_status();
// get threshold status
$threshold_exceeded = $cn->threshold_exceeded();
switch ( $app_status ) {
case 'active':
echo '
<div id="cn_app_status">
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Notice', 'cookie-notice' ) . '</span>: <span class="cn-status cn-active"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Autoblocking', 'cookie-notice' ) . '</span>: <span class="cn-status ' . ( $threshold_exceeded ? 'cn-pending' : 'cn-active' ) . '"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Cookie Categories', 'cookie-notice' ) . '</span>: <span class="cn-status cn-active"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Proof-of-Consent', 'cookie-notice' ) . '</span>: <span class="cn-status cn-active"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
</div>
<div id="cn_app_actions">
<a href="' . esc_url( $cn->get_url( 'host', '?utm_campaign=configure&utm_source=wordpress&utm_medium=button#/en/cc/login' ) ) . '" class="button button-primary button-hero cn-button" target="_blank">' . esc_html__( 'Log in & Configure', 'cookie-notice' ) . '</a>
<p class="description">' . esc_html__( 'Log into the Cookie Compliance&trade; web application to configure the appearance and functionality of the banner.', 'cookie-notice' ) . '</p>
</div>';
break;
case 'pending':
echo '
<div id="cn_app_status">
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Notice', 'cookie-notice' ) . '</span>: <span class="cn-status cn-active"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Autoblocking', 'cookie-notice' ) . '</span>: <span class="cn-status cn-pending"><span class="cn-icon"></span> ' . esc_html__( 'Pending', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Cookie Categories', 'cookie-notice' ) . '</span>: <span class="cn-status cn-pending"><span class="cn-icon"></span> ' . esc_html__( 'Pending', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Proof-of-Consent', 'cookie-notice' ) . '</span>: <span class="cn-status cn-pending"><span class="cn-icon"></span> ' . esc_html__( 'Pending', 'cookie-notice' ) . '</span></div>
</div>
<div id="cn_app_actions">
<a href="' . esc_url( $cn->get_url( 'host', '?utm_campaign=configure&utm_source=wordpress&utm_medium=button#/en/cc/login' ) ) . '" class="button button-primary button-hero cn-button" target="_blank">' . esc_html__( 'Log in & configure', 'cookie-notice' ) . '</a>
<p class="description">' . esc_html__( 'Log into the Cookie Compliance&trade; web application and complete the setup process.', 'cookie-notice' ) . '</p>
</div>';
break;
default:
if ( $cn->is_network_admin() )
$url = network_admin_url( 'admin.php?page=cookie-notice' );
else
$url = admin_url( 'admin.php?page=cookie-notice' );
echo '
<div id="cn_app_status">
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Notice', 'cookie-notice' ) . '</span>: <span class="cn-status cn-active"><span class="cn-icon"></span> ' . esc_html__( 'Active', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Autoblocking', 'cookie-notice' ) . '</span>: <span class="cn-status cn-inactive"><span class="cn-icon"></span> ' . esc_html__( 'Inactive', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Cookie Categories', 'cookie-notice' ) . '</span>: <span class="cn-status cn-inactive"><span class="cn-icon"></span> ' . esc_html__( 'Inactive', 'cookie-notice' ) . '</span></div>
<div class="cn_compliance_status"><span class="cn-status-label">' . esc_html__( 'Proof-of-Consent', 'cookie-notice' ) . '</span>: <span class="cn-status cn-inactive"><span class="cn-icon"></span> ' . esc_html__( 'Inactive', 'cookie-notice' ) . '</span></div>
</div>
<div id="cn_app_actions">
<a href="' . esc_url( $url ) . '" class="button button-primary button-hero cn-button cn-run-welcome">' . esc_html__( 'Add Compliance features', 'cookie-notice' ) . '</a>
<p class="description">' . sprintf( esc_html__( 'Sign up to %s and add GDPR, CCPA and other international data privacy laws compliance features.', 'cookie-notice' ), '<a href="https://cookie-compliance.co/?utm_campaign=sign-up&utm_source=wordpress&utm_medium=textlink" target="_blank">Cookie Compliance&trade;</a>' ) . '</p>
</div>';
break;
}
}
/**
* App ID option.
*
* @return void
*/
public function cn_app_id() {
echo '
<div id="cn_app_id">
<input type="text" class="regular-text" name="cookie_notice_options[app_id]" value="' . esc_attr( Cookie_Notice()->options['general']['app_id'] ) . '" />
<p class="description">' . esc_html__( 'Enter your Cookie Compliance&trade; application ID.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* App key option.
*
* @return void
*/
public function cn_app_key() {
echo '
<div id="cn_app_key">
<input type="password" class="regular-text" name="cookie_notice_options[app_key]" value="' . esc_attr( Cookie_Notice()->options['general']['app_key'] ) . '" />
<p class="description">' . esc_html__( 'Enter your Cookie Compliance&trade; application secret key.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* App autoblocking option.
*
* @return void
*/
public function cn_app_blocking() {
// get main instance
$cn = Cookie_Notice();
$threshold_exceeded = $cn->threshold_exceeded();
echo '
<div id="cn_app_blocking"' . ( $threshold_exceeded ? ' class="cn-option-disabled"' : '' ) . '>
<label><input type="checkbox" name="cookie_notice_options[app_blocking]" value="1" ' . checked( true, $cn->options['general']['app_blocking'], false ) . ' ' . disabled( $threshold_exceeded, true, false ) . ' />' . esc_html__( 'Enable to automatically block 3rd party scripts before user consent is set.', 'cookie-notice' ) . '</label>' .
( $threshold_exceeded ? '<p class="description"><span class="cn-warning">*</span> ' . esc_html__( 'This option has been temporarily disabled because your website has reached the usage limit for the Cookie Compliance Basic plan. It will become available again when the current visits cycle resets or you upgrade your website to a Professional plan.', 'cookie-notice' ) . '</p>' : '' ) .
'</div>';
}
/**
* Purge cache option.
*
* @return void
*/
public function cn_app_purge_cache() {
echo '
<div id="cn_app_purge_cache">
<div class="cn-button-container">
<a href="#" class="button button-secondary">' . esc_html__( 'Purge Cache', 'cookie-notice' ) . '</a>
</div>
<p class="description">' . esc_html__( 'Click the Purge Cache button to refresh the app configuration.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Conditional display option.
*
* @return void
*/
public function cn_conditional_display() {
// get main instance
$cn = Cookie_Notice();
echo '
<fieldset id="cn_conditional_display">
<label><input id="cn_conditional_display_opt" type="checkbox" name="cookie_notice_options[conditional_active]" value="1" ' . checked( true, $cn->options['general']['conditional_active'], false ) . ' />' . esc_html__( 'Enable conditional display of the banner.', 'cookie-notice' ) . '</label>
<div id="cn_conditional_display_opt_container"' . ( $cn->options['general']['conditional_active'] === false ? ' style="display: none"' : '' ) . ' class="cn_fieldset_content">
<div>
<select name="cookie_notice_options[conditional_display]">';
foreach ( $this->conditional_display_types as $type => $label ) {
echo '
<option value="' . esc_attr( $type ) . '" ' . selected( $type, $cn->options['general']['conditional_display'] ) . '>' . esc_html( $label ) . '</option>';
}
echo '
</select>
<p class="description">' . esc_html__( 'Determine what should happen when the following conditions are met.', 'cookie-notice' ) . '</p>
</div>';
// get allowed html
$allowed_html = wp_kses_allowed_html( 'post' );
$allowed_html['select'] = [
'name' => true,
'class' => true
];
$allowed_html['option'] = [
'value' => true,
'selected' => true
];
add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
echo wp_kses( $this->conditional_display( $cn->options['general']['conditional_rules'] ), $allowed_html );
remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
echo '
</div>
</fieldset>';
}
/**
* Debug mode option.
*
* @return void
*/
public function cn_debug_mode() {
echo '
<div id="cn_debug_mode">
<label><input type="checkbox" name="cookie_notice_options[debug_mode]" value="1" ' . checked( true, Cookie_Notice()->options['general']['debug_mode'], false ) . ' />' . esc_html__( 'Enable to run the consent banner in debug mode.', 'cookie-notice' ) . '</label>
</div>';
}
/**
* Debug mode option.
*
* @return void
*/
public function cn_caching_compatibility() {
// get main instance
$cn = Cookie_Notice();
$plugins_html = '';
// get active caching plugins
$active_plugins = cn_get_active_caching_plugins();
if ( ! empty( $active_plugins ) ) {
$active_plugins_html = [];
$plugins_html .= '<p class="description">' . esc_html__( 'Currently detected active caching plugins', 'cookie-notice' ) . ': ';
foreach ( $active_plugins as $plugin ) {
$active_plugins_html[] = '<code>' . esc_html( $plugin ) . '</code>';
}
$plugins_html .= implode( ', ', $active_plugins_html ) . '.</p>';
} else
$plugins_html .= '<p class="description">' . esc_html__( 'No compatible cache plugins found.', 'cookie-notice' ) . '</p>';
echo '
<div id="cn_caching_compatibility">
<label><input type="checkbox" name="cookie_notice_options[caching_compatibility]" value="1" ' . checked( true, $cn->options['general']['caching_compatibility'] && ! empty( $active_plugins ), false ) . ' ' . disabled( empty( $active_plugins ), true, false ) . ' />' . esc_html__( 'Enable to apply changes improving compatibility with caching plugins.', 'cookie-notice' ) . '</label>' . $plugins_html . '
</div>';
}
/**
* Cookie notice message option.
*
* @return void
*/
public function cn_message_text() {
echo '
<div id="cn_message_text">
<textarea name="cookie_notice_options[message_text]" class="large-text" cols="50" rows="5">' . esc_textarea( Cookie_Notice()->options['general']['message_text'] ) . '</textarea>
<p class="description">' . esc_html__( 'Enter the cookie notice message.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Accept cookie label option.
*
* @return void
*/
public function cn_accept_text() {
echo '
<div id="cn_accept_text">
<input type="text" class="regular-text" name="cookie_notice_options[accept_text]" value="' . esc_attr( Cookie_Notice()->options['general']['accept_text'] ) . '" />
<p class="description">' . esc_html__( 'The text of the option to accept the notice and make it disappear.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Toggle third party non functional cookies option.
*
* @return void
*/
public function cn_refuse_opt() {
// get main instance
$cn = Cookie_Notice();
echo '
<fieldset>
<label><input id="cn_refuse_opt" type="checkbox" name="cookie_notice_options[refuse_opt]" value="1" ' . checked( true, $cn->options['general']['refuse_opt'], false ) . ' />' . esc_html__( 'Enable to give to the user the possibility to refuse third party non functional cookies.', 'cookie-notice' ) . '</label>
<div id="cn_refuse_opt_container"' . ( $cn->options['general']['refuse_opt'] === false ? ' style="display: none"' : '' ) . ' class="cn_fieldset_content">
<div id="cn_refuse_text">
<input type="text" class="regular-text" name="cookie_notice_options[refuse_text]" value="' . esc_attr( $cn->options['general']['refuse_text'] ) . '" />
<p class="description">' . esc_html__( 'The text of the button to refuse the consent.', 'cookie-notice' ) . '</p>
</div>
</div>
</fieldset>';
}
/**
* Non functional cookies code option.
*
* @return void
*/
public function cn_refuse_code() {
// get main instance
$cn = Cookie_Notice();
$allowed_html = $cn->get_allowed_html();
$active = ! empty( $cn->options['general']['refuse_code'] ) && empty( $cn->options['general']['refuse_code_head'] ) ? 'body' : 'head';
echo '
<div id="cn_refuse_code">
<div id="cn_refuse_code_fields">
<h2 class="nav-tab-wrapper">
<a id="refuse_head-tab" class="nav-tab' . ( $active === 'head' ? ' nav-tab-active' : '' ) . '" href="#refuse_head">' . esc_html__( 'Head', 'cookie-notice' ) . '</a>
<a id="refuse_body-tab" class="nav-tab' . ( $active === 'body' ? ' nav-tab-active' : '' ) . '" href="#refuse_body">' . esc_html__( 'Body', 'cookie-notice' ) . '</a>
</h2>
<div id="refuse_head" class="refuse-code-tab' . ( $active === 'head' ? ' active' : '' ) . '">
<p class="description">' . esc_html__( 'The code to be used in your site header, before the closing head tag.', 'cookie-notice' ) . '</p>
<textarea name="cookie_notice_options[refuse_code_head]" class="large-text" cols="50" rows="8">' . html_entity_decode( trim( wp_kses( $cn->options['general']['refuse_code_head'], $allowed_html ) ) ) . '</textarea>
</div>
<div id="refuse_body" class="refuse-code-tab' . ( $active === 'body' ? ' active' : '' ) . '">
<p class="description">' . esc_html__( 'The code to be used in your site footer, before the closing body tag.', 'cookie-notice' ) . '</p>
<textarea name="cookie_notice_options[refuse_code]" class="large-text" cols="50" rows="8">' . html_entity_decode( trim( wp_kses( $cn->options['general']['refuse_code'], $allowed_html ) ) ) . '</textarea>
</div>
</div>
<p class="description">' . esc_html__( 'Enter non functional cookies Javascript code here (for e.g. Google Analitycs) to be used after the notice is accepted.', 'cookie-notice' ) . '</br>' . sprintf( esc_html__( 'To get the user consent status use the %scn_cookies_accepted()%s function.', 'cookie-notice' ), '<code>', '</code>' ) . '</p>
</div>';
}
/**
* Revoke cookies option.
*
* @return void
*/
public function cn_revoke_opt() {
// get main instance
$cn = Cookie_Notice();
echo '
<fieldset id="cn_revoke_opt">
<label><input id="cn_revoke_cookies" type="checkbox" name="cookie_notice_options[revoke_cookies]" value="1" ' . checked( true, $cn->options['general']['revoke_cookies'], false ) . ' />' . sprintf( esc_html__( 'Enable to give to the user the possibility to revoke their consent %s(requires "Refuse consent" option enabled)%s.', 'cookie-notice' ), '<i>', '</i>' ) . '</label>
<div id="cn_revoke_opt_container"' . ( $cn->options['general']['revoke_cookies'] ? '' : ' style="display: none"' ) . ' class="cn_fieldset_content">
<textarea name="cookie_notice_options[revoke_message_text]" class="large-text" cols="50" rows="2">' . esc_textarea( $cn->options['general']['revoke_message_text'] ) . '</textarea>
<p class="description">' . esc_html__( 'Enter the revoke message.', 'cookie-notice' ) . '</p>
<input type="text" class="regular-text" name="cookie_notice_options[revoke_text]" value="' . esc_attr( $cn->options['general']['revoke_text'] ) . '" />
<p class="description">' . esc_html__( 'The text of the button to revoke the consent.', 'cookie-notice' ) . '</p>';
foreach ( $this->revoke_opts as $value => $label ) {
echo '
<label><input id="cn_revoke_cookies-' . esc_attr( $value ) . '" type="radio" name="cookie_notice_options[revoke_cookies_opt]" value="' . esc_attr( $value ) . '" ' . checked( $value, $cn->options['general']['revoke_cookies_opt'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
<p class="description">' . sprintf( esc_html__( 'Select the method for displaying the revoke button - automatic (in the banner) or manual using %s[cookies_revoke]%s shortcode.', 'cookie-notice' ), '<code>', '</code>' ) . '</p>
</div>
</fieldset>';
}
/**
* Redirection on cookie accept option.
*
* @return void
*/
public function cn_redirection() {
echo '
<div id="cn_redirection">
<label><input type="checkbox" name="cookie_notice_options[redirection]" value="1" ' . checked( true, Cookie_Notice()->options['general']['redirection'], false ) . ' />' . esc_html__( 'Enable to reload the page after the notice is accepted.', 'cookie-notice' ) . '</label>
</div>';
}
/**
* Privacy policy link option.
*
* @global string $wp_version
*
* @return void
*/
public function cn_see_more() {
// get main instance
$cn = Cookie_Notice();
// get published pages
$pages = get_pages(
[
'sort_order' => 'ASC',
'sort_column' => 'post_title',
'hierarchical' => 0,
'child_of' => 0,
'parent' => -1,
'offset' => 0,
'post_type' => 'page',
'post_status' => 'publish'
]
);
echo '
<fieldset>
<label><input id="cn_see_more" type="checkbox" name="cookie_notice_options[see_more]" value="1" ' . checked( true, $cn->options['general']['see_more'], false ) . ' />' . esc_html__( 'Enable privacy policy link.', 'cookie-notice' ) . '</label>
<div id="cn_see_more_opt"' . ( $cn->options['general']['see_more'] === false ? ' style="display: none"' : '' ) . ' class="cn_fieldset_content">
<input type="text" class="regular-text" name="cookie_notice_options[see_more_opt][text]" value="' . esc_attr( $cn->options['general']['see_more_opt']['text'] ) . '" />
<p class="description">' . esc_html__( 'The text of the privacy policy button.', 'cookie-notice' ) . '</p>
<div id="cn_see_more_opt_custom_link">';
foreach ( $this->links as $value => $label ) {
echo '
<label><input id="cn_see_more_link-' . esc_attr( $value ) . '" type="radio" name="cookie_notice_options[see_more_opt][link_type]" value="' . esc_attr( $value ) . '" ' . checked( $value, $cn->options['general']['see_more_opt']['link_type'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
</div>
<p class="description">' . esc_html__( 'Select where to redirect user for more information.', 'cookie-notice' ) . '</p>
<div id="cn_see_more_opt_page"' . ( $cn->options['general']['see_more_opt']['link_type'] === 'custom' ? ' style="display: none"' : '' ) . '>
<select name="cookie_notice_options[see_more_opt][id]">
<option value="0" ' . selected( 0, $cn->options['general']['see_more_opt']['id'], false ) . '>' . esc_html__( '-- select page --', 'cookie-notice' ) . '</option>';
if ( $pages ) {
foreach ( $pages as $page ) {
echo '
<option value="' . esc_attr( $page->ID ) . '" ' . selected( $page->ID, $cn->options['general']['see_more_opt']['id'], false ) . '>' . esc_html( $page->post_title ) . '</option>';
}
}
echo '
</select>
<p class="description">' . esc_html__( 'Select from one of your site\'s pages.', 'cookie-notice' ) . '</p>';
global $wp_version;
if ( version_compare( $wp_version, '4.9.6', '>=' ) ) {
echo '
<label><input id="cn_see_more_opt_sync" type="checkbox" name="cookie_notice_options[see_more_opt][sync]" value="1" ' . checked( true, $cn->options['general']['see_more_opt']['sync'], false ) . ' />' . esc_html__( 'Synchronize with WordPress Privacy Policy page.', 'cookie-notice' ) . '</label>';
}
echo '
</div>
<div id="cn_see_more_opt_link"' . ( $cn->options['general']['see_more_opt']['link_type'] === 'page' ? ' style="display: none"' : '' ) . '>
<input type="text" class="regular-text" name="cookie_notice_options[see_more_opt][link]" value="' . esc_attr( $cn->options['general']['see_more_opt']['link'] ) . '" />
<p class="description">' . esc_html__( 'Enter the full URL starting with http(s)://', 'cookie-notice' ) . '</p>
</div>
<div id="cn_see_more_link_target">';
foreach ( $this->link_targets as $target ) {
echo '
<label><input id="cn_see_more_link_target-' . esc_attr( $target ) . '" type="radio" name="cookie_notice_options[link_target]" value="' . esc_attr( $target ) . '" ' . checked( $target, $cn->options['general']['link_target'], false ) . ' />' . esc_html( $target ) . '</label>';
}
echo '
<p class="description">' . esc_html__( 'Select the privacy policy link target.', 'cookie-notice' ) . '</p>
</div>
<div id="cn_see_more_link_position">';
foreach ( $this->link_positions as $position => $label ) {
echo '
<label><input id="cn_see_more_link_position-' . esc_attr( $position ) . '" type="radio" name="cookie_notice_options[link_position]" value="' . esc_attr( $position ) . '" ' . checked( $position, $cn->options['general']['link_position'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
<p class="description">' . esc_html__( 'Select the privacy policy link position.', 'cookie-notice' ) . '</p>
</div>
</div>
</fieldset>';
}
/**
* Expiration time option.
*
* @return void
*/
public function cn_time() {
echo '
<div id="cn_time">
<select name="cookie_notice_options[time]">';
foreach ( $this->times as $time => $arr ) {
echo '
<option value="' . esc_attr( $time ) . '" ' . selected( $time, Cookie_Notice()->options['general']['time'] ) . '>' . esc_html( $arr[0] ) . '</option>';
}
echo '
</select>
<p class="description">' . esc_html__( 'The amount of time that the cookie should be stored for when user accepts the notice.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Expiration time option.
*
* @return void
*/
public function cn_time_rejected() {
echo '
<div id="cn_time_rejected">
<select name="cookie_notice_options[time_rejected]">';
foreach ( $this->times as $time => $arr ) {
echo '
<option value="' . esc_attr( $time ) . '" ' . selected( $time, Cookie_Notice()->options['general']['time_rejected'] ) . '>' . esc_html( $arr[0] ) . '</option>';
}
echo '
</select>
<p class="description">' . esc_html__( 'The amount of time that the cookie should be stored for when the user doesn\'t accept the notice.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Script placement option.
*
* @return void
*/
public function cn_script_placement() {
echo '
<div id="cn_script_placement">';
foreach ( $this->script_placements as $value => $label ) {
echo '
<label><input id="cn_script_placement-' . esc_attr( $value ) . '" type="radio" name="cookie_notice_options[script_placement]" value="' . esc_attr( $value ) . '" ' . checked( $value, Cookie_Notice()->options['general']['script_placement'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
<p class="description">' . esc_html__( 'Select where all the plugin scripts should be placed.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Position option.
*
* @return void
*/
public function cn_position() {
echo '
<div id="cn_position">';
foreach ( $this->positions as $value => $label ) {
echo '
<label><input id="cn_position-' . esc_attr( $value ) . '" type="radio" name="cookie_notice_options[position]" value="' . esc_attr( $value ) . '" ' . checked( $value, Cookie_Notice()->options['general']['position'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
<p class="description">' . esc_html__( 'Select location for the notice.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Animation effect option.
*
* @return void
*/
public function cn_hide_effect() {
echo '
<div id="cn_hide_effect">';
foreach ( $this->effects as $value => $label ) {
echo '
<label><input id="cn_hide_effect-' . esc_attr( $value ) . '" type="radio" name="cookie_notice_options[hide_effect]" value="' . esc_attr( $value ) . '" ' . checked( $value, Cookie_Notice()->options['general']['hide_effect'], false ) . ' />' . esc_html( $label ) . '</label>';
}
echo '
<p class="description">' . esc_html__( 'Select the animation style.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* On scroll option.
*
* @return void
*/
public function cn_on_scroll() {
// get main instance
$cn = Cookie_Notice();
echo '
<fieldset>
<label><input id="cn_on_scroll" type="checkbox" name="cookie_notice_options[on_scroll]" value="1" ' . checked( true, $cn->options['general']['on_scroll'], false ) . ' />' . esc_html__( 'Enable to accept the notice when user scrolls.', 'cookie-notice' ) . '</label>
<div id="cn_on_scroll_offset"' . ( $cn->options['general']['on_scroll'] === false || $cn->options['general']['on_scroll'] == false ? ' style="display: none"' : '' ) . ' class="cn_fieldset_content">
<input type="number" min="0" class="small-text" name="cookie_notice_options[on_scroll_offset]" value="' . esc_attr( $cn->options['general']['on_scroll_offset'] ) . '" /> <span>px</span>
<p class="description">' . esc_html__( 'Number of pixels user has to scroll to accept the notice and make it disappear.', 'cookie-notice' ) . '</p>
</div>
</fieldset>';
}
/**
* On click option.
*
* @return void
*/
public function cn_on_click() {
echo '
<div id="cn_on_click">
<label><input type="checkbox" name="cookie_notice_options[on_click]" value="1" ' . checked( true, Cookie_Notice()->options['general']['on_click'], false ) . ' />' . esc_html__( 'Enable to accept the notice on any click on the page.', 'cookie-notice' ) . '</label>
</div>';
}
/**
* Delete plugin data on deactivation option.
*
* @return void
*/
public function cn_deactivation_delete() {
echo '
<div id="cn_deactivation_delete">
<label><input type="checkbox" name="cookie_notice_options[deactivation_delete]" value="1" ' . checked( true, Cookie_Notice()->options['general']['deactivation_delete'], false ) . '/>' . esc_html__( 'Enable if you want all plugin data to be deleted on deactivation.', 'cookie-notice' ) . '</label>
</div>';
}
/**
* CSS style option.
*
* @return void
*/
public function cn_css_class() {
echo '
<div id="cn_css_class">
<input type="text" class="regular-text" name="cookie_notice_options[css_class]" value="' . esc_attr( Cookie_Notice()->options['general']['css_class'] ) . '" />
<p class="description">' . esc_html__( 'Enter additional button CSS classes separated by spaces.', 'cookie-notice' ) . '</p>
</div>';
}
/**
* Colors option.
*
* @return void
*/
public function cn_colors() {
// get main instance
$cn = Cookie_Notice();
echo '
<fieldset>
<div id="cn_colors">';
foreach ( $this->colors as $value => $label ) {
echo '
<div id="cn_colors-' . esc_attr( $value ) . '"><label>' . esc_html( $label ) . '</label><br />
<input class="cn_color" type="text" name="cookie_notice_options[colors][' . esc_attr( $value ) . ']" value="' . esc_attr( $cn->options['general']['colors'][$value] ) . '" />
</div>';
}
echo '
<div id="cn_colors-bar_opacity"><label>' . esc_html__( 'Bar opacity', 'cookie-notice' ) . '</label><br />
<div><input id="cn_colors_bar_opacity_range" class="cn_range" type="range" min="50" max="100" step="1" name="cookie_notice_options[colors][bar_opacity]" value="' . (int) $cn->options['general']['colors']['bar_opacity'] . '" onchange="cn_colors_bar_opacity_text.value = cn_colors_bar_opacity_range.value" /><input id="cn_colors_bar_opacity_text" class="small-text" type="number" onchange="cn_colors_bar_opacity_range.value = cn_colors_bar_opacity_text.value" min="50" max="100" value="' . (int) $cn->options['general']['colors']['bar_opacity'] . '" /></div>
</div>';
echo '
</div>
</fieldset>';
}
/**
* Validate options.
*
* @param array $input
* @return array
*/
public function validate_options( $input ) {
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
return $input;
// get main instance
$cn = Cookie_Notice();
$is_network = $cn->is_network_admin();
if ( isset( $_POST['save_cookie_notice_options'] ) ) {
// app id
$input['app_id'] = isset( $input['app_id'] ) ? sanitize_key( $input['app_id'] ) : $cn->defaults['general']['app_id'];
// app key
$input['app_key'] = isset( $input['app_key'] ) ? sanitize_key( $input['app_key'] ) : $cn->defaults['general']['app_key'];
// set app status
if ( ! empty( $input['app_id'] ) && ! empty( $input['app_key'] ) ) {
$app_data = $cn->welcome_api->get_app_config( $input['app_id'], true );
if ( $cn->check_status( $app_data['status'] ) === 'active' && $cn->options['general']['app_id'] !== $input['app_id'] ) {
// get_app_analytics requires fresh app data
$this->analytics_app_data = [
'id' => $input['app_id'],
'key' => $input['app_key']
];
// update analytics data
$cn->welcome_api->get_app_analytics( $input['app_id'], true );
$this->analytics_app_data = [];
}
} else {
if ( $is_network )
update_site_option( 'cookie_notice_status', $cn->defaults['data'] );
else
update_option( 'cookie_notice_status', $cn->defaults['data'] );
}
// app blocking
$input['app_blocking'] = isset( $input['app_blocking'] ) && ! $cn->threshold_exceeded();
// conditional display
$input['conditional_active'] = isset( $input['conditional_active'] );
$input['conditional_display'] = isset( $input['conditional_display'] ) ? sanitize_key( $input['conditional_display'] ) : $cn->defaults['general']['conditional_display'];
if ( ! in_array( $input['conditional_display'], array_keys( $this->conditional_display_types ), true ) )
$input['conditional_display'] = $cn->defaults['general']['conditional_display'];
if ( ! empty( $input['conditional_rules'] ) && is_array( $input['conditional_rules'] ) ) {
$group_id = $rule_id = 1;
$rules = [];
foreach ( $input['conditional_rules'] as $group_number => $group ) {
// skips template data or empty groups
if ( (int) $group_number <= 0 || empty( $group ) )
continue;
foreach ( $group as $rule ) {
$param = sanitize_key( $rule['param'] );
$operator = sanitize_key( $rule['operator'] );
$value = sanitize_key( $rule['value'] );
if ( $this->check_rule( $param, $operator, $value ) ) {
$rules[$group_id][$rule_id++] = [
'param' => $param,
'operator' => $operator,
'value' => $value
];
}
}
$rule_id = 1;
$group_id++;
}
$input['conditional_rules'] = $rules;
} else
$input['conditional_rules'] = [];
// debug mode
$input['debug_mode'] = isset( $input['debug_mode'] );
// get active caching plugins
$active_plugins = cn_get_active_caching_plugins();
// caching compatibility
$input['caching_compatibility'] = isset( $input['caching_compatibility'] ) && ! empty( $active_plugins );
// position
if ( isset( $input['position'] ) ) {
$input['position'] = sanitize_key( $input['position'] );
if ( ! array_key_exists( $input['position'], $this->positions ) )
$input['position'] = $cn->defaults['general']['position'];
} else
$input['position'] = $cn->defaults['general']['position'];
// text color
if ( isset( $input['colors']['text'] ) ) {
$input['colors']['text'] = sanitize_hex_color( $input['colors']['text'] );
if ( empty( $input['colors']['text'] ) )
$input['colors']['text'] = $cn->defaults['general']['colors']['text'];
} else
$input['colors']['text'] = $cn->defaults['general']['colors']['text'];
// button color
if ( isset( $input['colors']['button'] ) ) {
$input['colors']['button'] = sanitize_hex_color( $input['colors']['button'] );
if ( empty( $input['colors']['button'] ) )
$input['colors']['button'] = $cn->defaults['general']['colors']['button'];
} else
$input['colors']['button'] = $cn->defaults['general']['colors']['button'];
// bar color
if ( isset( $input['colors']['bar'] ) ) {
$input['colors']['bar'] = sanitize_hex_color( $input['colors']['bar'] );
if ( empty( $input['colors']['bar'] ) )
$input['colors']['bar'] = $cn->defaults['general']['colors']['bar'];
} else
$input['colors']['bar'] = $cn->defaults['general']['colors']['bar'];
// bar opacity
$input['colors']['bar_opacity'] = isset( $input['colors']['bar_opacity'] ) ? (int) $input['colors']['bar_opacity'] : $cn->defaults['general']['colors']['bar_opacity'];
if ( $input['colors']['bar_opacity'] < 50 || $input['colors']['bar_opacity'] > 100 )
$input['colors']['bar_opacity'] = $cn->defaults['general']['colors']['bar_opacity'];
// message text
if ( isset( $input['message_text'] ) ) {
add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
$input['message_text'] = wp_kses_post( trim( $input['message_text'] ) );
remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
if ( $input['message_text'] === '' )
$input['message_text'] = $cn->defaults['general']['message_text'];
} else
$input['message_text'] = $cn->defaults['general']['message_text'];
// accept button text
if ( isset( $input['accept_text'] ) ) {
$input['accept_text'] = sanitize_text_field( $input['accept_text'] );
if ( $input['accept_text'] === '' )
$input['accept_text'] = $cn->defaults['general']['accept_text'];
} else
$input['accept_text'] = $cn->defaults['general']['accept_text'];
// refuse button text
if ( isset( $input['refuse_text'] ) ) {
$input['refuse_text'] = sanitize_text_field( $input['refuse_text'] );
if ( $input['refuse_text'] === '' )
$input['refuse_text'] = $cn->defaults['general']['refuse_text'];
} else
$input['refuse_text'] = $cn->defaults['general']['refuse_text'];
// revoke message text
if ( isset( $input['revoke_message_text'] ) ) {
add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
$input['revoke_message_text'] = wp_kses_post( trim( $input['revoke_message_text'] ) );
remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
if ( $input['revoke_message_text'] === '' )
$input['revoke_message_text'] = $cn->defaults['general']['revoke_message_text'];
} else
$input['revoke_message_text'] = $cn->defaults['general']['revoke_message_text'];
// revoke button text
if ( isset( $input['revoke_text'] ) ) {
$input['revoke_text'] = sanitize_text_field( $input['revoke_text'] );
if ( $input['revoke_text'] === '' )
$input['revoke_text'] = $cn->defaults['general']['revoke_text'];
} else
$input['revoke_text'] = $cn->defaults['general']['revoke_text'];
// refuse consent
$input['refuse_opt'] = isset( $input['refuse_opt'] );
// revoke consent
$input['revoke_cookies'] = isset( $input['revoke_cookies'] );
// revoke consent type
if ( isset( $input['revoke_cookies_opt'] ) ) {
$input['revoke_cookies_opt'] = sanitize_key( $input['revoke_cookies_opt'] );
if ( ! array_key_exists( $input['revoke_cookies_opt'], $this->revoke_opts ) )
$input['revoke_cookies_opt'] = $cn->defaults['general']['revoke_cookies_opt'];
} else
$input['revoke_cookies_opt'] = $cn->defaults['general']['revoke_cookies_opt'];
// get allowed html
$allowed_html = $cn->get_allowed_html();
// body refuse code
if ( isset( $input['refuse_code'] ) )
$input['refuse_code'] = wp_kses( trim( $input['refuse_code'] ), $allowed_html );
else
$input['refuse_code'] = $cn->defaults['general']['refuse_code'];
// head refuse code
if ( isset( $input['refuse_code_head'] ) )
$input['refuse_code_head'] = wp_kses( trim( $input['refuse_code_head'] ), $allowed_html );
else
$input['refuse_code_head'] = $cn->defaults['general']['refuse_code_head'];
// css button class(es)
if ( isset( $input['css_class'] ) ) {
$input['css_class'] = trim( $input['css_class'] );
if ( $input['css_class'] !== '' ) {
// more than 1 class?
if ( strpos( $input['css_class'], ' ' ) !== false ) {
// get unique valid html classes
$input['css_class'] = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $input['css_class'] ) ) ) );
if ( ! empty( $input['css_class'] ) )
$input['css_class'] = implode( ' ', $input['css_class'] );
else
$input['css_class'] = $cn->defaults['general']['css_class'];
// single class
} else
$input['css_class'] = sanitize_html_class( $input['css_class'] );
}
} else
$input['css_class'] = $cn->defaults['general']['css_class'];
// accepted expiry
if ( isset( $input['time'] ) ) {
$input['time'] = sanitize_key( $input['time'] );
if ( ! array_key_exists( $input['time'], $this->times ) )
$input['time'] = $cn->defaults['general']['time'];
} else
$input['time'] = $cn->defaults['general']['time'];
// rejected expiry
if ( isset( $input['time_rejected'] ) ) {
$input['time_rejected'] = sanitize_key( $input['time_rejected'] );
if ( ! array_key_exists( $input['time_rejected'], $this->times ) )
$input['time_rejected'] = $cn->defaults['general']['time_rejected'];
} else
$input['time_rejected'] = $cn->defaults['general']['time_rejected'];
// script placement
if ( isset( $input['script_placement'] ) ) {
$input['script_placement'] = sanitize_key( $input['script_placement'] );
if ( ! array_key_exists( $input['script_placement'], $this->script_placements ) )
$input['script_placement'] = $cn->defaults['general']['script_placement'];
} else
$input['script_placement'] = $cn->defaults['general']['script_placement'];
// hide effect
if ( isset( $input['hide_effect'] ) ) {
$input['hide_effect'] = sanitize_key( $input['hide_effect'] );
if ( ! array_key_exists( $input['hide_effect'], $this->effects ) )
$input['hide_effect'] = $cn->defaults['general']['hide_effect'];
} else
$input['hide_effect'] = $cn->defaults['general']['hide_effect'];
// reloading
$input['redirection'] = isset( $input['redirection'] );
// on scroll
$input['on_scroll'] = isset( $input['on_scroll'] );
// on scroll offset
$input['on_scroll_offset'] = isset( $input['on_scroll_offset'] ) ? (int) $input['on_scroll_offset'] : $cn->defaults['general']['on_scroll_offset'];
if ( $input['on_scroll_offset'] < 0 )
$input['on_scroll_offset'] = 0;
// on click
$input['on_click'] = isset( $input['on_click'] );
// deactivation
$input['deactivation_delete'] = isset( $input['deactivation_delete'] );
// privacy policy
$input['see_more'] = isset( $input['see_more'] );
// privacy policy link text
if ( isset( $input['see_more_opt']['text'] ) ) {
$input['see_more_opt']['text'] = sanitize_text_field( $input['see_more_opt']['text'] );
if ( $input['see_more_opt']['text'] === '' )
$input['see_more_opt']['text'] = $cn->defaults['general']['see_more_opt']['text'];
} else
$input['see_more_opt']['text'] = $cn->defaults['general']['see_more_opt']['text'];
// privacy policy link type
if ( isset( $input['see_more_opt']['link_type'] ) ) {
$input['see_more_opt']['link_type'] = sanitize_key( $input['see_more_opt']['link_type'] );
if ( ! array_key_exists( $input['see_more_opt']['link_type'], $this->links ) )
$input['see_more_opt']['link_type'] = $cn->defaults['general']['see_more_opt']['link_type'];
} else
$input['see_more_opt']['link_type'] = $cn->defaults['general']['see_more_opt']['link_type'];
if ( $input['see_more_opt']['link_type'] === 'custom' )
$input['see_more_opt']['link'] = $input['see_more'] && isset( $input['see_more_opt']['link'] ) ? esc_url_raw( $input['see_more_opt']['link'] ) : '';
elseif ( $input['see_more_opt']['link_type'] === 'page' ) {
$input['see_more_opt']['id'] = $input['see_more'] && isset( $input['see_more_opt']['id'] ) ? (int) $input['see_more_opt']['id'] : 0;
$input['see_more_opt']['sync'] = isset( $input['see_more_opt']['sync'] );
if ( $input['see_more_opt']['sync'] )
update_option( 'wp_page_for_privacy_policy', $input['see_more_opt']['id'] );
}
// privacy policy link target
if ( isset( $input['link_target'] ) ) {
$input['link_target'] = sanitize_key( $input['link_target'] );
if ( ! array_key_exists( $input['link_target'], $this->link_targets ) )
$input['link_target'] = $cn->defaults['general']['link_target'];
} else
$input['link_target'] = $cn->defaults['general']['link_target'];
// policy policy link position
if ( isset( $input['link_position'] ) ) {
$input['link_position'] = sanitize_key( $input['link_position'] );
if ( ! array_key_exists( $input['link_position'], $this->link_positions ) )
$input['link_position'] = $cn->defaults['general']['link_position'];
} else
$input['link_position'] = $cn->defaults['general']['link_position'];
// message link position?
if ( $input['see_more'] && $input['link_position'] === 'message' && strpos( $input['message_text'], '[cookies_policy_link' ) === false )
$input['message_text'] .= ' [cookies_policy_link]';
$input['update_version'] = $cn->options['general']['update_version'];
$input['update_notice'] = $cn->options['general']['update_notice'];
$input['translate'] = false;
// WPML >= 3.2
if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ) {
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Message in the notice', $input['message_text'] );
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Button text', $input['accept_text'] );
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Refuse button text', $input['refuse_text'] );
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Revoke message text', $input['revoke_message_text'] );
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Revoke button text', $input['revoke_text'] );
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Privacy policy text', $input['see_more_opt']['text'] );
if ( $input['see_more_opt']['link_type'] === 'custom' )
do_action( 'wpml_register_single_string', 'Cookie Notice', 'Custom link', $input['see_more_opt']['link'] );
}
add_settings_error( 'cn_cookie_notice_options', 'save_cookie_notice_options', esc_html__( 'Settings saved.', 'cookie-notice' ), 'updated' );
} elseif ( isset( $_POST['reset_cookie_notice_options'] ) ) {
$input = $cn->defaults['general'];
add_settings_error( 'cn_cookie_notice_options', 'reset_cookie_notice_options', esc_html__( 'Settings restored to defaults.', 'cookie-notice' ), 'updated' );
// network area?
if ( $is_network ) {
// set app data
update_site_option( 'cookie_notice_status', $cn->defaults['data'] );
} else {
// set app data
update_option( 'cookie_notice_status', $cn->defaults['data'] );
}
}
return $input;
}
/**
* Validate network options.
*
* @return void
*/
public function validate_network_options() {
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
return;
// get main instance
$cn = Cookie_Notice();
// global network page?
if ( $cn->is_network_admin() && isset( $_POST['cn-network-settings'] ) ) {
// network settings
if ( ! empty( $_POST['cookie_notice_options'] ) && check_admin_referer( 'cookie_notice_options-options', '_wpnonce' ) !== false ) {
if ( isset( $_POST['save_cookie_notice_options'] ) ) {
// validate options
$data = $this->validate_options( $_POST['cookie_notice_options'] );
// check network settings
$data['global_override'] = isset( $_POST['cookie_notice_options']['global_override'] );
$data['global_cookie'] = isset( $_POST['cookie_notice_options']['global_cookie'] );
$data['update_notice_diss'] = $cn->options['general']['update_notice_diss'];
if ( $data['global_override'] && ! $cn->options['general']['update_notice_diss'] )
$data['update_notice'] = true;
else
$data['update_notice'] = false;
// update database
update_site_option( 'cookie_notice_options', $data );
// update settings
$cn->options['general'] = $cn->multi_array_merge( $cn->defaults['general'], get_site_option( 'cookie_notice_options', $cn->defaults['general'] ) );
} elseif ( isset( $_POST['reset_cookie_notice_options'] ) ) {
$cn->defaults['general']['update_notice'] = false;
$cn->defaults['general']['update_notice_diss'] = false;
// silent options validation
$this->validate_options( $cn->defaults['general'] );
// update database
update_site_option( 'cookie_notice_options', $cn->defaults['general'] );
// update settings
$cn->options['general'] = $cn->defaults['general'];
}
}
// update status of cookie compliance
$cn->set_status_data();
}
}
/**
* Load scripts and styles - admin.
*
* @return void
*/
public function admin_enqueue_scripts( $page ) {
if ( $page === 'toplevel_page_cookie-notice' ) {
// get main instance
$cn = Cookie_Notice();
wp_enqueue_script( 'cookie-notice-admin', COOKIE_NOTICE_URL . '/js/admin' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.js', [ 'jquery', 'wp-color-picker' ], $cn->defaults['version'] );
// prepare script data
$script_data = [
'ajaxURL' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'cn-purge-cache' ),
'nonceConditional' => wp_create_nonce( 'cn-get-group-values' ),
'network' => $cn->is_network_admin(),
'resetToDefaults' => esc_html__( 'Are you sure you want to reset these settings to defaults?', 'cookie-notice' )
];
wp_add_inline_script( 'cookie-notice-admin', 'var cnArgs = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
wp_enqueue_style( 'wp-color-picker' );
}
wp_enqueue_style( 'cookie-notice-admin', COOKIE_NOTICE_URL . '/css/admin' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.css' );
}
/**
* Load admin style inline, for menu icon only.
*
* @return void
*/
public function admin_print_styles() {
echo '
<style>
a.toplevel_page_cookie-notice .wp-menu-image {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAzMjEgMzIxIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MjsiPjxwYXRoIGQ9Ik0zMTcuMjc4LDEzMC40NTFjLTAuODEyLC00LjMwMiAtNC4zMDEsLTcuNTYyIC04LjY0MiwtOC4wODFjLTQuMzU0LC0wLjUyMiAtOC41MDYsMS44MjkgLTEwLjMwNyw1LjgyMmMtMy4xNyw3LjAwMyAtMTAuMTMzLDExLjg3MyAtMTguMjA1LDExLjg2NGMtOC45NTUsMC4wMjIgLTE2LjUxNywtNi4wMjEgLTE5LjAzOCwtMTQuMzE1Yy0xLjUyMSwtNS4wNjMgLTYuNzI0LC04LjA2NCAtMTEuODY1LC02Ljg2M2MtMy4xNjMsMC43NDEgLTYuMTU0LDEuMTcyIC05LjEyNSwxLjE3MmMtMjIuMDM5LC0wLjA0MyAtMzkuOTc2LC0xNy45NzkgLTQwLjAxNSwtNDAuMDE5Yy0wLC0yLjk3IDAuNDMsLTUuOTYyIDEuMTY5LC05LjExM2MxLjIxMiwtNS4xNDEgLTEuNzk5LC0xMC4zNTMgLTYuODYsLTExLjg3M2MtOC4yOTUsLTIuNTEzIC0xNC4zMzcsLTEwLjA3NSAtMTQuMzE5LC0xOS4wMjljLTAuMDA5LC04LjA4MiA0Ljg2NCwtMTUuMDM2IDExLjg2NywtMTguMjA4YzMuOTkxLC0xLjc5OCA2LjM0MSwtNS45NjMgNS44MjIsLTEwLjMwNGMtMC41MjIsLTQuMzUxIC0zLjc4MywtNy44NDMgLTguMDg0LC04LjY1MmMtOS41NDMsLTEuNzkyIC0xOS40MjYsLTIuODUyIC0yOS42MTEsLTIuODUyYy04OC4yOTUsMC4wMjIgLTE2MC4wNDMsNzEuNzcgLTE2MC4wNjUsMTYwLjA2NWMwLjAyMiw4OC4yOTUgNzEuNzcsMTYwLjA0MyAxNjAuMDY1LDE2MC4wNjVjODguMjk1LC0wLjAyMiAxNjAuMDQzLC03MS43NyAxNjAuMDY1LC0xNjAuMDY1Yy0wLC0xMC4xODQgLTEuMDYzLC0yMC4wNjcgLTIuODUyLC0yOS42MTRabS01OC4yMjMsMTI4LjYwNGMtMjUuNDAxLDI1LjM4IC02MC4zNTUsNDEuMDY2IC05OC45OSw0MS4wNjZjLTM4LjYzNSwwIC03My41ODgsLTE1LjY4NiAtOTguOTg5LC00MS4wNjZjLTI1LjM4LC0yNS40MDEgLTQxLjA2NiwtNjAuMzU1IC00MS4wNjYsLTk4Ljk5Yy0wLC0zOC42MzUgMTUuNjg2LC03My41ODggNDEuMDY2LC05OC45ODljMjUuNDAxLC0yNS4zOCA2MC4zNTQsLTQxLjA2NiA5OC45ODksLTQxLjA2NmMxLjgwMSwwIDMuNTYsMC4xODkgNS4zNTIsMC4yNjhjLTMuMzQzLDUuODIzIC01LjM0MywxMi41MjcgLTUuMzUyLDE5LjczOGMwLjAxOCwxNC45MzUgOC4zMDQsMjcuNzQyIDIwLjM3OSwzNC41NzVjLTAuMTkyLDEuNzggLTAuMzczLDMuNTYgLTAuMzczLDUuNDRjMC4wMjIsMzMuMTI1IDI2LjkwMyw2MC4wMDcgNjAuMDI1LDYwLjAyNWMxLjg4LDAgMy42NjQsLTAuMTggNS40NDMsLTAuMzY5YzYuODMzLDEyLjA2NSAxOS42MjgsMjAuMzU2IDM0LjU3MiwyMC4zNzhjNy4yMTUsLTAuMDA5IDEzLjkxNiwtMi4wMTEgMTkuNzQxLC01LjM1MmMwLjA4LDEuNzggMC4yNjksMy41NTEgMC4yNjksNS4zNTJjLTAsMzguNjM1IC0xNS42ODYsNzMuNTg5IC00MS4wNjYsOTguOTlabS01OC45NzQsLTE4Ljk1OWMtMCwxMS4wNTIgLTguOTU4LDIwLjAxIC0yMC4wMSwyMC4wMWMtMTEuMDQ4LC0wIC0yMC4wMDUsLTguOTU4IC0yMC4wMDUsLTIwLjAxYy0wLC0xMS4wNDkgOC45NTcsLTIwLjAwNiAyMC4wMDUsLTIwLjAwNmMxMS4wNTIsLTAgMjAuMDEsOC45NTcgMjAuMDEsMjAuMDA2Wm0tODAuMDMxLC0xMC4wMDVjMCw1LjUyNiAtNC40NzksMTAuMDA1IC0xMC4wMDUsMTAuMDA1Yy01LjUyNiwtMCAtMTAuMDA1LC00LjQ3OSAtMTAuMDA1LC0xMC4wMDVjMCwtNS41MjMgNC40NzksLTEwLjAwMSAxMC4wMDUsLTEwLjAwMWM1LjUyNiwtMCAxMC4wMDUsNC40NzggMTAuMDA1LDEwLjAwMVptMTQwLjA1NSwtMjAuMDA2YzAsNS41MjYgLTQuNDc5LDEwLjAwNSAtMTAuMDA1LDEwLjAwNWMtNS41MjUsMCAtMTAuMDA1LC00LjQ3OSAtMTAuMDA1LC0xMC4wMDVjMCwtNS41MjYgNC40OCwtMTAuMDA1IDEwLjAwNSwtMTAuMDA1YzUuNTI2LDAgMTAuMDA1LDQuNDc5IDEwLjAwNSwxMC4wMDVabS0xNjAuMDY0LC01MC4wMmMtMCwxMS4wNDggLTguOTU3LDIwLjAwNiAtMjAuMDEsMjAuMDA2Yy0xMS4wNDgsMCAtMjAuMDA1LC04Ljk1OCAtMjAuMDA1LC0yMC4wMDZjLTAsLTExLjA1MiA4Ljk1NywtMjAuMDEgMjAuMDA1LC0yMC4wMWMxMS4wNTMsMCAyMC4wMSw4Ljk1OCAyMC4wMSwyMC4wMVptODAuMDMsMTAuMDA1YzAsNS41MjMgLTQuNDc4LDEwLjAwMSAtMTAuMDAxLDEwLjAwMWMtNS41MjYsMCAtMTAuMDA1LC00LjQ3OCAtMTAuMDA1LC0xMC4wMDFjMCwtNS41MjYgNC40NzksLTEwLjAwNSAxMC4wMDUsLTEwLjAwNWM1LjUyMywwIDEwLjAwMSw0LjQ3OSAxMC4wMDEsMTAuMDA1Wm0xMTUuNDkzLC02OS40MDZjMCw1LjUyNiAtNC40NzksMTAuMDA1IC0xMC4wMDUsMTAuMDA1Yy01LjUyNiwtMCAtMTAuMDA1LC00LjQ3OSAtMTAuMDA1LC0xMC4wMDVjMCwtNS41MjYgNC40NzksLTEwLjAwNSAxMC4wMDUsLTEwLjAwNWM1LjUyNiwtMCAxMC4wMDUsNC40NzkgMTAuMDA1LDEwLjAwNVptLTM1LjUyMywtMTkuODc0Yy0wLDExLjUwMyAtOS4zMjUsMjAuODI4IC0yMC44MjgsMjAuODI4Yy0xMS41MDQsLTAgLTIwLjgyOSwtOS4zMjUgLTIwLjgyOSwtMjAuODI4Yy0wLC0xMS41MDMgOS4zMjUsLTIwLjgyOCAyMC44MjksLTIwLjgyOGMxMS41MDMsLTAgMjAuODI4LDkuMzI1IDIwLjgyOCwyMC44MjhabS0xMTkuOTg1LC0wLjc1OWMtMCwxMS4wNTIgLTguOTU3LDIwLjAxIC0yMC4wMDYsMjAuMDFjLTExLjA1MiwtMCAtMjAuMDA5LC04Ljk1OCAtMjAuMDA5LC0yMC4wMWMtMCwtMTEuMDQ4IDguOTU3LC0yMC4wMDYgMjAuMDA5LC0yMC4wMDZjMTEuMDQ5LC0wIDIwLjAwNiw4Ljk1OCAyMC4wMDYsMjAuMDA2WiIgc3R5bGU9ImZpbGw6I2ZmZjtmaWxsLXJ1bGU6bm9uemVybzsiLz48L3N2Zz4=);
background-position: center center;
background-repeat: no-repeat;
background-size: 18px auto;
}
</style>
';
}
/**
* Register WPML (>= 3.2) strings if needed.
*
* @global object $wpdb
*
* @return void
*/
private function register_wpml_strings() {
// get main instance
$cn = Cookie_Notice();
global $wpdb;
// prepare strings
$strings = [
'Message in the notice' => $cn->options['general']['message_text'],
'Button text' => $cn->options['general']['accept_text'],
'Refuse button text' => $cn->options['general']['refuse_text'],
'Revoke message text' => $cn->options['general']['revoke_message_text'],
'Revoke button text' => $cn->options['general']['revoke_text'],
'Privacy policy text' => $cn->options['general']['see_more_opt']['text'],
'Custom link' => $cn->options['general']['see_more_opt']['link']
];
// get query results
$results = $wpdb->get_col( $wpdb->prepare( "SELECT name FROM " . $wpdb->prefix . "icl_strings WHERE context = %s", 'Cookie Notice' ) );
// check results
foreach( $strings as $string => $value ) {
// string does not exist?
if ( ! in_array( $string, $results, true ) ) {
// register string
do_action( 'wpml_register_single_string', 'Cookie Notice', $string, $value );
}
}
}
/**
* Display errors and notices.
*
* @global string $pagenow
*
* @return void
*/
public function settings_errors() {
global $pagenow;
// force display notices in top menu settings page
if ( $pagenow === 'options-general.php' )
return;
settings_errors( 'cn_cookie_notice_options' );
}
/**
* Save compliance config caching.
*
* @return void
*/
public function ajax_purge_cache() {
// valid nonce?
if ( ! check_ajax_referer( 'cn-purge-cache', 'nonce' ) )
exit;
// check capability
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
exit;
// request for new config data
Cookie_Notice()->welcome_api->get_app_config( '', true );
exit;
}
/**
* Generate conditions.
*
* @param array $groups
* @return string
*/
public function conditional_display( $groups ) {
$group_template = '
<div%s>
<table class="widefat">
<tbody>
%s
</tbody>
</table>
<h4 class="or-rules">' . esc_html__( 'or', 'cookie-notice' ) . '</h4>
</div>';
$rule_template = '
<tr data-rule-id="__RULE_ID__" %s>
<td class="param">
<select class="rule-type" name="cookie_notice_options[conditional_rules][__GROUP_ID__][__RULE_ID__][param]">
%s
</select>
</td>
<td class="operator">
<select name="cookie_notice_options[conditional_rules][__GROUP_ID__][__RULE_ID__][operator]">
%s
</select>
</td>
<td class="value">
<span class="spinner" style="display: none"></span>
<select name="cookie_notice_options[conditional_rules][__GROUP_ID__][__RULE_ID__][value]">
%s
</select>
</td>
<td class="remove">
<a href="#" class="dashicons dashicons-no-alt remove-rule"></a>
</td>
</tr>';
$html = sprintf(
$group_template,
' class="rules-group" id="rules-group-template" style="display: none"',
sprintf(
$rule_template,
' class="rule_template"',
$this->prepare_parameters(),
$this->prepare_operators(),
$this->prepare_values( 'page_type' )
)
) . '
<div id="cookie-notice-conditions">
<table class="widefat">
<tbody>
<tr>
<td>
<div id="rules-groups">';
if ( ! empty( $groups ) ) {
foreach ( $groups as $group_id => $group ) {
$html_rules = '';
foreach ( $group as $rule_id => $rule ) {
$html_rules .= sprintf(
str_replace(
[ '__GROUP_ID__', '__RULE_ID__' ],
[ (int) $group_id, (int) $rule_id ],
$rule_template
),
'',
$this->prepare_parameters( $rule['param'] ),
$this->prepare_operators( $rule['operator'] ),
$this->prepare_values( $rule['param'], $rule['value'] )
);
}
$html .= sprintf( str_replace( '__GROUP_ID__', $group_id, $group_template ), ' class="rules-group" id="rules-group-' . $group_id . '"', $html_rules );
}
}
$html .= ' </div>
<a class="add-rule-group button button-primary" href="#">' . esc_html__( '+ Add rule', 'cookie-notice' ) . '</a>
<p class="description">' . esc_html__( 'Create a set of rules to define the exact conditions for displaying or hiding the banner.', 'cookie-notice' ) . '</p>
</td>
</tr>
</tbody>
</table>
</div>';
return $html;
}
/**
* Prepare condition parameters.
*
* @param string $selected
* @return string
*/
public function prepare_parameters( $selected = 'page_type' ) {
$html = '';
foreach ( $this->parameters as $id => $element ) {
$html .= '<option value="' . esc_attr( $id ) . '" ' . selected( $id, $selected, false ) . '>' . esc_html( $element ) . '</option>';
}
return $html;
}
/**
* Prepare condition operators.
*
* @param string $selected
* @return string
*/
public function prepare_operators( $selected = 'equal' ) {
$html = '';
foreach ( $this->operators as $id => $operator ) {
$html .= '<option value="' . esc_attr( $id ) . '" ' . selected( $id, $selected, false ) . '>' . esc_html( $operator ) . '</option>';
}
return $html;
}
/**
* Prepare condition values.
*
* @param string $type
* @param string $selected
* @return string
*/
public function prepare_values( $type = '', $selected = '' ) {
$type = sanitize_key( $type );
$selected = sanitize_key( $selected );
$html = '';
switch ( sanitize_key( $type ) ) {
case 'page':
$pages = $this->get_pages();
if ( ! empty( $pages ) ) {
foreach ( $pages as $page_id => $page_title ) {
$html .= '<option value="' . esc_attr( $page_id ) . '" ' . selected( $page_id, $selected, false ) . '>' . esc_html( $page_title ) . '</option>';
}
}
break;
case 'page_type':
$page_types = $this->get_page_types();
if ( ! empty( $page_types ) ) {
foreach ( $page_types as $page_type => $label ) {
$html .= '<option value="' . esc_attr( $page_type ) . '" ' . selected( $page_type, $selected, false ) . '>' . esc_html( $label ) . '</option>';
}
}
break;
case 'post_type':
$post_types = $this->get_post_types();
if ( ! empty( $post_types ) ) {
foreach ( $post_types as $post_type => $label ) {
$html .= '<option value="' . esc_attr( $post_type ) . '" ' . selected( $post_type, $selected, false ) . '>' . esc_html( $label ) . '</option>';
}
}
break;
case 'user_type':
$user_types = $this->get_user_types();
if ( ! empty( $user_types ) ) {
foreach ( $user_types as $user_type => $username ) {
$html .= '<option value="' . esc_attr( $user_type ) . '" ' . selected( $user_type, $selected, false ) . '>' . esc_html( $username ).'</option>';
}
}
break;
case 'post_type_archive':
$post_type_archives = $this->get_post_type_archives();
if ( ! empty( $post_type_archives ) ) {
foreach ( $post_type_archives as $post_type => $archive_name ) {
$html .= '<option value="' . esc_attr( $post_type ) . '" ' . selected( $post_type, $selected, false ) . '>' . esc_html( $archive_name ) . '</option>';
}
} else
$html .= '<option value="__none__">' . esc_html__( '-- no public archives --', 'cookie-notice' ) . '</option>';
}
return $html;
}
/**
* Check condition rule.
*
* @param string $type
* @param string $operator
* @param string $value
* @return bool
*/
public function check_rule( $type = '', $operator = '', $value = '' ) {
if ( ! isset( $this->operators[$operator] ) )
return false;
switch( $type ) {
case 'page':
$pages = $this->get_pages();
$valid_rule = ! empty( $pages[$value] );
break;
case 'page_type':
$page_types = $this->get_page_types();
$valid_rule = ! empty( $page_types[$value] );
break;
case 'post_type':
$post_types = $this->get_post_types();
$valid_rule = ! empty( $post_types[$value] );
break;
case 'user_type':
$user_types = $this->get_user_types();
$valid_rule = ! empty( $user_types[$value] );
break;
case 'post_type_archive':
$post_type_archives = $this->get_post_type_archives();
$valid_rule = ! empty( $post_type_archives[$value] );
break;
default:
$valid_rule = false;
}
return $valid_rule;
}
/**
* Get page types.
*
* @return array
*/
public function get_pages() {
$pages = [];
// default arguments
$args = [
'post_type' => 'page',
'post__not_in' => [],
'nopaging' => true,
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'asc',
'suppress_filters' => false,
'no_found_rows' => true,
'cache_results' => false,
'post_status' => [ 'publish', 'private', 'future' ]
];
// get static home pages
$homepage = (int) get_option( 'page_for_posts', 0 );
$posts_page = (int) get_option( 'page_on_front', 0 );
// check homepage
if ( $homepage > 0 )
$args['post__not_in'][] = $homepage;
// check posts page
if ( $posts_page > 0 )
$args['post__not_in'][] = $posts_page;
$query = new WP_Query( $args );
if ( ! empty( $query->posts ) ) {
foreach ( $query->posts as $page ) {
$page_id = (int) $page->ID;
$pages[$page_id] = trim( $page->post_title ) === '' ? sprintf( __( 'Untitled Page %d', 'cookie-notice' ), $page_id ) : $page->post_title;
}
}
return $pages;
}
/**
* Get page types.
*
* @return array
*/
public function get_page_types() {
return [
'front' => __( 'Front Page', 'cookie-notice' ),
'home' => __( 'Home Page', 'cookie-notice' )
];
}
/**
* Get user types.
*
* @return array
*/
public function get_user_types() {
return [
'logged_in' => __( 'Logged in', 'cookie-notice' ),
'guest' => __( 'Guest', 'cookie-notice' )
];
}
/**
* Get public post types.
*
* @return array
*/
public function get_post_types() {
// get public post types
$post_types = get_post_types(
[
'public' => true
],
'objects',
'and'
);
$data = [];
if ( ! empty( $post_types ) ) {
foreach ( $post_types as $key => $post_type ) {
$data[$key] = $post_type->labels->singular_name;
}
}
asort( $data, SORT_STRING );
return $data;
}
/**
* Get public post type archives.
*
* @return array
*/
public function get_post_type_archives() {
// get public post types with archives
$post_types = get_post_types(
[
'has_archive' => true,
'public' => true
],
'objects',
'and'
);
$archives = [];
if ( ! empty( $post_types ) ) {
foreach ( $post_types as $key => $post_type ) {
$archives[$key] = $post_type->labels->name;
}
}
// sort archives alphabetically
asort( $archives, SORT_STRING );
return $archives;
}
/**
* Get group rule values.
*
* @return void
*/
public function get_group_rule_values() {
if ( isset( $_POST['action'], $_POST['cn_param'], $_POST['cn_nonce'] ) && wp_verify_nonce( $_POST['cn_nonce'], 'cn-get-group-values' ) !== false ) {
echo wp_json_encode(
[
'select' => $this->prepare_values( sanitize_key( $_POST['cn_param'] ) )
]
);
}
exit;
}
/**
*
*/
public function get_analytics_app_data() {
return $this->analytics_app_data;
}
/**
* Add new properties to style safe list.
*
* @param array $styles
* @return array
*/
public function allow_style_attributes( $styles ) {
$styles[] = 'display';
return $styles;
}
}
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Welcome_API class.
*
* @class Cookie_Notice_Welcome_API
*/
class Cookie_Notice_Welcome_API {
/**
* Constructor.
*
* @return void
*/
public function __construct() {
// actions
add_action( 'init', [ $this, 'check_cron' ] );
add_action( 'cookie_notice_get_app_analytics', [ $this, 'get_app_analytics' ] );
add_action( 'cookie_notice_get_app_config', [ $this, 'get_app_config' ] );
add_action( 'wp_ajax_cn_api_request', [ $this, 'api_request' ] );
}
/**
* Ajax API request.
*
* @return void
*/
public function api_request() {
// check capabilities
if ( ! current_user_can( apply_filters( 'cn_manage_cookie_notice_cap', 'manage_options' ) ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
// check main nonce
if ( ! check_ajax_referer( 'cookie-notice-welcome', 'nonce' ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
// get request
$request = isset( $_POST['request'] ) ? sanitize_key( $_POST['request'] ) : '';
// no valid request?
if ( ! in_array( $request, [ 'register', 'login', 'configure', 'select_plan', 'payment', 'get_bt_init_token', 'use_license' ], true ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
$special_actions = [ 'register', 'login', 'configure', 'payment' ];
// payment nonce
if ( $request === 'payment' )
$nonce = isset( $_POST['cn_payment_nonce'] ) ? sanitize_key( $_POST['cn_payment_nonce'] ) : '';
// special nonce
elseif ( in_array( $request, $special_actions, true ) )
$nonce = isset( $_POST['cn_nonce'] ) ? sanitize_key( $_POST['cn_nonce'] ) : '';
// check additional nonce
if ( in_array( $request, $special_actions, true ) && ! wp_verify_nonce( $nonce, 'cn_api_' . $request ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
$errors = [];
$response = false;
// get main instance
$cn = Cookie_Notice();
// get site language
$locale = get_locale();
$locale_code = explode( '_', $locale );
// check network
$network = $cn->is_network_admin();
// get app token data
if ( $network )
$data_token = get_site_transient( 'cookie_notice_app_token' );
else
$data_token = get_transient( 'cookie_notice_app_token' );
$admin_email = ! empty( $data_token->email ) ? $data_token->email : '';
$app_id = $cn->options['general']['app_id'];
$params = [];
switch ( $request ) {
case 'use_license':
$subscriptionID = isset( $_POST['subscriptionID'] ) ? (int) $_POST['subscriptionID'] : 0;
$result = $this->request(
'assign_subscription',
[
'AppID' => $app_id,
'subscriptionID' => $subscriptionID
]
);
// errors?
if ( ! empty( $result->message ) ) {
$response = [ 'error' => $result->message ];
break;
} else
$response = $result;
break;
case 'get_bt_init_token':
$result = $this->request( 'get_token' );
// is token available?
if ( ! empty( $result->token ) )
$response = [ 'token' => $result->token ];
break;
case 'payment':
$error = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
// empty data?
if ( empty( $_POST['payment_nonce'] ) || empty( $_POST['plan'] ) || empty( $_POST['method'] ) ) {
$response = $error;
break;
}
// validate plan and payment method
$available_plans = [
'compliance_monthly_notrial',
'compliance_monthly_5',
'compliance_monthly_10',
'compliance_monthly_20',
'compliance_yearly_notrial',
'compliance_yearly_5',
'compliance_yearly_10',
'compliance_yearly_20'
];
$available_payment_methods = [
'credit_card',
'paypal'
];
$plan = sanitize_key( $_POST['plan'] );
if ( ! in_array( $_POST['plan'], $available_plans, true ) )
$plan = false;
$method = sanitize_key( $_POST['method'] );
if ( ! in_array( $_POST['method'], $available_payment_methods, true ) )
$method = false;
// valid plan and payment method?
if ( empty( $plan ) || empty( $method ) ) {
$response = [ 'error' => esc_html__( 'Empty plan or payment method data.', 'cookie-notice' ) ];
break;
}
$result = $this->request(
'get_customer',
[
'AppID' => $app_id,
'PlanId' => $plan
]
);
// user found?
if ( ! empty( $result->id ) ) {
$customer = $result;
// create user
} else {
$result = $this->request(
'create_customer',
[
'AppID' => $app_id,
'AdminID' => $admin_email, // remove later - AdminID from API response
'PlanId' => $plan,
'paymentMethodNonce' => sanitize_key( $_POST['payment_nonce'] )
]
);
if ( ! empty( $result->success ) )
$customer = $result->customer;
else
$customer = $result;
}
// user created/received?
if ( empty( $customer->id ) ) {
$response = [ 'error' => esc_html__( 'Unable to create customer data.', 'cookie-notice' ) ];
break;
}
// selected payment method
$payment_method = false;
// get payment identifier (email or 4 digits)
$identifier = isset( $_POST['cn_payment_identifier'] ) ? sanitize_text_field( $_POST['cn_payment_identifier'] ) : '';
// customer available payment methods
$payment_methods = ! empty( $customer->paymentMethods ) ? $customer->paymentMethods : [];
// try to find payment method
if ( ! empty( $payment_methods ) && is_array( $payment_methods ) ) {
foreach ( $payment_methods as $pm ) {
// paypal
if ( isset( $pm->email ) && $pm->email === $identifier )
$payment_method = $pm;
// credit card
elseif ( isset( $pm->last4 ) && $pm->last4 === $identifier )
$payment_method = $pm;
}
}
// if payment method was not identified, create it
if ( ! $payment_method ) {
$result = $this->request(
'create_payment_method',
[
'AppID' => $app_id,
'paymentMethodNonce' => sanitize_key( $_POST['payment_nonce'] )
]
);
// payment method created successfully?
if ( ! empty( $result->success ) ) {
$payment_method = $result->paymentMethod;
} else {
$response = [ 'error' => esc_html__( 'Unable to create payment mehotd.', 'cookie-notice' ) ];
break;
}
}
if ( ! isset( $payment_method->token ) ) {
$response = [ 'error' => esc_html__( 'No payment method token.', 'cookie-notice' ) ];
break;
}
// @todo: check if subscription exists
$subscription = $this->request(
'create_subscription',
[
'AppID' => $app_id,
'PlanId' => $plan,
'paymentMethodToken' => $payment_method->token
]
);
// subscription assigned?
if ( ! empty( $subscription->error ) ) {
$response = $subscription->error;
break;
}
$status_data = $cn->defaults['data'];
// update app status
if ( $network ) {
$status_data = get_site_option( 'cookie_notice_status', $status_data );
$status_data['subscription'] = 'pro';
update_site_option( 'cookie_notice_status', $status_data );
} else {
$status_data = get_option( 'cookie_notice_status', $status_data );
$status_data['subscription'] = 'pro';
update_option( 'cookie_notice_status', $status_data );
}
$response = $app_id;
break;
case 'register':
// check terms
$terms = isset( $_POST['terms'] );
// no terms?
if ( ! $terms ) {
$response = [ 'error' => esc_html__( 'Please accept the Terms of Service to proceed.', 'cookie-notice' ) ];
break;
}
// check email
$email = isset( $_POST['email'] ) ? is_email( $_POST['email'] ) : false;
// empty email?
if ( ! $email ) {
$response = [ 'error' => esc_html__( 'Email is not allowed to be empty.', 'cookie-notice' ) ];
break;
}
// check passwords
$pass = ! empty( $_POST['pass'] ) ? stripslashes( $_POST['pass'] ) : '';
$pass2 = ! empty( $_POST['pass2'] ) ? stripslashes( $_POST['pass2'] ) : '';
// empty password?
if ( ! $pass || ! is_string( $pass ) ) {
$response = [ 'error' => esc_html__( 'Password is not allowed to be empty.', 'cookie-notice' ) ];
break;
}
// invalid password?
if ( preg_match( '/^(?=.*[A-Z])(?=.*\d)[\w !"#$%&\'()*\+,\-.\/:;<=>?@\[\]^\`\{\|\}\~\\\\]{8,}$/', $pass ) !== 1 ) {
$response = [ 'error' => esc_html__( 'The password contains illegal characters or does not meet the conditions.', 'cookie-notice' ) ];
break;
}
// no match?
if ( $pass !== $pass2 ) {
$response = [ 'error' => esc_html__( 'Passwords do not match.', 'cookie-notice' ) ];
break;
}
$params = [
'AdminID' => $email,
'Password' => $pass,
'Language' => ! empty( $_POST['language'] ) ? sanitize_key( $_POST['language'] ) : 'en'
];
$response = $this->request( 'register', $params );
// errors?
if ( ! empty( $response->error ) )
break;
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
// ok, so log in now
$params = [
'AdminID' => $email,
'Password' => $pass
];
$response = $this->request( 'login', $params );
// errors?
if ( ! empty( $response->error ) )
break;
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
// token in response?
if ( empty( $response->data->token ) ) {
$response = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
break;
}
// set token
if ( $network )
set_site_transient( 'cookie_notice_app_token', $response->data, 24 * HOUR_IN_SECONDS );
else
set_transient( 'cookie_notice_app_token', $response->data, 24 * HOUR_IN_SECONDS );
// multisite?
if ( is_multisite() ) {
switch_to_blog( 1 );
$site_title = get_bloginfo( 'name' );
$site_url = network_site_url();
$site_description = get_bloginfo( 'description' );
restore_current_blog();
} else {
$site_title = get_bloginfo( 'name' );
$site_url = get_home_url();
$site_description = get_bloginfo( 'description' );
}
// create new app, no need to check existing
$params = [
'DomainName' => $site_title,
'DomainUrl' => $site_url
];
if ( ! empty( $site_description ) )
$params['DomainDescription'] = $site_description;
$response = $this->request( 'app_create', $params );
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
// data in response?
if ( empty( $response->data->AppID ) || empty( $response->data->SecretKey ) ) {
$response = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
break;
} else {
$app_id = $response->data->AppID;
$secret_key = $response->data->SecretKey;
}
// update options: app id and secret key
$cn->options['general'] = wp_parse_args( [ 'app_id' => $app_id, 'app_key' => $secret_key ], $cn->options['general'] );
if ( $network ) {
$cn->options['general']['global_override'] = true;
update_site_option( 'cookie_notice_options', $cn->options['general'] );
// get options
$app_config = get_site_transient( 'cookie_notice_app_quick_config' );
} else {
update_option( 'cookie_notice_options', $cn->options['general'] );
// get options
$app_config = get_transient( 'cookie_notice_app_quick_config' );
}
// create quick config
$params = ! empty( $app_config ) && is_array( $app_config ) ? $app_config : [];
// cast to objects
if ( $params ) {
$new_params = [];
foreach ( $params as $key => $array ) {
$object = new stdClass();
foreach ( $array as $subkey => $value ) {
$new_params[$key] = $object;
$new_params[$key]->{$subkey} = $value;
}
}
$params = $new_params;
}
$params['AppID'] = $app_id;
// @todo When mutliple default languages are supported
$params['DefaultLanguage'] = 'en';
if ( ! array_key_exists( 'text', $params ) )
$params['text'] = new stdClass();
// add privacy policy url
$params['text']->privacyPolicyUrl = get_privacy_policy_url();
// add translations if needed
if ( $locale_code[0] !== 'en' )
$params['Languages'] = [ $locale_code[0] ];
$response = $this->request( 'quick_config', $params );
$status_data = $cn->defaults['data'];
if ( $response->status === 200 ) {
// notify publish app
$params = [
'AppID' => $app_id
];
$response = $this->request( 'notify_app', $params );
if ( $response->status === 200 ) {
$response = true;
$status_data['status'] = 'active';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
} else {
$status_data['status'] = 'pending';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
// errors?
if ( ! empty( $response->error ) )
break;
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
}
} else {
$status_data['status'] = 'pending';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
// errors?
if ( ! empty( $response->error ) ) {
$response->error = $response->error;
break;
}
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
}
break;
case 'login':
// check email
$email = isset( $_POST['email'] ) ? is_email( $_POST['email'] ) : false;
// invalid email?
if ( ! $email ) {
$response = [ 'error' => esc_html__( 'Email is not allowed to be empty.', 'cookie-notice' ) ];
break;
}
// check password
$pass = ! empty( $_POST['pass'] ) ? preg_replace( '/[^\w !"#$%&\'()*\+,\-.\/:;<=>?@\[\]^\`\{\|\}\~\\\\]/', '', $_POST['pass'] ) : '';
// empty password?
if ( ! $pass ) {
$response = [ 'error' => esc_html__( 'Password is not allowed to be empty.', 'cookie-notice' ) ];
break;
}
$params = [
'AdminID' => $email,
'Password' => $pass
];
$response = $this->request( $request, $params );
// errors?
if ( ! empty( $response->error ) )
break;
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
// token in response?
if ( empty( $response->data->token ) ) {
$response = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
break;
}
// set token
if ( $network )
set_site_transient( 'cookie_notice_app_token', $response->data, 24 * HOUR_IN_SECONDS );
else
set_transient( 'cookie_notice_app_token', $response->data, 24 * HOUR_IN_SECONDS );
// get apps and check if one for the current domain already exists
$response = $this->request( 'list_apps', [] );
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
$apps_list = [];
$app_exists = false;
// multisite?
if ( is_multisite() ) {
switch_to_blog( 1 );
$site_title = get_bloginfo( 'name' );
$site_url = network_site_url();
$site_description = get_bloginfo( 'description' );
restore_current_blog();
} else {
$site_title = get_bloginfo( 'name' );
$site_url = get_home_url();
$site_description = get_bloginfo( 'description' );
}
// apps added, check if current one exists
if ( ! empty( $response->data ) ) {
$apps_list = (array) $response->data;
foreach ( $apps_list as $index => $app ) {
$site_without_http = trim( str_replace( [ 'http://', 'https://' ], '', $site_url ), '/' );
if ( $app->DomainUrl === $site_without_http ) {
$app_exists = $app;
continue;
}
}
}
// if no app, create one
if ( ! $app_exists ) {
// create new app
$params = [
'DomainName' => $site_title,
'DomainUrl' => $site_url,
];
if ( ! empty( $site_description ) )
$params['DomainDescription'] = $site_description;
$response = $this->request( 'app_create', $params );
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
$app_exists = $response->data;
}
// check if we have the valid app data
if ( empty( $app_exists->AppID ) || empty( $app_exists->SecretKey ) ) {
$response = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
break;
}
// get subscriptions
$subscriptions = [];
$params = [
'AppID' => $app_exists->AppID
];
$response = $this->request( 'get_subscriptions', $params );
// errors?
if ( ! empty( $response->error ) ) {
$response->error = $response->error;
break;
} else
$subscriptions = map_deep( (array) $response->data, 'sanitize_text_field' );
// set subscriptions data
if ( $network )
set_site_transient( 'cookie_notice_app_subscriptions', $subscriptions, 24 * HOUR_IN_SECONDS );
else
set_transient( 'cookie_notice_app_subscriptions', $subscriptions, 24 * HOUR_IN_SECONDS );
// update options: app ID and secret key
$cn->options['general'] = wp_parse_args( [ 'app_id' => $app_exists->AppID, 'app_key' => $app_exists->SecretKey ], $cn->options['general'] );
if ( $network ) {
$cn->options['general']['global_override'] = true;
update_site_option( 'cookie_notice_options', $cn->options['general'] );
} else {
update_option( 'cookie_notice_options', $cn->options['general'] );
}
// create quick config
$params = [
'AppID' => $app_exists->AppID,
'DefaultLanguage' => 'en',
'text' => new stdClass()
];
// add privacy policy url
$params['text']->privacyPolicyUrl = get_privacy_policy_url();
// add translations if needed
if ( $locale_code[0] !== 'en' )
$params['Languages'] = [ $locale_code[0] ];
$response = $this->request( 'quick_config', $params );
$status_data = $cn->defaults['data'];
if ( $response->status === 200 ) {
// @todo notify publish app
$params = [
'AppID' => $app_exists->AppID
];
$response = $this->request( 'notify_app', $params );
if ( $response->status === 200 ) {
$response = true;
$status_data['status'] = 'active';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
} else {
$status_data['status'] = 'pending';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
// errors?
if ( ! empty( $response->error ) )
break;
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
}
} else {
$status_data['status'] = 'pending';
// update app status
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data );
// errors?
if ( ! empty( $response->error ) ) {
$response->error = $response->error;
break;
}
// errors?
if ( ! empty( $response->message ) ) {
$response->error = $response->message;
break;
}
}
// all ok, return subscriptions
$response = (object) [];
$response->subscriptions = $subscriptions;
break;
case 'configure':
$fields = [
'cn_position',
'cn_color_primary',
'cn_color_background',
'cn_color_border',
'cn_color_text',
'cn_color_heading',
'cn_color_button_text',
'cn_laws',
'cn_naming',
'cn_privacy_paper',
'cn_privacy_contact'
];
$options = [];
// loop through potential config form fields
foreach ( $fields as $field ) {
switch ( $field ) {
case 'cn_position':
// sanitize position
$position = isset( $_POST[$field] ) ? sanitize_key( $_POST[$field] ) : '';
// valid position?
if ( in_array( $position, [ 'bottom', 'top', 'left', 'right', 'center' ], true ) )
$options['design']['position'] = $position;
else
$options['design']['position'] = 'bottom';
break;
case 'cn_color_primary':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['primaryColor'] = '#20c19e';
else
$options['design']['primaryColor'] = $color;
break;
case 'cn_color_background':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['bannerColor'] = '#ffffff';
else
$options['design']['bannerColor'] = $color;
break;
case 'cn_color_border':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['borderColor'] = '#5e6a74';
else
$options['design']['borderColor'] = $color;
break;
case 'cn_color_text':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['textColor'] = '#434f58';
else
$options['design']['textColor'] = $color;
break;
case 'cn_color_heading':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['headingColor'] = '#434f58';
else
$options['design']['headingColor'] = $color;
break;
case 'cn_color_button_text':
// sanitize color
$color = isset( $_POST[$field] ) ? sanitize_hex_color( $_POST[$field] ) : '';
// valid color?
if ( empty( $color ) )
$options['design']['btnTextColor'] = '#ffffff';
else
$options['design']['btnTextColor'] = $color;
break;
case 'cn_laws':
$new_options = [];
// any data?
if ( ! empty( $_POST[$field] ) && is_array( $_POST[$field] ) ) {
$options['laws'] = array_map( 'sanitize_text_field', $_POST[$field] );
foreach ( $options['laws'] as $law ) {
if ( in_array( $law, [ 'gdpr', 'ccpa' ], true ) )
$new_options[$law] = true;
}
}
$options['laws'] = $new_options;
// GDPR
if ( array_key_exists( 'gdpr', $options['laws'] ) )
$options['config']['privacyPolicyLink'] = true;
else
$options['config']['privacyPolicyLink'] = false;
// CCPA
if ( array_key_exists( 'ccpa', $options['laws'] ) )
$options['config']['dontSellLink'] = true;
else
$options['config']['dontSellLink'] = false;
break;
case 'cn_naming':
$naming = isset( $_POST[$field] ) ? (int) $_POST[$field] : 1;
$naming = in_array( $naming, [ 1, 2, 3 ] ) ? $naming : 1;
// english only for now
$level_names = [
1 => [
1 => 'Silver',
2 => 'Gold',
3 => 'Platinum'
],
2 => [
1 => 'Private',
2 => 'Balanced',
3 => 'Personalized'
],
3 => [
1 => 'Reject All',
2 => 'Accept Some',
3 => 'Accept All'
]
];
$options['text'] = [
'levelNameText_1' => $level_names[$naming][1],
'levelNameText_2' => $level_names[$naming][2],
'levelNameText_3' => $level_names[$naming][3]
];
break;
case 'cn_privacy_paper':
$options['config']['privacyPaper'] = false; // isset( $_POST[$field] );
break;
case 'cn_privacy_contact':
$options['config']['privacyContact'] = false; // isset( $_POST[$field] );
break;
}
}
// set options
if ( $network )
set_site_transient( 'cookie_notice_app_quick_config', $options, 24 * HOUR_IN_SECONDS );
else
set_transient( 'cookie_notice_app_quick_config', $options, 24 * HOUR_IN_SECONDS );
break;
case 'select_plan':
break;
}
echo wp_json_encode( $response );
exit;
}
/**
* API request.
*
* @param string $request The requested action.
* @param array $params Parameters for the API action.
* @return string|array
*/
private function request( $request = '', $params = [] ) {
// get main instance
$cn = Cookie_Notice();
$api_args = [
'timeout' => 60,
'sslverify' => false,
'headers' => [
'x-api-key' => $cn->get_api_key()
]
];
$api_params = [];
$json = false;
// check network
$network = $cn->is_network_admin();
// get app token data
if ( $network )
$data_token = get_site_transient( 'cookie_notice_app_token' );
else
$data_token = get_transient( 'cookie_notice_app_token' );
$api_token = ! empty( $data_token->token ) ? $data_token->token : '';
switch ( $request ) {
case 'register':
$api_url = $cn->get_url( 'account_api', '/api/account/account/registration' );
$api_args['method'] = 'POST';
break;
case 'login':
$api_url = $cn->get_url( 'account_api', '/api/account/account/login' );
$api_args['method'] = 'POST';
break;
case 'list_apps':
$api_url = $cn->get_url( 'account_api', '/api/account/app/list' );
$api_args['method'] = 'GET';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token
]
);
break;
case 'app_create':
$api_url = $cn->get_url( 'account_api', '/api/account/app/add' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token
]
);
break;
case 'get_analytics':
$api_url = $cn->get_url( 'transactional_api', '/api/transactional/analytics/analytics-data' );
$api_args['method'] = 'GET';
$diff_data = $cn->settings->get_analytics_app_data();
if ( ! empty( $diff_data ) ) {
$app_data = [
'app-id' => $diff_data['id'],
'app-secret-key' => $diff_data['key']
];
} else {
$app_data = [
'app-id' => $cn->options['general']['app_id'],
'app-secret-key' => $cn->options['general']['app_key']
];
}
$api_args['headers'] = array_merge( $api_args['headers'], $app_data );
break;
case 'get_config':
$api_url = $cn->get_url( 'designer_api', '/api/designer/user-design-live' );
$api_args['method'] = 'GET';
break;
case 'quick_config':
$json = true;
$api_url = $cn->get_url( 'designer_api', '/api/designer/user-design/quick' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
case 'notify_app':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/app/notifyAppPublished' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree init token
case 'get_token':
$api_url = $cn->get_url( 'account_api', '/api/account/braintree' );
$api_args['method'] = 'GET';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token
]
);
break;
// braintree get customer
case 'get_customer':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/findcustomer' );
$api_args['method'] = 'POST';
$api_args['data_format'] = 'body';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree create customer in vault
case 'create_customer':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/createcustomer' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree get subscriptions
case 'get_subscriptions':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/subscriptionlists' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree create subscription
case 'create_subscription':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/createsubscription' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree assign subscription
case 'assign_subscription':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/assignsubscription' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
// braintree create payment method
case 'create_payment_method':
$json = true;
$api_url = $cn->get_url( 'account_api', '/api/account/braintree/createpaymentmethod' );
$api_args['method'] = 'POST';
$api_args['headers'] = array_merge(
$api_args['headers'],
[
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json; charset=utf-8'
]
);
break;
}
if ( ! empty( $params ) && is_array( $params ) ) {
foreach ( $params as $key => $param ) {
if ( is_object( $param ) )
$api_params[$key] = $param;
elseif ( is_array( $param ) )
$api_params[$key] = array_map( 'sanitize_text_field', $param );
elseif ( $key === 'Password' && ( $request === 'register' || $request === 'login' ) )
$api_params[$key] = preg_replace( '/[^\w !"#$%&\'()*\+,\-.\/:;<=>?@\[\]^\`\{\|\}\~\\\\]/', '', $param );
else
$api_params[$key] = sanitize_text_field( $param );
}
if ( $json )
$api_args['body'] = wp_json_encode( $api_params );
else
$api_args['body'] = $api_params;
}
$response = wp_remote_request( $api_url, $api_args );
if ( is_wp_error( $response ) )
$result = [ 'error' => $response->get_error_message() ];
else {
$content_type = wp_remote_retrieve_header( $response, 'Content-Type' );
// html response, means error
if ( $content_type == 'text/html' )
$result = [ 'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ) ];
else {
$result = wp_remote_retrieve_body( $response );
// detect json or array
$result = is_array( $result ) ? $result : json_decode( $result );
}
}
return $result;
}
/**
* Check whether WP Cron needs to add new task.
*
* @return void
*/
public function check_cron() {
// get main instance
$cn = Cookie_Notice();
if ( is_multisite() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
$app_id = $cn->network_options['app_id'];
$app_key = $cn->network_options['app_key'];
} else {
$app_id = $cn->options['general']['app_id'];
$app_key = $cn->options['general']['app_key'];
}
// compliance active only
if ( $app_id !== '' && $app_key !== '' ) {
if ( $cn->get_status() === 'active' )
$recurrence = 'daily';
else
$recurrence = 'hourly';
// set schedule if needed
if ( ! wp_next_scheduled( 'cookie_notice_get_app_analytics' ) )
wp_schedule_event( time(), 'hourly', 'cookie_notice_get_app_analytics' );
// set schedule if needed
if ( ! wp_next_scheduled( 'cookie_notice_get_app_config' ) )
wp_schedule_event( time(), $recurrence, 'cookie_notice_get_app_config' );
} else {
// remove schedule if needed
if ( wp_next_scheduled( 'cookie_notice_get_app_analytics' ) )
wp_clear_scheduled_hook( 'cookie_notice_get_app_analytics' );
// remove schedule if needed
if ( wp_next_scheduled( 'cookie_notice_get_app_config' ) )
wp_clear_scheduled_hook( 'cookie_notice_get_app_config' );
}
}
/**
* Get app analytics.
*
* @param string $app_id
* @param bool $force_update
* @return void
*/
public function get_app_analytics( $app_id = '', $force_update = false ) {
// get main instance
$cn = Cookie_Notice();
$allow_one_cron_per_hour = false;
if ( is_multisite() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
if ( empty( $app_id ) )
$app_id = $cn->network_options['app_id'];
$network = true;
$allow_one_cron_per_hour = true;
} else {
if ( empty( $app_id ) )
$app_id = $cn->options['general']['app_id'];
$network = false;
}
// in global override mode allow only one cron per hour
if ( $allow_one_cron_per_hour && ! $force_update ) {
$analytics = get_site_option( 'cookie_notice_app_analytics', [] );
// analytics data?
if ( ! empty( $analytics ) ) {
$updated = strtotime( $analytics['lastUpdated'] );
// last updated less than an hour?
if ( $updated !== false && current_time( 'timestamp', true ) - $updated < 3600 )
return;
}
}
$response = $this->request(
'get_analytics',
[
'AppID' => $app_id
]
);
// get analytics
if ( ! empty( $response->data ) ) {
$result = map_deep( (array) $response->data, 'sanitize_text_field' );
// add time updated
$result['lastUpdated'] = date( 'Y-m-d H:i:s', current_time( 'timestamp', true ) );
// get default status data
$status_data = $cn->defaults['data'];
// update status
$status_data['status'] = $cn->get_status();
// update subscription
$status_data['subscription'] = $cn->get_subscription();
if ( $status_data['status'] === 'active' && $status_data['subscription'] === 'basic' ) {
$threshold = ! empty( $result['cycleUsage']->threshold ) ? (int) $result['cycleUsage']->threshold : 0;
$visits = ! empty( $result['cycleUsage']->visits ) ? (int) $result['cycleUsage']->visits : 0;
if ( $visits >= $threshold && $threshold > 0 )
$status_data['threshold_exceeded'] = true;
}
if ( $network ) {
update_site_option( 'cookie_notice_app_analytics', $result );
update_site_option( 'cookie_notice_status', $status_data );
} else {
update_option( 'cookie_notice_app_analytics', $result, false );
update_option( 'cookie_notice_status', $status_data, false );
}
}
}
/**
* Get app config.
*
* @param string $app_id
* @param bool $force_update
* @return void|array
*/
public function get_app_config( $app_id = '', $force_update = false ) {
// get main instance
$cn = Cookie_Notice();
$allow_one_cron_per_hour = false;
if ( is_multisite() && $cn->is_plugin_network_active() && $cn->network_options['global_override'] ) {
if ( empty( $app_id ) )
$app_id = $cn->network_options['app_id'];
$network = true;
$allow_one_cron_per_hour = true;
} else {
if ( empty( $app_id ) )
$app_id = $cn->options['general']['app_id'];
$network = false;
}
// in global override mode allow only one cron per hour
if ( $allow_one_cron_per_hour && ! $force_update ) {
$blocking = get_site_option( 'cookie_notice_app_blocking', [] );
// analytics data?
if ( ! empty( $blocking ) ) {
$updated = strtotime( $blocking['lastUpdated'] );
// last updated less than an hour?
if ( $updated !== false && current_time( 'timestamp', true ) - $updated < 3600 )
return;
}
}
// get config
$response = $this->request(
'get_config',
[
'AppID' => $app_id
]
);
// get status data
$status_data = $cn->defaults['data'];
// get config
if ( ! empty( $response->data ) ) {
// sanitize data
$result_raw = map_deep( (array) $response->data, 'sanitize_text_field' );
// set status
$status_data['status'] = 'active';
// check subscription
if ( ! empty( $result_raw['SubscriptionType'] ) )
$status_data['subscription'] = $cn->check_subscription( strtolower( $result_raw['SubscriptionType'] ) );
if ( $status_data['subscription'] === 'basic' ) {
// get analytics data options
if ( $network )
$analytics = get_site_option( 'cookie_notice_app_analytics', [] );
else
$analytics = get_option( 'cookie_notice_app_analytics', [] );
if ( ! empty( $analytics ) ) {
$threshold = ! empty( $analytics['cycleUsage']->threshold ) ? (int) $analytics['cycleUsage']->threshold : 0;
$visits = ! empty( $analytics['cycleUsage']->visits ) ? (int) $analytics['cycleUsage']->visits : 0;
if ( $visits >= $threshold && $threshold > 0 )
$status_data['threshold_exceeded'] = true;
}
}
// process blocking data
$result = [
'categories' => ! empty( $result_raw['DefaultCategoryJSON'] ) && is_array( $result_raw['DefaultCategoryJSON'] ) ? $result_raw['DefaultCategoryJSON'] : [],
'providers' => ! empty( $result_raw['DefaultProviderJSON'] ) && is_array( $result_raw['DefaultProviderJSON'] ) ? $result_raw['DefaultProviderJSON'] : [],
'patterns' => ! empty( $result_raw['DefaultCookieJSON'] ) && is_array( $result_raw['DefaultCookieJSON'] ) ? $result_raw['DefaultCookieJSON'] : [],
'lastUpdated' => date( 'Y-m-d H:i:s', current_time( 'timestamp', true ) )
];
if ( $network )
update_site_option( 'cookie_notice_app_blocking', $result );
else
update_option( 'cookie_notice_app_blocking', $result, false );
} else {
if ( ! empty( $response->error ) ) {
if ( $response->error == 'App is not puplised yet' )
$status_data['status'] = 'pending';
else
$status_data['status'] = '';
}
}
if ( $network )
update_site_option( 'cookie_notice_status', $status_data );
else
update_option( 'cookie_notice_status', $status_data, false );
return $status_data;
}
}
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Welcome_Frontend class.
*
* @class Cookie_Notice_Welcome_Frontend
*/
class Cookie_Notice_Welcome_Frontend {
private $preview_mode = false;
/**
* Constructor.
*
* @return void
*/
public function __construct() {
add_action( 'after_setup_theme', [ $this, 'preview_init' ], 1 );
}
/**
* Initialize preview mode.
*
* @return void
*/
public function preview_init() {
// check preview mode
$this->preview_mode = isset( $_GET['cn_preview_mode'] ) ? (int) $_GET['cn_preview_mode'] : false;
if ( $this->preview_mode !== false ) {
// filters
add_filter( 'show_admin_bar', '__return_false' );
add_filter( 'cn_cookie_notice_output', '__return_false', 1000 );
// actions
add_action( 'wp_enqueue_scripts', [ $this, 'wp_dequeue_scripts' ] );
// only in live preview
if ( $this->preview_mode === 1 ) {
add_action( 'wp_enqueue_scripts', [ $this, 'wp_enqueue_scripts' ] );
add_action( 'wp_head', [ $this, 'wp_head_scripts' ], 0 );
}
}
}
/**
* Load scripts and styles.
*
* @return void
*/
public function wp_enqueue_scripts() {
// get main instance
$cn = Cookie_Notice();
// show only in live preview
if ( $this->preview_mode === 1 ) {
wp_enqueue_script( 'cookie-notice-welcome-frontend', COOKIE_NOTICE_URL . '/js/front-welcome.js', [ 'jquery', 'underscore' ], $cn->defaults['version'] );
// prepare script data
$script_data = [
'previewMode' => $this->preview_mode,
'allowedURLs' => $this->get_allowed_urls(),
'levelNames' => $cn->settings->level_names,
'textStrings' => $cn->settings->text_strings
];
wp_add_inline_script( 'cookie-notice-welcome-frontend', 'var cnFrontWelcome = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
}
}
/**
* Unload scripts and styles.
*
* @return void
*/
public function wp_dequeue_scripts() {
// deregister native cookie notice script
wp_dequeue_script( 'cookie-notice-front' );
}
/**
* Load cookie compliance script.
*
* @return void
*/
public function wp_head_scripts() {
$options = [
'currentLanguage' => 'en',
'previewMode' => true,
'debugMode' => true,
'config' => [
'privacyPaper' => true,
'privacyContact' => true
]
];
echo '
<!-- Cookie Compliance -->
<script type="text/javascript">
var huOptions = ' . wp_json_encode( $options ) . ';
</script>
<script type="text/javascript" src="' . esc_url( Cookie_Notice()->get_url( 'widget' ) ) . '"></script>
<style>.hu-preview-mode #hu::after {content: "";position: fixed;width: 100%;height: 100%;display: block;top: 0;left: 0}</style>';
}
/**
* Get URLs allowed to be previewed.
*
* @return array
*/
public function get_allowed_urls() {
$allowed_urls = [ home_url( '/' ) ];
if ( is_ssl() && ! $this->is_cross_domain() )
$allowed_urls[] = home_url( '/', 'https' );
return $allowed_urls;
}
/**
* Determines whether the admin and the frontend are on different domains.
*
* @return bool
*/
public function is_cross_domain() {
$admin_origin = wp_parse_url( admin_url() );
$home_origin = wp_parse_url( home_url() );
return ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) );
}
}
\ No newline at end of file
<?php
// exit if accessed directly
if ( ! defined( 'ABSPATH' ) )
exit;
/**
* Cookie_Notice_Welcome class.
*
* @class Cookie_Notice_Welcome
*/
class Cookie_Notice_Welcome {
private $pricing_monthly = [];
private $pricing_yearly = [];
/**
* Constructor.
*
* @return void
*/
public function __construct() {
// actions
add_action( 'plugins_loaded', [ $this, 'allow_protocols' ] );
add_action( 'admin_init', [ $this, 'init' ] );
add_action( 'admin_init', [ $this, 'welcome' ] );
add_action( 'wp_ajax_cn_welcome_screen', [ $this, 'welcome_screen' ] );
}
/**
* Allow new protocols.
*
* @return void
*/
function allow_protocols() {
// allow only ajax calls
if ( ! wp_doing_ajax() )
return;
// get action
$action = isset( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : '';
// welcome screen?
if ( $action === 'cn_welcome_screen' )
add_filter( 'kses_allowed_protocols', [ $this, 'allow_data_protocol' ] );
}
/**
* Add new properties to style safe list.
*
* @param array $styles
* @return array
*/
public function allow_style_attributes( $styles ) {
$styles[] = 'display';
return $styles;
}
/**
* Add data protocol to image source.
*
* @param array $protocols
* @return array
*/
public function allow_data_protocol( $protocols ) {
$protocols[] = 'data';
return $protocols;
}
/**
* Load defaults.
*
* @return void
*/
public function init() {
$this->pricing_monthly = [
'compliance_monthly_notrial' => '14.95',
'compliance_monthly_5' => '29.95',
'compliance_monthly_10' => '49.95',
'compliance_monthly_20' => '69.95'
];
$this->pricing_yearly = [
'compliance_yearly_notrial' => '149.50',
'compliance_yearly_5' => '299.50',
'compliance_yearly_10' => '499.50',
'compliance_yearly_20' => '699.50'
];
}
/**
* Load scripts and styles - admin.
*
* @return void
*/
public function admin_enqueue_scripts( $page ) {
// get main instance
$cn = Cookie_Notice();
if ( $cn->check_status( $cn->get_status() ) )
return;
// styles
wp_enqueue_style( 'dashicons' );
wp_enqueue_style( 'cookie-notice-modaal', COOKIE_NOTICE_URL . '/assets/modaal/css/modaal.min.css', [], $cn->defaults['version'] );
wp_enqueue_style( 'cookie-notice-spectrum', COOKIE_NOTICE_URL . '/assets/spectrum/spectrum.min.css', [], $cn->defaults['version'] );
wp_enqueue_style( 'cookie-notice-microtip', COOKIE_NOTICE_URL . '/assets/microtip/microtip.min.css', [], $cn->defaults['version'] );
// scripts
wp_enqueue_script( 'cookie-notice-modaal', COOKIE_NOTICE_URL . '/assets/modaal/js/modaal.min.js', [], $cn->defaults['version'] );
wp_enqueue_script( 'cookie-notice-spectrum', COOKIE_NOTICE_URL . '/assets/spectrum/spectrum.min.js', [], $cn->defaults['version'] );
wp_enqueue_script( 'cookie-notice-welcome', COOKIE_NOTICE_URL . '/js/admin-welcome.js', [ 'jquery', 'jquery-ui-core', 'jquery-ui-progressbar' ], $cn->defaults['version'] );
wp_enqueue_script( 'cookie-notice-braintree-client', 'https://js.braintreegateway.com/web/3.71.0/js/client.min.js', [], null, false );
wp_enqueue_script( 'cookie-notice-braintree-hostedfields', 'https://js.braintreegateway.com/web/3.71.0/js/hosted-fields.min.js', [], null, false );
wp_enqueue_script( 'cookie-notice-braintree-paypal', 'https://js.braintreegateway.com/web/3.71.0/js/paypal-checkout.min.js', [], null, false );
// check network
$network = $cn->is_network_admin();
// prepare script data
$script_data = [
'ajaxURL' => admin_url( 'admin-ajax.php' ),
'network' => $network,
'nonce' => wp_create_nonce( 'cookie-notice-welcome' ),
'cnNonce' => wp_create_nonce( 'cookie-notice-welcome' ),
'initModal' => $network ? get_site_transient( 'cn_show_welcome' ) : get_transient( 'cn_show_welcome' ), // welcome modal
'error' => esc_html__( 'Unexpected error occurred. Please try again later.', 'cookie-notice' ),
'statusPassed' => esc_html__( 'Passed', 'cookie-notice' ),
'statusFailed' => esc_html__( 'Failed', 'cookie-notice' ),
'paidMonth' => esc_html__( 'monthly', 'cookie-notice' ),
'paidYear' => esc_html__( 'yearly', 'cookie-notice' ),
'pricingMonthly' => $this->pricing_monthly,
'pricingYearly' => $this->pricing_yearly,
'complianceStatus' => $cn->get_status(),
'complianceFailed' => sprintf( esc_html__( '%sCompliance Failed!%sYour website does not achieve minimum viable compliance. %sSign up to Cookie Compliance%s to bring your site into compliance with the latest data privacy rules and regulations.', 'cookie-notice' ), '<em>', '</em>', '<b><a href="#" class="cn-sign-up">', '</a></b>' ),
'compliancePassed' => sprintf( esc_html__( '%sCompliance Passed!%sCongratulations. Your website meets minimum viable compliance.', 'cookie-notice' ), '<em>', '</em>' ),
'licensesAvailable' => esc_html__( 'available', 'cookie-notice' ),
'invalidFields' => esc_html__( 'Please fill all the required fields.', 'cookie-notice' )
];
// delete the show modal transient
if ( $network )
delete_site_transient( 'cn_show_welcome' );
else
delete_transient( 'cn_show_welcome' );
wp_add_inline_script( 'cookie-notice-welcome', 'var cnWelcomeArgs = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
wp_enqueue_style( 'cookie-notice-welcome', COOKIE_NOTICE_URL . '/css/admin-welcome.css' );
}
/**
* Send user to the welcome page on first activation.
*
* @global string $pagenow
*
* @return void
*/
public function welcome() {
global $pagenow;
if ( $pagenow !== 'admin.php' )
return;
// get page
$page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
if ( $page !== 'cookie-notice' )
return;
// bail if bulk activating or within an iframe
if ( isset( $_GET['activate-multi'] ) || defined( 'IFRAME_REQUEST' ) )
return;
// get action
$action = isset( $_GET['action'] ) ? sanitize_key( $_GET['action'] ) : '';
// get plugin
$plugin = isset( $_GET['plugin'] ) ? sanitize_file_name( $_GET['plugin'] ) : '';
if ( $action === 'upgrade-plugin' && strpos( $plugin, 'cookie-notice.php' ) !== false )
return;
add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
add_action( 'admin_footer', [ $this, 'admin_footer' ] );
}
/**
* Welcome modal container.
*
* @return void
*/
public function admin_footer() {
echo '<button id="cn-modal-trigger" style="display:none"></button>';
}
/**
* Render welcome screen sidebar step.
*
* @param int|string $screen
* @param bool $echo
* @return string|void
*/
public function welcome_screen( $screen, $echo = true ) {
if ( ! current_user_can( 'install_plugins' ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
$sidebars = [ 'about', 'login', 'register', 'configure', 'success' ];
$steps = [ 1, 2, 3, 4 ];
$screens = array_merge( $sidebars, $steps );
if ( ! empty( $screen ) ) {
if ( is_numeric( $screen ) )
$screen = (int) $screen;
else
$screen = sanitize_key( $screen );
} else
$screen = '';
if ( empty( $screen ) || ! in_array( $screen, $screens, true ) ) {
if ( isset( $_REQUEST['screen'] ) ) {
if ( is_numeric( $_REQUEST['screen'] ) )
$screen = (int) $_REQUEST['screen'];
else
$screen = sanitize_key( $_REQUEST['screen'] );
} else
$screen = '';
if ( ! in_array( $screen, $screens, true ) )
$screen = '';
}
if ( empty( $screen ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
if ( wp_doing_ajax() && ! check_ajax_referer( 'cookie-notice-welcome', 'nonce' ) )
wp_die( _( 'You do not have permission to access this page.', 'cookie-notice' ) );
// step screens
if ( in_array( $screen, $steps ) ) {
$html = '
<div class="wrap full-width-layout cn-welcome-wrap cn-welcome-step-' . esc_attr( $screen ) . ' has-loader">';
if ( $screen == 1 ) {
$html .= $this->welcome_screen( 'about', false );
$html .= '
<div class="cn-content cn-sidebar-visible">
<div class="cn-inner">
<div class="cn-content-full">
<h1><b>Cookie Compliance&trade;</b></h1>
<h2>' . esc_html__( 'The next generation of Cookie Notice', 'cookie-notice' ) . '</h2>
<div class="cn-lead">
<p><b>' . esc_html__( 'Cookie Compliance is a free web application that enables websites to take a proactive approach to data protection and consent laws.', 'cookie-notice' ) . '</b></p>
<div class="cn-hero-image">
<div class="cn-flex-item">
<img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/screen-compliance.png" alt="Cookie Notice dashboard" />
</div>
</div>
<p>' . sprintf( esc_html__( 'It is the first solution to offer %sintentional consent%s, a new consent framework that incorporates the latest guidelines from over 100+ countries, and emerging standards from leading international organizations like the IEEE.', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p>' . sprintf( esc_html__( 'Cookie Notice includes %sseamless integration%s with Cookie Compliance to help your site comply with the latest updates to existing consent laws and provide a beautiful, multi-level experience to engage visitors in data privacy decisions.', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
</div>';
$html .= '
<div class="cn-buttons">
<button type="button" class="cn-btn cn-btn-lg cn-screen-button" data-screen="2"><span class="cn-spinner"></span>' . esc_html__( 'Sign up to Cookie Compliance', 'cookie-notice' ) . '</button><br />
<button type="button" class="cn-btn cn-btn-lg cn-btn-transparent cn-skip-button">' . esc_html__( 'Skip for now', 'cookie-notice' ) . '</button>
</div>
';
$html .= '
</div>
</div>
</div>';
} elseif ( $screen == 2 ) {
$html .= $this->welcome_screen( 'configure', false );
$html .= '
<div id="cn_upgrade_iframe" class="cn-content cn-sidebar-visible has-loader cn-loading"><span class="cn-spinner"></span>
<iframe id="cn_iframe_id" src="' . esc_url( home_url( '/?cn_preview_mode=1' ) ) . '"></iframe>
</div>';
} elseif ( $screen == 3 ) {
$html .= $this->welcome_screen( 'register', false );
$html .= '
<div class="cn-content cn-sidebar-visible">
<div class="cn-inner">
<div class="cn-content-full">
<h1><b>Cookie Compliance&trade;</b></h1>
<h2>' . esc_html__( 'The next generation of Cookie Notice', 'cookie-notice' ) . '</h2>
<div class="cn-lead">
<p>' . esc_html__( 'Take a proactive approach to data protection and consent laws by signing up for Cookie Compliance account. Then select a limited Basic Plan for free or get one of the Professional Plans for unlimited visits, consent storage, languages and customizations.', 'cookie-notice' ) . '</p>
</div>';
$html .= '
<h3 class="cn-pricing-select">' . esc_html__( 'Compliance Plans', 'cookie-notice' ) . ':</h3>
<div class="cn-pricing-type cn-radio-wrapper">
<div>
<label for="pricing-type-monthly"><input id="pricing-type-monthly" type="radio" name="cn_pricing_type" value="monthly" checked><span class="cn-pricing-toggle toggle-left"><span class="cn-label">' . esc_html__( 'Monthly', 'cookie-notice' ) . '</span></span></label>
</div>
<div>
<label for="pricing-type-yearly"><input id="pricing-type-yearly" type="radio" name="cn_pricing_type" value="yearly"><span class="cn-pricing-toggle toggle-right"><span class="cn-label">' . esc_html__( 'Yearly', 'cookie-notice' ) . '<span class="cn-badge">' . esc_html__( 'Save 12%', 'cookie-notice' ) . '</span></span></span></label>
</div>
</div>
<div class="cn-pricing-table">
<label class="cn-pricing-item cn-pricing-plan-free" for="cn-pricing-plan-free">
<input id="cn-pricing-plan-free" type="radio" name="cn_pricing" value="free">
<div class="cn-pricing-info">
<div class="cn-pricing-head">
<h4>' . esc_html__( 'Basic', 'cookie-notice' ) . '</h4>
<span class="cn-plan-pricing"><span class="cn-plan-price">' . esc_html__( 'Free', 'cookie-notice' ) . '</span></span>
</div>
<div class="cn-pricing-body">
<p class="cn-included"><span class="cn-icon"></span>' . esc_html__( 'GDPR, CCPA, LGPD, PECR requirements', 'cookie-notice' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . esc_html__( 'Consent Analytics Dashboard', 'cookie-notice' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%s1,000%s visits / month', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%s30 days%s consent storage', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGoogle & Facebook%s consent modes', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGeolocation%s support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%s1 additional%s language', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-excluded"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sBasic%s Support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
</div>
<div class="cn-pricing-footer">
<button type="button" class="cn-btn cn-btn-outline">' . esc_html__( 'Start Basic', 'cookie-notice' ) . '</button>
</div>
</div>
</label>
<label class="cn-pricing-item cn-pricing-plan-pro" for="cn-pricing-plan-pro">
<input id="cn-pricing-plan-pro" type="radio" name="cn_pricing" value="pro">
<div class="cn-pricing-info">
<div class="cn-pricing-head">
<h4>' . esc_html__( 'Professional', 'cookie-notice' ) . '</h4>
<span class="cn-plan-pricing"><span class="cn-plan-price"><sup>$ </sup><span class="cn-plan-amount">' . esc_attr( $this->pricing_monthly['compliance_monthly_notrial'] ) . '</span><sub> / <span class="cn-plan-period">' . esc_html__( 'monthly', 'cookie-notice' ) . '</span></sub></span></span>
<span class="cn-plan-promo">' . esc_html__( 'Recommended', 'cookie-notice' ) . '</span>
<div class="cn-select-wrapper">
<select name="cn_pricing_plan" class="form-select" aria-label="' . esc_html__( 'Pricing options', 'cookie-notice' ) . '" id="cn-pricing-plans">
<option value="compliance_monthly_notrial" data-price="' . esc_attr( $this->pricing_monthly['compliance_monthly_notrial'] ) . '">' . esc_html( sprintf( _n( '%s domain license', '%s domains license', 1, 'cookie-notice' ), 1 ) ) . '</option>
<option value="compliance_monthly_5" data-price="' . esc_attr( $this->pricing_monthly['compliance_monthly_5'] ) . '">' . esc_html( sprintf( _n( '%s domain license', '%s domains license', 5, 'cookie-notice' ), 5 ) ) . '</option>
<option value="compliance_monthly_10" data-price="' . esc_attr( $this->pricing_monthly['compliance_monthly_10'] ) . '">' . esc_html( sprintf( _n( '%s domain license', '%s domains license', 10, 'cookie-notice' ), 10 ) ) . '</option>
<option value="compliance_monthly_20" data-price="' . esc_attr( $this->pricing_monthly['compliance_monthly_20'] ) . '">' . esc_html( sprintf( _n( '%s domain license', '%s domains license', 20, 'cookie-notice' ), 20 ) ) . '</option>
</select>
</div>
</div>
<div class="cn-pricing-body">
<p class="cn-included"><span class="cn-icon"></span>' . esc_html__( 'GDPR, CCPA, LGPD, PECR requirements', 'cookie-notice' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . esc_html__( 'Consent Analytics Dashboard', 'cookie-notice' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sUnlimited%s visits', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sLifetime%s consent storage', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGoogle & Facebook%s consent modes', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sGeolocation%s support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sUnlimited%s languages', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
<p class="cn-included"><span class="cn-icon"></span>' . sprintf( esc_html__( '%sPriority%s Support', 'cookie-notice' ), '<b>', '</b>' ) . '</p>
</div>
<div class="cn-pricing-footer">
<button type="button" class="cn-btn cn-btn-secondary">' . esc_html__( 'Start Professional', 'cookie-notice' ) . '</button>
</div>
</div>
</label>
</div>
<div class="cn-buttons">
<button type="button" class="cn-btn cn-btn-lg cn-btn-transparent cn-skip-button">' . esc_html__( "I don’t want to create an account now", 'cookie-notice' ) . '</button>
</div>';
$html .= '
</div>
</div>
</div>';
} elseif ( $screen == 4 ) {
$html .= $this->welcome_screen( 'success', false );
// get main instance
$cn = Cookie_Notice();
$subscription = $cn->get_subscription();
$html .= '
<div class="cn-content cn-sidebar-visible">
<div class="cn-inner">
<div class="cn-content-full">
<h1><b>' . esc_html__( 'Congratulations', 'cookie-notice' ) . '</b></h1>
<h2>' . ( $subscription === 'pro' ? esc_html__( 'You have successfully signed up to a Professional plan.', 'cookie-notice' ) : esc_html__( 'You have successfully signed up to a limited, Basic plan.', 'cookie-notice' ) ) . '</h2>
<div class="cn-lead">
<p>' . esc_html__( 'Log in to your Cookie Compliance account and continue configuring your Privacy Experience.', 'cookie-notice' ) . '</p>
</div>
<div class="cn-buttons">
<a href="' . esc_url( $cn->get_url( 'host', '?utm_campaign=configure&utm_source=wordpress&utm_medium=button#/en/cc/login' ) ) . '" class="cn-btn cn-btn-lg" target="_blank">' . esc_html__( 'Go to Application', 'cookie-notice' ) . '</a>
</div>
</div>
</div>
</div>';
}
$html .= '
</div>';
// sidebar screens
} elseif ( in_array( $screen, $sidebars ) ) {
$html = '';
if ( $screen === 'about' ) {
$theme = wp_get_theme();
$html .= '
<div class="cn-sidebar cn-sidebar-left has-loader">
<div class="cn-inner">
<div class="cn-header">
<div class="cn-top-bar">
<div class="cn-logo"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-notice-logo.png" alt="Cookie Notice logo" /></div>
</div>
</div>
<div class="cn-body">
<h2>' . esc_html__( 'Compliance check', 'cookie-notice' ) . '</h2>
<div class="cn-lead"><p>' . esc_html__( 'This is a Compliance Check to determine your site’s compliance with updated data processing and consent rules under GDPR, CCPA and other international data privacy laws.', 'cookie-notice' ) . '</p></div>
<div id="cn_preview_about">
<p>' . esc_html__( 'Site URL', 'cookie-notice' ) . ': <b>' . esc_url( home_url() ) . '</b></p>
<p>' . esc_html__( 'Site Name', 'cookie-notice' ) . ': <b>' . esc_html( get_bloginfo( 'name' ) ) . '</b></p>
</div>
<div class="cn-compliance-check">
<div class="cn-progressbar"><div class="cn-progress-label">' . esc_html__( 'Checking...', 'cookie-notice' ) . '</div></div>
<div class="cn-compliance-feedback cn-hidden"></div>
<div class="cn-compliance-results">
<div class="cn-compliance-item"><p><span class="cn-compliance-label">' . esc_html__( 'Cookie Notice', 'cookie-notice' ) . ' </span><span class="cn-compliance-status"></span></p><p><span class="cn-compliance-desc">' . esc_html__( 'Notifies visitors that site uses cookies.', 'cookie-notice' ) . '</span></p></div>
<div class="cn-compliance-item" style="display: none"><p><span class="cn-compliance-label">' . esc_html__( 'Autoblocking', 'cookie-notice' ) . ' </span><span class="cn-compliance-status"></span></p><p><span class="cn-compliance-desc">' . esc_html__( 'Non-essential cookies blocked until consent is registered.', 'cookie-notice' ) . '</span></p></div>
<div class="cn-compliance-item" style="display: none"><p><span class="cn-compliance-label">' . esc_html__( 'Cookie Categories', 'cookie-notice' ) . ' </span><span class="cn-compliance-status"></span></p><p><span class="cn-compliance-desc">' . esc_html__( 'Separate consent requested per purpose of use.', 'cookie-notice' ) . '</span></p></div>
<div class="cn-compliance-item" style="display: none"><p><span class="cn-compliance-label">' . esc_html__( 'Proof-of-Consent', 'cookie-notice' ) . ' </span><span class="cn-compliance-status"></span></p><p><span class="cn-compliance-desc">' . esc_html__( 'Proof-of-consent stored in secure audit format.', 'cookie-notice' ) . '</span></p></div>
</div>
</div>
' /* <div id="cn_preview_frame"><img src=" ' . esc_url( $theme->get_screenshot() ) . '" /></div>
. '<div id="cn_preview_frame"><div id="cn_preview_frame_wrapper"><iframe id="cn_iframe_id" src="' . home_url( '/?cn_preview_mode=0' ) . '" scrolling="no" frameborder="0"></iframe></div></div> */ . '
</div>';
} elseif ( $screen === 'configure' ) {
$html .= '
<div class="cn-sidebar cn-sidebar-left has-loader cn-theme-light">
<div class="cn-inner">
<div class="cn-header">
<div class="cn-top-bar">
<div class="cn-logo"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-notice-logo.png" alt="Cookie Notice logo" /></div>
</div>
</div>
<div class="cn-body">
<h2>' . esc_html__( 'Live Setup', 'cookie-notice' ) . '</h2>
<div class="cn-lead"><p>' . esc_html__( 'Configure your Cookie Notice & Compliance design and compliance features through the options below. Click Apply Setup to save the configuration and go to selecting your preferred cookie solution.', 'cookie-notice' ) . '</p></div>
<form method="post" id="cn-form-configure" class="cn-form" action="" data-action="configure">
<div class="cn-accordion">
<div class="cn-accordion-item cn-form-container" tabindex="-1">
<div class="cn-accordion-header cn-form-header"><button class="cn-accordion-button" type="button">' . esc_html__( 'Banner Compliance', 'cookie-notice' ) . '</button></div>
<div class="cn-accordion-collapse cn-form">
<div class="cn-form-feedback cn-hidden"></div>' .
/*
<div class="cn-field cn-field-select">
<label for="cn_location">' . __( 'What is the location of your business/organization?', 'cookie-notice' ) . '​</label>
<div class="cn-select-wrapper">
<select id="cn_location" name="cn_location">
<option value="0">' . __( 'Select location', 'cookie-notice' ) . '</option>';
foreach ( Cookie_Notice()->settings->countries as $country_code => $country_name ) {
$html .= '<option value="' . $country_code . '">' . $country_name . '</option>';
}
$html .= '
</select>
</div>
</div>
*/
'
<div id="cn_laws" class="cn-field cn-field-checkbox">
<label>' . esc_html__( 'Select the laws that apply to your business', 'cookie-notice' ) . ':</label>
<div class="cn-checkbox-image-wrapper">
<label for="cn_laws_gdpr"><input id="cn_laws_gdpr" type="checkbox" name="cn_laws" value="gdpr" title="' . esc_attr__( 'GDPR', 'cookie-notice' ) . '" checked><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC/ElEQVRoge2ZzZGjMBCFmcMet4rjHjlsANQmsGRgZ7BkMGRgZ7DOYMhgnME4A08GdgZ2AujbA41HiD8JEOawXUWVXUjd73WLVqsVBB4F+OlTv3cBciB7Ng4nAV6ADHjnSz6A7bOxPQQIh94Dd43AaSFodgKkFmNOGoHEYvwySw1IgJtFFHJgC6RD4GTJnedF2jQSAUfNqzfgMFFnAnxqOi9CvNc5UwzG1CWaQede03f1Bl6MhZqxz5l0Jot97BKBRH5nc3hLCETyO52qr1LqL4wjxWm5Akd/UMaJfOzdjpUs8xvYyXp8k//RcjA7Mf01MMVdE3IjyxyfvZyMLIVEIuoarGcZJhqOgY14bJITqO8VSd/AqobZy6T2UPUbi5RSH0op9EeW5igiguVAWZ50YxKvhRoZJ4MC/maCr56iKN5GEgi139EYHVailDpqYHMgKYpir5S6a5FIvQGYIuL9B3jjXapFYnUpOgiCIAC2mpcT872+lJ4Ab1hkqfQRuHslIB9wNHa+BYHrHAToOprKJuacJSgPLH+M1HmRtLkDdkqp95aU+tqb09tthcC5No/moeLcybKpMO5KmZbPydLON3HwzagSflQD9BIid/BI4gD2OpaA2DIbBan+8qC9sD5cOxD4FADZWAJir72kkAjE8sxN4FEGF0WRT4xAVtl1/X6sCQCZlpH6wDtHYHbpIFDVUskA+HUSUEqd9eKrB/xqCVQkNmb+X4SAy8fhmEYnEbDGJanKavDCBPoPWJSnsIvk2BvlAbr3RAaEssZPYx6blN2BK2obGFGX/bBf/EsLrm7SlL3J5k73ZMGmVS9MT5Qt8T0rulGhLHViyso3sZ20uvbif1kiKl5tuFSqI/WH+Gq78HUR4dytc7CRS86fLwo078YQQ5HFXKtLEOq3NMP53lVaNpPIcs4Fy0YB9S70LNdXpgGqjW5g3AvNlvgd+DUwb6vZmHT72aY8rtY+WgN4YI5+fh3cFPUNynqz8inUt//V7OpWAnwHNuZvH/IPPeDD9c6V9FUAAAAASUVORK5CYII=" width="24" height="24"><span>' . esc_html__( 'GDPR', 'cookie-notice' ) . '</span></label>
<label for="cn_laws_ccpa"><input id="cn_laws_ccpa" type="checkbox" name="cn_laws" value="ccpa" title="' . esc_attr__( 'CCPA', 'cookie-notice' ) . '"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAwCAYAAACScGMWAAACPElEQVRYheXYvXHbMBTAcY7AEbSA79Smskp30QiqkyLaQPQE8Qb2BtEG4QZil3Ry5ZZaAO/vAqANIwSJD1LmXXD3ToVE8sf3hEcQRVEUBXADfE+Mu2LOAVSkj/q/xj0sGVcvEgeUGTAvDlgBP4CD+Vyl4HaZuNa9WRH5JSK4oZT6CZQxuN+ZOBzYqQ9mxSkYmAuzcUqpyoE0InIUkWcng1UoLresWFlrOwCwczLa2EAispczWzvcxs5YzzXWDm4bistpwk1RfCypr2yppc3BVUvDXYAtsO7OsSRcbY5bAbfArYicrYu36Ob7Fj297wx8Ncf7JwewScGJSD3S00LjOJa9p0/E1SHlDQWm4rqmHI+LAKbgGsx/y23IMbiQVUos7g2G04yjcOYEObga2InIxQNrc3FjK2MvDtP7DOQYAIvGlcBzYub+WRKNwOJw5oRDvW8Ih4icImDxOHNiX3nHcF0GDwGwZJyvvCG4aZuwB9i31lsMbu/DAXsD9IZS6kEpVQ0FoQvPHlxfaU/jR15peGbuGf3mlhqHKYF95c0dj1MCY5ZV1wUy/uT4dOB2BtykwDmyNw0QOM6EyweS9547L/AKOID7VNwcLcUdf1Jxa3T27MjaDOoZL0m4AXRJ3uZ3Pg69p9fy/pxssVYW6GdxbrvJwjXoUnZh40oTFXrT53q4EXiNtYltkCkTaDoc71v734B9z/ex7WdSXHfxzcBvYsbfKXHlECwAd0H/JZ7MjX6ZDBcy0DPYBmyHbugVe8KbbhsHbZ0AAAAASUVORK5CYII=" width="24" height="24"><span>' . esc_html__( 'CCPA', 'cookie-notice' ) . '</span></label>
</div>
</div>
<div id="cn_naming" class="cn-field cn-field-radio">
<label class="cn-asterix">' . esc_html__( 'Select a naming style for the consent choices', 'cookie-notice' ) . ':</label>
<div class="cn-radio-wrapper">
<label for="cn_naming_1"><input id="cn_naming_1" type="radio" name="cn_naming" value="1" checked><span>' . esc_html__( 'Silver, Gold, Platinum (Default)​', 'cookie-notice' ) . '</span></label>
<label for="cn_naming_2"><input id="cn_naming_2" type="radio" name="cn_naming" value="2"><span>' . esc_html__( 'Private, Balanced, Personalized', 'cookie-notice' ) . '</span></label>
<label for="cn_naming_3"><input id="cn_naming_3" type="radio" name="cn_naming" value="3"><span>' . esc_html__( 'Reject All, Accept Some, Accept All​', 'cookie-notice' ) . '</span></label>
</div>
</div>
<div class="cn-field cn-field-checkbox">
<label>' . esc_html__( 'Select additional information to include in the banner: *', 'cookie-notice' ) . '</label>
<div class="cn-checkbox-wrapper">
<label for="cn_privacy_paper"><input id="cn_privacy_paper" type="checkbox" name="cn_privacy_paper" value="1"><span>' . sprintf( esc_html__( 'Display %sPrivacy Paper%s to provide helpful data privacy and consent information to visitors.', 'cookie-notice' ), '<b>', '</b>' ) . '</span></label>
<label for="cn_privacy_contact"><input id="cn_privacy_contact" type="checkbox" name="cn_privacy_contact" value="1"><span>' . sprintf( esc_html__( 'Display %sPrivacy Contact%s to provide Data Controller contact information and links to external data privacy resources.', 'cookie-notice' ), '<b>', '</b>' ) . '</span></label>
</div>
</div>
<div class="cn-small">* ' . esc_html__( 'available for Cookie Compliance&trade; Pro plans only', 'cookie-notice' ) . '</div>
</div>
</div>
<div class="cn-accordion-item cn-form-container cn-collapsed" tabindex="-1">
<div class="cn-accordion-header cn-form-header"><button class="cn-accordion-button" type="button">' . esc_html__( 'Banner Design', 'cookie-notice' ) . '</button></div>
<div class="cn-accordion-collapse cn-form">
<div class="cn-form-feedback cn-hidden"></div>
<div class="cn-field cn-field-radio-image">
<label>' . esc_html__( 'Select your preferred display position', 'cookie-notice' ) . '​:</label>
<div class="cn-radio-image-wrapper">
<label for="cn_position_bottom"><input id="cn_position_bottom" type="radio" name="cn_position" value="bottom" title="' . esc_attr__( 'Bottom', 'cookie-notice' ) . '" checked><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/layout-bottom.png" width="24" height="24"></label>
<label for="cn_position_top"><input id="cn_position_top" type="radio" name="cn_position" value="top" title="' . esc_attr__( 'Top', 'cookie-notice' ) . '"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/layout-top.png" width="24" height="24"></label>
<label for="cn_position_left"><input id="cn_position_left" type="radio" name="cn_position" value="left" title="' . esc_attr__( 'Left', 'cookie-notice' ) . '"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/layout-left.png" width="24" height="24"></label>
<label for="cn_position_right"><input id="cn_position_right" type="radio" name="cn_position" value="right" title="' . esc_attr__( 'Right', 'cookie-notice' ) . '"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/layout-right.png" width="24" height="24"></label>
<label for="cn_position_center"><input id="cn_position_center" type="radio" name="cn_position" value="center" title="' . esc_attr__( 'Center', 'cookie-notice' ) . '"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/layout-center.png" width="24" height="24"></label>
</div>
</div>
<div class="cn-field cn-fieldset">
<label>' . esc_html__( 'Adjust the banner color scheme', 'cookie-notice' ) . '​:</label>
<div class="cn-checkbox-wrapper cn-color-picker-wrapper">
<label for="cn_color_primary"><input id="cn_color_primary" class="cn-color-picker" type="checkbox" name="cn_color_primary" value="#20c19e"><span>' . esc_html__( 'Color of the buttons and interactive elements.', 'cookie-notice' ) . '</span></label>
<label for="cn_color_background"><input id="cn_color_background" class="cn-color-picker" type="checkbox" name="cn_color_background" value="#ffffff"><span>' . esc_html__( 'Color of the banner background.', 'cookie-notice' ) . '</span></label>
<label for="cn_color_text"><input id="cn_color_text" class="cn-color-picker" type="checkbox" name="cn_color_text" value="#434f58"><span>' . esc_html__( 'Color of the body text.', 'cookie-notice' ) . '</span></label>
<label for="cn_color_border"><input id="cn_color_border" class="cn-color-picker" type="checkbox" name="cn_color_border" value="#5e6a74"><span>' . esc_html__( 'Color of the borders and inactive elements.', 'cookie-notice' ) . '</span></label>
<label for="cn_color_heading"><input id="cn_color_heading" class="cn-color-picker" type="checkbox" name="cn_color_heading" value="#434f58"><span>' . esc_html__( 'Color of the heading text.', 'cookie-notice' ) . '</span></label>
<label for="cn_color_button_text"><input id="cn_color_button_text" class="cn-color-picker" type="checkbox" name="cn_color_button_text" value="#ffffff"><span>' . esc_html__( 'Color of the button text.', 'cookie-notice' ) . '</span></label>
</div>
</div>
<div class="cn-small">* ' . esc_html__( 'available for Cookie Compliance&trade; Pro plans only', 'cookie-notice' ) . '</div>
</div>
</div>
</div>
<div class="cn-field cn-field-submit cn-nav">
<button type="button" class="cn-btn cn-screen-button" data-screen="3"><span class="cn-spinner"></span>' . esc_html__( 'Apply Setup', 'cookie-notice' ) . '</button>
</div>';
$html .= wp_nonce_field( 'cn_api_configure', 'cn_nonce', true, false );
$html .= '
</form>
</div>';
} elseif ( $screen === 'register' ) {
$html .= '
<div class="cn-sidebar cn-sidebar-left has-loader">
<div class="cn-inner">
<div class="cn-header">
<div class="cn-top-bar">
<div class="cn-logo"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-notice-logo.png" alt="Cookie Notice logo" /></div>
</div>
</div>
<div class="cn-body">
<h2>' . esc_html__( 'Compliance account', 'cookie-notice' ) . '</h2>
<div class="cn-lead">
<p>' . esc_html__( 'Create a Cookie Compliance&trade; account and select your preferred plan.', 'cookie-notice' ) . '</p>
</div>
<div class="cn-accordion">
<div id="cn-accordion-account" class="cn-accordion-item cn-form-container" tabindex="-1">
<div class="cn-accordion-header cn-form-header"><button class="cn-accordion-button" type="button">1. ' . esc_html__( 'Create Account', 'cookie-notice' ) . '</button></div>
<div class="cn-accordion-collapse">
<form method="post" class="cn-form" action="" data-action="register">
<div class="cn-form-feedback cn-hidden"></div>
<div class="cn-field cn-field-text">
<input type="text" name="email" value="" tabindex="1" placeholder="' . esc_attr__( 'Email address', 'cookie-notice' ) . '">
</div>
<div class="cn-field cn-field-text">
<input type="password" name="pass" value="" tabindex="2" autocomplete="off" placeholder="' . esc_attr__( 'Password', 'cookie-notice' ) . '">
<span>' . esc_html( 'Minimum eight characters, at least one capital letter and one number are required.', 'cookie-notice' ) . '</span>
</div>
<div class="cn-field cn-field-text">
<input type="password" name="pass2" value="" tabindex="3" autocomplete="off" placeholder="' . esc_attr__( 'Confirm Password', 'cookie-notice' ) . '">
</div>
<div class="cn-field cn-field-checkbox">
<div class="cn-checkbox-wrapper">
<label for="cn_terms"><input id="cn_terms" type="checkbox" name="terms" value="1"><span>' . sprintf( esc_html__( 'I have read and agree to the %sTerms of Service%s', 'cookie-notice' ), '<a href="https://cookie-compliance.co/terms-of-service/?utm_campaign=accept-terms&utm_source=wordpress&utm_medium=link" target="_blank">', '</a>' ) . '</span></label>
</div>
</div>
<div class="cn-field cn-field-submit cn-nav">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Sign Up', 'cookie-notice' ) . '</button>
</div>';
// get site language
$locale = get_locale();
$locale_code = explode( '_', $locale );
$html .= '
<input type="hidden" name="language" value="' . esc_attr( $locale_code[0] ) . '" />';
$html .= wp_nonce_field( 'cn_api_register', 'cn_nonce', true, false );
$html .= '
</form>
<p>' . esc_html__( 'Already have an account?', 'cookie-notice' ) . ' <a href="#" class="cn-screen-button" data-screen="login">' . esc_html__( 'Sign in', 'cookie-notice' ). '</a></p>
</div>
</div>';
$html .= '
<div id="cn-accordion-billing" class="cn-accordion-item cn-form-container cn-collapsed cn-disabled" tabindex="-1">
<div class="cn-accordion-header cn-form-header">
<button class="cn-accordion-button" type="button">2. ' . esc_html__( 'Select Plan', 'cookie-notice' ) . '</button>
</div>
<form method="post" class="cn-accordion-collapse cn-form cn-form-disabled" action="" data-action="payment">
<div class="cn-form-feedback cn-hidden"></div>
<div class="cn-field cn-field-radio">
<div class="cn-radio-wrapper cn-plan-wrapper">
<label for="cn-field-plan-free" class="cn-pricing-plan-free"><input id="cn-field-plan-free" type="radio" name="plan" value="free" checked><span><span class="cn-plan-description">' . esc_html__( 'Basic', 'cookie-notice' ) . '</span><span class="cn-plan-pricing"><span class="cn-plan-price">Free</span></span><span class="cn-plan-overlay"></span></span></label>
<label for="cn-field-plan-pro" class="cn-pricing-plan-pro"><input id="cn-field-plan-pro" type="radio" name="plan" value="compliance_monthly_notrial"><span><span class="cn-plan-description">' . sprintf( esc_html__( '%sProfessional%s', 'cookie-notice' ), '<b>', '</b>' ) . ' - <span class="cn-plan-period">' . esc_html__( 'monthly', 'cookie-notice' ) . '</span></span><span class="cn-plan-pricing"><span class="cn-plan-price">$<span class="cn-plan-amount">' . esc_attr( $this->pricing_monthly['compliance_monthly_notrial'] ) . '</span></span></span><span class="cn-plan-overlay"></span></span></label>
</div>
</div>
<div class="cn-field cn-fieldset" id="cn_submit_free">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Confirm', 'cookie-notice' ) . '</button>
</div>
<div class="cn-field cn-fieldset cn-hidden" id="cn_submit_pro">
<input type="hidden" name="cn_payment_identifier" value="" />
<div class="cn-field cn-field-radio">
<label>' . esc_html__( 'Payment Method', 'cookie-notice' ) . '</label>
<div class="cn-radio-wrapper cn-horizontal-wrapper">
<label for="cn_field_method_credit_card"><input id="cn_field_method_credit_card" type="radio" name="method" value="credit_card" checked><span>' . esc_html__( 'Credit Card', 'cookie-notice' ) . '</span></label>
<label for="cn_field_method_paypal"><input id="cn_field_method_paypal" type="radio" name="method" value="paypal"><span>' . esc_html__( 'PayPal', 'cookie-notice' ) . '</span></label>
</div>
</div>
<div class="cn-fieldset" id="cn_payment_method_credit_card">
<input type="hidden" name="payment_nonce" value="" />
<div class="cn-field cn-field-text">
<label for="cn_card_number">' . esc_html__( 'Card Number', 'cookie-notice' ) . '</label>
<div id="cn_card_number"></div>
</div>
<div class="cn-field cn-field-text cn-field-half cn-field-first">
<label for="cn_expiration_date">' . esc_html__( 'Expiration Date', 'cookie-notice' ) . '</label>
<div id="cn_expiration_date"></div>
</div>
<div class="cn-field cn-field-text cn-field-half cn-field-last">
<label for="cn_cvv">' . esc_html__( 'CVC/CVV', 'cookie-notice' ) . '</label>
<div id="cn_cvv"></div>
</div>
<div class="cn-field cn-field-submit cn-nav">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Submit', 'cookie-notice' ) . '</button>
</div>
</div>
<div class="cn-fieldset" id="cn_payment_method_paypal" style="display: none">
<div id="cn_paypal_button"></div>
</div>
</div>';
$html .= wp_nonce_field( 'cn_api_payment', 'cn_payment_nonce', true, false );
$html .= '
</form>
</div>
</div>
</div>';
} elseif ( $screen === 'login' ) {
$html .= '
<div class="cn-sidebar cn-sidebar-left has-loader">
<div class="cn-inner">
<div class="cn-header">
<div class="cn-top-bar">
<div class="cn-logo"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-notice-logo.png" alt="Cookie Notice logo" /></div>
</div>
</div>
<div class="cn-body">
<h2>' . esc_html__( 'Compliance Sign in', 'cookie-notice' ) . '</h2>
<div class="cn-lead">
<p>' . esc_html__( 'Sign in to your existing Cookie Compliance&trade; account and select your preferred plan.', 'cookie-notice' ) . '</p>
</div>
<div class="cn-accordion">
<div id="cn-accordion-account" class="cn-accordion-item cn-form-container" tabindex="-1">
<div class="cn-accordion-header cn-form-header"><button class="cn-accordion-button" type="button">1. ' . esc_html__( 'Account Login', 'cookie-notice' ) . '</button></div>
<div class="cn-accordion-collapse">
<form method="post" class="cn-form" action="" data-action="login">
<div class="cn-form-feedback cn-hidden"></div>
<div class="cn-field cn-field-text">
<input type="text" name="email" value="" tabindex="1" placeholder="' . esc_attr__( 'Email address', 'cookie-notice' ) . '">
</div>
<div class="cn-field cn-field-text">
<input type="password" name="pass" value="" tabindex="2" autocomplete="off" placeholder="' . esc_attr__( 'Password', 'cookie-notice' ) . '">
</div>
<div class="cn-field cn-field-submit cn-nav">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" ' . /* data-screen="4" */ '><span class="cn-spinner"></span>' . esc_html__( 'Sign in', 'cookie-notice' ) . '</button>
</div>';
// get site language
$locale = get_locale();
$locale_code = explode( '_', $locale );
$html .= '
<input type="hidden" name="language" value="' . esc_attr( $locale_code[0] ) . '" />';
$html .= wp_nonce_field( 'cn_api_login', 'cn_nonce', true, false );
$html .= '
</form>
<p>' . esc_html__( 'Don\'t have an account yet?', 'cookie-notice' ) . ' <a href="#" class="cn-screen-button" data-screen="register">' . esc_html__( 'Sign up', 'cookie-notice' ) . '</a></p>
</div>
</div>
<div id="cn-accordion-billing" class="cn-accordion-item cn-form-container cn-collapsed cn-disabled" tabindex="-1">
<div class="cn-accordion-header cn-form-header">
<button class="cn-accordion-button" type="button">2. ' . esc_html__( 'Select Plan', 'cookie-notice' ) . '</button>
</div>
<form method="post" class="cn-accordion-collapse cn-form cn-form-disabled" action="" data-action="payment">
<div class="cn-form-feedback cn-hidden"></div>
<div class="cn-field cn-field-radio">
<div class="cn-radio-wrapper cn-plan-wrapper">
<label for="cn-field-plan-free" class="cn-pricing-plan-free"><input id="cn-field-plan-free" type="radio" name="plan" value="free" checked><span><span class="cn-plan-description">' . esc_html__( 'Basic', 'cookie-notice' ) . '</span><span class="cn-plan-pricing"><span class="cn-plan-price">Free</span></span><span class="cn-plan-overlay"></span></span></label>
<label for="cn-field-plan-pro" class="cn-pricing-plan-pro"><input id="cn-field-plan-pro" type="radio" name="plan" value="compliance_monthly_notrial"><span><span class="cn-plan-description">' . sprintf( esc_html__( '%sProfessional%s', 'cookie-notice' ), '<b>', '</b>' ) . ' - <span class="cn-plan-period">' . esc_html__( 'monthly', 'cookie-notice' ) . '</span></span><span class="cn-plan-pricing"><span class="cn-plan-price">$<span class="cn-plan-amount">' . esc_attr( $this->pricing_monthly['compliance_monthly_notrial'] ) . '</span></span></span><span class="cn-plan-overlay"></span></span></label>
<label for="cn-field-plan-license" class="cn-pricing-plan-license cn-disabled">
<input id="cn-field-plan-license" type="radio" name="plan" value="license"><span><span class="cn-plan-description">' . esc_html__( 'Use License', 'cookie-notice' ) . '</span><span class="cn-plan-pricing"><span class="cn-plan-price"><span class="cn-plan-amount">0</span> ' . esc_html__( 'available', 'cookie-notice' ) . '</span></span><span class="cn-plan-overlay"></span></span>
</label>
</div>
</div>
<div class="cn-field cn-fieldset" id="cn_submit_free">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Confirm', 'cookie-notice' ) . '</button>
</div>
<div class="cn-field cn-fieldset cn-hidden" id="cn_submit_pro">
<input type="hidden" name="cn_payment_identifier" value="" />
<div class="cn-field cn-field-radio">
<label>' . esc_html__( 'Payment Method', 'cookie-notice' ) . '</label>
<div class="cn-radio-wrapper cn-horizontal-wrapper">
<label for="cn_field_method_credit_card"><input id="cn_field_method_credit_card" type="radio" name="method" value="credit_card" checked><span>' . esc_html__( 'Credit Card', 'cookie-notice' ) . '</span></label>
<label for="cn_field_method_paypal"><input id="cn_field_method_paypal" type="radio" name="method" value="paypal"><span>' . esc_html__( 'PayPal', 'cookie-notice' ) . '</span></label>
</div>
</div>
<div class="cn-fieldset" id="cn_payment_method_credit_card">
<input type="hidden" name="payment_nonce" value="" />
<div class="cn-field cn-field-text">
<label for="cn_card_number">' . esc_html__( 'Card Number', 'cookie-notice' ) . '</label>
<div id="cn_card_number"></div>
</div>
<div class="cn-field cn-field-text cn-field-half cn-field-first">
<label for="cn_expiration_date">' . esc_html__( 'Expiration Date', 'cookie-notice' ) . '</label>
<div id="cn_expiration_date"></div>
</div>
<div class="cn-field cn-field-text cn-field-half cn-field-last">
<label for="cn_cvv">' . esc_html__( 'CVC/CVV', 'cookie-notice' ) . '</label>
<div id="cn_cvv"></div>
</div>
<div class="cn-field cn-field-submit cn-nav">
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Submit', 'cookie-notice' ) . '</button>
</div>
</div>
<div class="cn-fieldset" id="cn_payment_method_paypal" style="display: none">
<div id="cn_paypal_button"></div>
</div>
</div>
<div class="cn-field cn-fieldset cn-hidden" id="cn_submit_license">
<div class="cn-field cn-field-select" id="cn-subscriptions-list">
<label for="cn-subscription-select">' . esc_html__( 'Select subscription', 'cookie-notice' ) . '​</label>
<select name="cn_subscription_id" class="form-select" aria-label="' . esc_attr__( 'Licenses', 'cookie-notice' ) . '" id="cn-subscription-select">
</select>
</div><br>
<button type="submit" class="cn-btn cn-screen-button" tabindex="4" data-screen="4"><span class="cn-spinner"></span>' . esc_html__( 'Confirm', 'cookie-notice' ) . '</button>
</div>';
$html .= wp_nonce_field( 'cn_api_payment', 'cn_payment_nonce', true, false );
$html .= '
</form>
</div>
</div>
</div>';
} elseif ( $screen === 'success' ) {
$html .= '
<div class="cn-sidebar cn-sidebar-left has-loader">
<div class="cn-inner">
<div class="cn-header">
<div class="cn-top-bar">
<div class="cn-logo"><img src="' . esc_url( COOKIE_NOTICE_URL ) . '/img/cookie-notice-logo.png" alt="Cookie Notice logo" /></div>
</div>
</div>
<div class="cn-body">
<h2>' . esc_html__( 'Success!', 'cookie-notice' ) . '</h2>
<div class="cn-lead"><p><b>' . esc_html__( 'You have successfully integrated your website to Cookie Compliance&trade;', 'cookie-notice' ) . '</b></p><p>' . sprintf( esc_html__( 'Go to Cookie Compliance application now. Or access it anytime from your %sCookie Notice settings page%s.', 'cookie-notice' ), '<a href="' . esc_url( Cookie_Notice()->is_network_admin() ? network_admin_url( 'admin.php?page=cookie-notice' ) : admin_url( 'admin.php?page=cookie-notice' ) ) . '">', '</a>' ) . '</p></div>
</div>';
}
$html .= '
<div class="cn-footer">';
/*
switch ( $screen ) {
case 'about':
$html .= '<a href="' . esc_url( admin_url( 'admin.php?page=cookie-notice' ) ) . '" class="cn-btn cn-btn-link cn-skip-button">' . __( 'Skip Live Setup', 'cookie-notice' ) . '</a>';
break;
case 'success':
$html .= '<a href="' . esc_url( get_dashboard_url() ) . '" class="cn-btn cn-btn-link cn-skip-button">' . __( 'WordPress Dashboard', 'cookie-notice' ) . '</a>';
break;
default:
$html .= '<a href="' . esc_url( admin_url( 'admin.php?page=cookie-notice' ) ) . '" class="cn-btn cn-btn-link cn-skip-button">' . __( 'Skip for now', 'cookie-notice' ) . '</a>';
break;
}
*/
$html .= '
</div>
</div>
</div>';
}
if ( $echo ) {
// get allowed html
$allowed_html = wp_kses_allowed_html( 'post' );
$allowed_html['div']['tabindex'] = true;
$allowed_html['button']['tabindex'] = true;
$allowed_html['iframe'] = [
'id' => true,
'src' => true
];
$allowed_html['form'] = [
'id' => true,
'class' => true,
'action' => true,
'data-action' => true
];
$allowed_html['select'] = [
'name' => true,
'class' => true,
'id' => true,
'aria-label' => true
];
$allowed_html['option'] = [
'value' => true,
'data-price' => true
];
$allowed_html['input'] = [
'id' => true,
'type' => true,
'name' => true,
'class' => true,
'value' => true,
'tabindex' => true,
'autocomplete' => true,
'checked' => true,
'placeholder' => true,
'title' => true
];
add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
// echo wp_kses( $html, $allowed_html );
echo $html;
remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
} else
return $html;
if ( wp_doing_ajax() )
exit();
}
}
\ No newline at end of file
<?php
// Silence is golden.
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
var charts = cnDashboardArgs.charts;
if ( Object.entries(charts).length > 0 ) {
for ( const [key, config] of Object.entries( charts ) ) {
// create canvas
var canvas = document.getElementById( 'cn-' + key + '-chart' );
if ( canvas ) {
// options per chart type
var options = {
doughnut: {
responsive: true,
plugins: {
legend: {
position: 'top',
}
},
hover: {
mode: 'label'
},
layout: {
padding: 0
}
},
line: {
scales: {
x: {
display: true,
title: {
display: false
}
},
y: {
display: true,
grace: 0,
beginAtZero: true,
title: {
display: false
},
ticks: {
precision: 0,
maxTicksLimit: 12
}
}
}
}
}
config.options = options.hasOwnProperty( config.type ) ? options[config.type] : {};
var chart = new Chart( canvas, config );
chart.update();
}
}
}
} );
} )( jQuery );
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
// save dismiss state // .is-dismissible
$( '.cn-notice' ).on( 'click', '.notice-dismiss, .cn-notice-dismiss', function( e ) {
var notice_action = 'dismiss';
var param = '';
if ( $( e.currentTarget ).hasClass( 'cn-approve' ) )
notice_action = 'approve';
else if ( $( e.currentTarget ).hasClass( 'cn-delay' ) )
notice_action = 'delay';
else if ( $( e.delegateTarget ).hasClass( 'cn-threshold' ) ) {
notice_action = 'threshold';
var delay = $( e.delegateTarget ).find( '.cn-notice-text' ).data( 'delay' );
param = parseInt( delay );
}
$.ajax( {
url: cnArgsNotice.ajaxURL,
type: 'POST',
dataType: 'json',
data: {
action: 'cn_dismiss_notice',
notice_action: notice_action,
nonce: cnArgsNotice.nonce,
param: param,
cn_network: cnArgsNotice.network ? 1 : 0
}
} );
$( e.delegateTarget ).slideUp( 'fast' );
} );
} );
} )( jQuery );
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
// cancel deactivation
$( document ).on( 'click', '.cn-deactivate-plugin-cancel', function( e ) {
tb_remove();
return false;
} );
// simple deactivation
$( document ).on( 'click', '.cn-deactivate-plugin-simple', function( e ) {
// display spinner
$( '#cn-deactivation-footer .spinner' ).addClass( 'is-active' );
} );
// deactivation with sending data
$( document ).on( 'click', '.cn-deactivate-plugin-data', function( e ) {
var spinner = $( '#cn-deactivation-footer .spinner' );
var url = $( this ).attr( 'href' );
// display spinner
spinner.addClass( 'is-active' );
// submit data
$.post( ajaxurl, {
action: 'cn-deactivate-plugin',
option_id: $( 'input[name="cn_deactivation_option"]:checked' ).val(),
other: $( 'textarea[name="cn_deactivation_other"]' ).val(),
nonce: cnArgsPlugins.nonce
} ).done( function( response ) {
// deactivate plugin
window.location.href = url;
} ).fail( function() {
// deactivate plugin
window.location.href = url;
} );
return false;
} );
// click on deactivation link
$( document ).on( 'click', '.cn-deactivate-plugin-modal', function( e ) {
tb_show( cnArgsPlugins.deactivate, '#TB_inline?inlineId=cn-deactivation-modal&modal=false' );
setTimeout( function() {
var modalBox = $( '#cn-deactivation-container' ).closest( '#TB_window' );
if ( modalBox.length > 0 ) {
$( modalBox ).addClass( 'cn-deactivation-modal' );
$( modalBox ).find( '#TB_closeWindowButton' ).on( 'blur' );
}
}, 0 );
return false;
} );
// change radio
$( document ).on( 'change', 'input[name="cn_deactivation_option"]', function( e ) {
var last = $( 'input[name="cn_deactivation_option"]' ).last().get( 0 );
// last element?
if ( $( this ).get( 0 ) === last )
$( '.cn-deactivation-textarea textarea' ).prop( 'disabled', false );
else
$( '.cn-deactivation-textarea textarea' ).prop( 'disabled', true );
} );
} );
} )( jQuery );
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
var btClient = false;
var btCreditCardsInitialized = false;
var btPayPalInitialized = false;
var btInit = function() {
var result = btInitToken();
if ( result !== false && btCreditCardsInitialized === false ) {
// ajax was successful
result.done( function( response ) {
// token received
try {
// parse response
data = JSON.parse( response );
// first step, init braintree client
btClient = braintree.client.create( {
authorization: data.token
} );
btInitPaymentMethod( 'credit_card' );
// token failed
} catch ( e ) {
btGatewayFail( 'btInit catch' );
}
// ajax failed
} ).fail( function() {
btGatewayFail( 'btInit AJAX failed' );
} );
}
}
var btInitToken = function() {
// payment screen?
var paymentEl = $( '.cn-sidebar form[data-action="payment"]' );
// init braintree
if ( paymentEl.length ) {
paymentEl.addClass( 'cn-form-disabled' );
if ( typeof braintree !== 'undefined' ) {
var ajaxArgs = {
action: 'cn_api_request',
request: 'get_bt_init_token',
nonce: cnWelcomeArgs.nonce
};
// network area?
if ( cnWelcomeArgs.network === '1' )
ajaxArgs.cn_network = 1;
return $.ajax( {
url: cnWelcomeArgs.ajaxURL,
type: 'POST',
dataType: 'html',
data: ajaxArgs
} );
} else
return false;
} else
return false;
}
var btInitPaymentMethod = function( type ) {
if ( btClient !== false ) {
if ( type === 'credit_card' && btCreditCardsInitialized === false ) {
$( 'form.cn-form[data-action="payment"]' ).addClass( 'cn-form-disabled' );
btClient.then( btCreditCardsInit ).then( btHostedFieldsInstance ).catch( btGatewayFail );
} else if ( type === 'paypal' && btPayPalInitialized === false ) {
$( 'form.cn-form[data-action="payment"]' ).addClass( 'cn-form-disabled' );
btClient.then( btPaypalCheckoutInit ).then( btPaypalCheckoutSDK ).then( btPaypalCheckoutInstance ).then( btPaypalCheckoutButton ).catch( btGatewayFail );
}
} else
btGatewayFail( 'btInitPaymentMethod btClient is false' );
}
var btCreditCardsInit = function( clientInstance ) {
return braintree.hostedFields.create( {
client: clientInstance,
styles: {
'input': {
'font-size': '14px',
'font-family': '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif',
'color': '#fff'
},
':focus': {
'color': '#fff'
},
"::placeholder": {
'color': '#aaa'
}
},
fields: {
number: {
'selector': '#cn_card_number',
'placeholder': '0000 0000 0000 0000'
},
expirationDate: {
'selector': '#cn_expiration_date',
'placeholder': 'MM / YY'
},
cvv: {
'selector': '#cn_cvv',
'placeholder': '123'
}
}
} );
}
var btHostedFieldsInstance = function( hostedFieldsInstance ) {
btCreditCardsInitialized = true;
var form = $( 'form.cn-form[data-action="payment"]' );
form.removeClass( 'cn-form-disabled' );
form.on( 'submit', function() {
if ( form.hasClass( 'cn-payment-in-progress' ) )
return false;
form.find( '.cn-form-feedback' ).addClass( 'cn-hidden' );
// spin the spinner, if exists
if ( form.find( '.cn-spinner' ).length )
form.find( '.cn-spinner' ).addClass( 'spin' );
var invalidForm = false;
var state = hostedFieldsInstance.getState();
// check hosted fields
Object.keys( state.fields ).forEach( function( field ) {
if ( ! state.fields[field].isValid ) {
$( state.fields[field].container ).addClass( 'braintree-hosted-fields-invalid' );
invalidForm = true;
}
} );
if ( invalidForm ) {
setTimeout( function() {
cnDisplayError( cnWelcomeArgs.invalidFields, form );
// spin the spinner, if exists
if ( form.find( '.cn-spinner' ).length )
form.find( '.cn-spinner' ).removeClass( 'spin' );
}, 500 );
return false;
}
hostedFieldsInstance.tokenize( function( err, payload ) {
if ( err ) {
cnDisplayError( cnWelcomeArgs.error );
return false;
} else {
form.addClass( 'cn-payment-in-progress' );
form.find( 'input[name="payment_nonce"]' ).val( payload.nonce );
form.find( 'input[name="cn_payment_identifier"]' ).val( payload.details.lastFour );
$( '#cn_submit_pro' ).find( '.cn-screen-button[data-screen="4"]' ).trigger( 'click' );
}
} );
return false;
} );
}
var btPaypalCheckoutInit = function( clientInstance ) {
return braintree.paypalCheckout.create( {
client: clientInstance
} );
}
var btPaypalCheckoutSDK = function( paypalCheckoutInstance ) {
return paypalCheckoutInstance.loadPayPalSDK( {
vault: true,
intent: 'tokenize'
} );
}
var btPaypalCheckoutInstance = function( paypalCheckoutInstance ) {
var form = $( 'form.cn-form[data-action="payment"]' );
return paypal.Buttons( {
fundingSource: paypal.FUNDING.PAYPAL,
createBillingAgreement: function() {
form.addClass( 'cn-form-disabled' );
return paypalCheckoutInstance.createPayment( {
flow: 'vault',
intent: 'tokenize',
currency: 'EUR'
} );
},
onApprove: function( data, actions ) {
return paypalCheckoutInstance.tokenizePayment( data ).then( function( payload ) {
form.addClass( 'cn-payment-in-progress' );
form.find( 'input[name="payment_nonce"]' ).val( payload.nonce );
form.find( 'input[name="cn_payment_identifier"]' ).val( payload.details.email );
$( '#cn_submit_pro' ).find( '.cn-screen-button[data-screen="4"]' ).trigger( 'click' );
} );
},
onCancel: function( data ) {
form.removeClass( 'cn-form-disabled' );
},
onError: function( err ) {
form.removeClass( 'cn-form-disabled' );
}
} ).render( '#cn_paypal_button' );
}
var btPaypalCheckoutButton = function() {
btPayPalInitialized = true;
$( 'form.cn-form[data-action="payment"]' ).removeClass( 'cn-form-disabled' );
}
var btGatewayFail = function( error ) {
if ( typeof error !== 'undefined' )
console.log( error );
cnDisplayError( cnWelcomeArgs.error );
}
var cnDisplayError = function( message, form ) {
if ( typeof form === 'undefined' )
form = $( 'form.cn-form[data-action="payment"]' );
form.find( '.cn-form-feedback' ).html( '<p class="cn-error">' + message + '</p>' ).removeClass( 'cn-hidden' );
}
var cnWelcomeScreen = function( target ) {
var screen = $( target ).data( 'screen' );
var steps = [1, 2, 3, 4];
var sidebars = ['login', 'register', 'configure', 'payment'];
// continue with screen loading
var requestData = {
action: 'cn_welcome_screen',
nonce: cnWelcomeArgs.nonce
};
if ( $.inArray( screen, steps ) !== -1 ) {
var container = $( '.cn-welcome-wrap' );
requestData.screen = screen;
} else if ( $.inArray( screen, sidebars ) !== -1 ) {
var container = $( '.cn-sidebar' );
requestData.screen = screen;
} else
return false;
// network area?
if ( cnWelcomeArgs.network === '1' )
requestData.cn_network = 1;
// add loading overlay
$( container ).addClass( 'cn-loading' );
$.ajax( {
url: cnWelcomeArgs.ajaxURL,
type: 'POST',
dataType: 'html',
data: requestData
} ).done( function( response ) {
$( container ).replaceWith( response );
} ).fail( function( jqXHR, textStatus, errorThrown ) {
//
} ).always( function( response ) {
// remove spinner
$( container ).removeClass( 'cn-loading' );
// trigger event
var event = $.Event( 'screen-loaded' );
$( document ).trigger( event );
} );
return this;
};
var cnWelcomeForm = function( form ) {
var formAction = $( form[0] ).data( 'action' );
var formResult = null;
var formData = {
action: 'cn_api_request',
nonce: cnWelcomeArgs.nonce
};
// clear feedback
$( form[0] ).find( '.cn-form-feedback' ).addClass( 'cn-hidden' );
// build request data
formData.request = formAction;
// convert form data to object
$( form[0] ).serializeArray().map( function( x ) {
// exception for checkboxes
if ( x.name === 'cn_laws' ) {
var arrayVal = typeof formData[x.name] !== 'undefined' ? formData[x.name] : [];
arrayVal.push( x.value );
formData[x.name] = arrayVal;
} else
formData[x.name] = x.value;
} );
// network area?
if ( cnWelcomeArgs.network === '1' )
formData.cn_network = 1;
formResult = $.ajax( {
url: cnWelcomeArgs.ajaxURL,
type: 'POST',
dataType: 'json',
data: formData
} );
return formResult;
};
// handle screen loading
$( document ).on( 'click', '.cn-screen-button', function( e ) {
var form = $( e.target ).closest( 'form' );
var result = false;
// spin the spinner, if exists
if ( $( e.target ).find( '.cn-spinner' ).length )
$( e.target ).find( '.cn-spinner' ).addClass( 'spin' );
// no form?
if ( form.length === 0 )
return cnWelcomeScreen( e.target );
var formData = {};
var formDataset = $( form[0] ).data();
var formAction = formDataset.hasOwnProperty( 'action' ) ? formDataset.action : '';
// get form data
$( form[0] ).serializeArray().map( function( x ) {
// exception for checkboxes
if ( x.name === 'cn_laws' ) {
var arrayVal = typeof formData[x.name] !== 'undefined' ? formData[x.name] : [];
arrayVal.push( x.value );
formData[x.name] = arrayVal;
} else
formData[x.name] = x.value;
} );
// payment?
if ( formAction === 'payment' ) {
// free
if ( formData.plan === 'free' ) {
// load screen
cnWelcomeScreen( e.target );
return false;
// licesne
} else if ( formData.plan === 'license' ) {
// payment screen?
var paymentEl = $( '.cn-sidebar form[data-action="payment"]' );
// disable form
if ( paymentEl.length )
paymentEl.addClass( 'cn-form-disabled' );
// get subscription ID
var subscriptionID = formData.hasOwnProperty( 'cn_subscription_id' ) ? parseInt( formData.cn_subscription_id ) : 0;
var ajaxArgs = {
action: 'cn_api_request',
request: 'use_license',
subscriptionID: subscriptionID,
nonce: cnWelcomeArgs.nonce
};
// network area?
if ( cnWelcomeArgs.network === '1' )
ajaxArgs.cn_network = 1;
// assign license request
result = $.ajax( {
url: cnWelcomeArgs.ajaxURL,
type: 'POST',
dataType: 'json',
data: ajaxArgs
} );
// process license
result.done( function( response ) {
// error
if ( response.hasOwnProperty( 'error' ) ) {
cnDisplayError( response.error, $( form[0] ) );
return false;
// message
} else {
var targetEl = $( '#cn_submit_license' ).find( '.cn-screen-button[data-screen="4"]' );
// open next screen
cnWelcomeScreen( targetEl );
return result;
}
} );
// remove spinner
result.always( function( response ) {
if ( $( e.target ).find( '.cn-spinner' ).length )
$( e.target ).find( '.cn-spinner' ).removeClass( 'spin' );
// enable form
if ( paymentEl.length )
paymentEl.removeClass( 'cn-form-disabled' );
} );
// pro
} else {
// only credit cards
if ( $( form[0] ).find( 'input[name="payment_nonce"]' ).val() === '' ) {
form.trigger( 'submit' );
return false;
}
}
// other forms
} else
e.preventDefault();
// break here on license payment
if ( formAction === 'payment' && formData.plan === 'license' )
return result;
// get form and process it
result = cnWelcomeForm( form );
result.done( function( response ) {
// error
if ( response.hasOwnProperty( 'error' ) ) {
cnDisplayError( response.error, $( form[0] ) );
return false;
// message
} else if ( response.hasOwnProperty( 'message' ) ) {
cnDisplayError( response.message, $( form[0] ) );
return false;
// all good
} else {
switch ( formAction ) {
// logged in, go to success or billing
case 'login':
// register complete, go to success or billing
case 'register':
// if there are any subscriptions
if ( response.hasOwnProperty( 'subscriptions' ) ) {
var subscriptions = response.subscriptions;
if ( subscriptions.length > 0 ) {
var available = 0;
for ( i = 0; i < subscriptions.length; i ++ ) {
var subscriptionID = subscriptions[i].subscriptionid;
var licensesAvailable = parseInt( subscriptions[i].availablelicense );
var subscriptionText = subscriptions[i].VendorSubscriptionID + ' - ' + licensesAvailable + ' ' + cnWelcomeArgs.licensesAvailable;
var subscriptionOption = $( '<option value="' + subscriptionID + '">' + subscriptionText + '</option>' );
if ( licensesAvailable == 0 ) {
$( subscriptionOption ).attr( 'disabled', 'true');
}
$( '#cn-subscription-select' ).append( subscriptionOption );
available += licensesAvailable;
}
if ( available > 0 ) {
$( '.cn-pricing-plan-license' ).removeClass( 'cn-disabled' );
$( '.cn-pricing-plan-license' ).find( '.cn-plan-amount' ).text( available );
}
}
}
var accountPlan = formData.hasOwnProperty( 'plan' ) ? formData.plan : 'free';
// trigger payment
var accordionItem = $( form[0] ).closest( '.cn-accordion-item' );
// collapse account
$( accordionItem ).addClass( 'cn-collapsed cn-disabled' );
// show billing
$( accordionItem ).next().removeClass( 'cn-disabled' ).removeClass( 'cn-collapsed' );
$( accordionItem ).find( 'form' ).removeClass( 'cn-form-disabled' );
// init braintree after payment screen is loaded via AJAX
btInit();
break;
case 'configure':
default:
// load screen
cnWelcomeScreen( e.target );
break;
}
}
} );
result.always( function( response ) {
if ( $( e.target ).find( '.cn-spinner' ).length )
$( e.target ).find( '.cn-spinner' ).removeClass( 'spin' );
// after invalid payment?
if ( formAction === 'payment' ) {
$( form[0] ).removeClass( 'cn-payment-in-progress' );
$( form[0] ).find( 'input[name="payment_nonce"]' ).val( '' );
}
} );
return result;
} );
//
$( document ).on( 'screen-loaded', function() {
var configureFields = $( '#cn-form-configure' ).serializeArray() || [];
var frame = window.frames[ 'cn_iframe_id' ];
if ( configureFields.length > 0 ) {
$( configureFields ).each( function( index, field ) {
} );
}
} );
// change payment method
$( document ).on( 'change', 'input[name="method"]', function() {
var input = $( this );
$( '#cn_payment_method_credit_card, #cn_payment_method_paypal' ).toggle();
input.closest( 'form' ).find( '.cn-form-feedback' ).addClass( 'cn-hidden' );
// init payment method if needed
btInitPaymentMethod( input.val() );
} );
//
$( document ).on( 'click', '.cn-accordion > .cn-accordion-item .cn-accordion-button', function() {
var accordionItem = $( this ).closest( '.cn-accordion-item' );
var activeItem = $( this ).closest( '.cn-accordion' ).find( '.cn-accordion-item:not(.cn-collapsed)' );
if ( $( accordionItem ).hasClass( 'cn-collapsed' ) ) {
$( activeItem ).addClass( 'cn-collapsed' );
$( accordionItem ).removeClass( 'cn-collapsed' );
}
return false;
} );
// live preview
$( document ).on( 'change', 'input[name="cn_position"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'position', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_laws"]', function() {
var val = [];
$( 'input[name="cn_laws"]:checked' ).each( function() {
val.push( $( this ).val() );
} );
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'laws', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_naming"]', function() {
var val = [];
$( 'input[name="cn_naming"]:checked' ).each( function() {
val.push( $( this ).val() );
} );
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'naming', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_privacy_paper"]', function() {
var val = $( this ).prop( 'checked' );
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'privacy_paper', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_privacy_contact"]', function() {
var val = $( this ).prop( 'checked' );
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'privacy_contact', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_primary"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_primary', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_background"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_background', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_border"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_border', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_text"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_text', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_heading"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_heading', value: val} );
} );
$( document ).on( 'change', 'input[name="cn_color_button_text"]', function() {
var val = $( this ).val();
var frame = window.frames['cn_iframe_id'];
frame.contentWindow.postMessage( {call: 'color_button_text', value: val} );
} );
// handle monthly / yearly payment plan
$( document ).on( 'change', 'input[name="cn_pricing_type"]', function() {
// pricing plans
var plansMonthly = cnWelcomeArgs.pricingMonthly;
var plansYearly = cnWelcomeArgs.pricingYearly;
var pricingOptions = $( '#cn-pricing-plans option' );
var checked = $( 'input[name="cn_pricing_type"]:checked' ).val();
var names = Object.keys( checked === 'yearly' ? plansYearly : plansMonthly );
var pricing = Object.values( checked === 'yearly' ? plansYearly : plansMonthly );
if ( checked === 'yearly' )
$( '.cn-plan-period' ).text( cnWelcomeArgs.paidYear );
else
$( '.cn-plan-period' ).text( cnWelcomeArgs.paidMonth );
// replace options
var i = 0;
for ( var property in pricing ) {
var option = pricingOptions[i];
$( option ).val( names[i] );
$( option ).attr( 'data-price', pricing[i] );
i++;
}
// trigger plan selection
$( 'select[name="cn_pricing_plan"]' ).trigger( 'change' );
} );
// handle pro plan selection
$( document ).on( 'change', 'select[name="cn_pricing_plan"]', function() {
var el = $( '#cn-pricing-plans' );
var selected = $( el ).find( 'option:selected' );
// update price
$( '.cn-pricing-plan-pro .cn-plan-amount' ).text( $( selected ).attr( 'data-price' ) );
var availablePlans = ['free'];
// merge with pro plans
availablePlans = availablePlans.concat( Object.keys( cnWelcomeArgs.pricingMonthly ) );
availablePlans = availablePlans.concat( Object.keys( cnWelcomeArgs.pricingYearly ) );
var input = $( this );
var inputVal = input.val();
inputVal = availablePlans.indexOf( inputVal ) !== -1 ? inputVal : 'free';
if ( inputVal === 'free' ) {
$( '#cn_submit_free' ).removeClass( 'cn-hidden' );
$( '#cn_submit_pro' ).addClass( 'cn-hidden' );
$( document ).find( '#cn-field-plan-free' ).prop( 'checked', true );
$( document ).find( '#cn-pricing-plan-free' ).prop( 'checked', true );
} else {
$( '#cn_submit_free' ).addClass( 'cn-hidden' );
$( '#cn_submit_pro' ).removeClass( 'cn-hidden' );
$( document ).find( '#cn-field-plan-pro' ).val( inputVal ).prop( 'checked', true );
$( document ).find( '#cn-pricing-plan-pro' ).prop( 'checked', true );
}
} );
// handle free / pro / license selection
$( document ).on( 'change', 'input[name="plan"]', function() {
var input = $( this ),
inputVal = input.val();
if ( inputVal === 'free' ) {
$( '#cn_submit_free' ).removeClass( 'cn-hidden' );
$( '#cn_submit_pro' ).addClass( 'cn-hidden' );
$( '#cn_submit_license' ).addClass( 'cn-hidden' );
$( document ).find( '#cn-pricing-plan-free' ).prop( 'checked', true );
} else if ( inputVal === 'license' ) {
$( '#cn_submit_free' ).addClass( 'cn-hidden' );
$( '#cn_submit_pro' ).addClass( 'cn-hidden' );
$( '#cn_submit_license' ).removeClass( 'cn-hidden' );
$( document ).find( '#cn-pricing-plan-free' ).prop( 'checked', false );
$( document ).find( '#cn-pricing-plan-pro' ).prop( 'checked', false );
} else {
$( '#cn_submit_free' ).addClass( 'cn-hidden' );
$( '#cn_submit_pro' ).removeClass( 'cn-hidden' );
$( '#cn_submit_license' ).addClass( 'cn-hidden' );
$( document ).find( '#cn-pricing-plan-pro' ).prop( 'checked', true );
}
} );
// highlight form
$( document ).on( 'click', 'input[name="cn_pricing"]', function() {
$( '.cn-accordion .cn-accordion-item:first-child:not(.cn-collapsed)' ).focus();
} );
// select plan payment
$( document ).on( 'change', 'input[name="cn_pricing"]', function() {
var input = $( this ),
inputVal = input.val();
if ( inputVal === 'free' ) {
$( '#cn_submit_free' ).removeClass( 'cn-hidden' );
$( '#cn_submit_pro' ).addClass( 'cn-hidden' );
$( document ).find( '#cn-field-plan-free' ).prop( 'checked', true );
} else {
$( '#cn_submit_free' ).addClass( 'cn-hidden' );
$( '#cn_submit_pro' ).removeClass( 'cn-hidden' );
$( document ).find( '#cn-field-plan-pro' ).prop( 'checked', true );
}
} );
// color picker
initSpectrum();
// init welcome modal
if ( cnWelcomeArgs.initModal == true )
initModal();
} );
$( document ).on( 'ajaxComplete', function() {
// color picker
initSpectrum();
} );
function initSpectrum() {
$( '.cn-color-picker' ).spectrum( {
showInput: true,
showInitial: true,
allowEmpty: false,
showAlpha: false
} );
}
function initModal() {
var progressbar,
timerId,
modal = $( "#cn-modal-trigger" );
if ( modal ) {
$( "#cn-modal-trigger" ).modaal( {
content_source: cnWelcomeArgs.ajaxURL + '?action=cn_welcome_screen' + '&nonce=' + cnWelcomeArgs.nonce + '&screen=1',
type: 'ajax',
width: 1600,
custom_class: 'cn-modal',
// is_locked: true
ajax_success: function() {
progressbar = $( document ).find( '.cn-progressbar' );
if ( progressbar ) {
timerId = initProgressBar( progressbar );
}
},
before_close: function() {
clearInterval( timerId );
var currentStep = $( '.cn-welcome-wrap' );
// reload if on success screen
if ( currentStep.length > 0 ) {
if ( $( currentStep[0] ).hasClass( 'cn-welcome-step-4' ) === true )
window.location.reload( true );
}
},
after_close: function() {
progressbar = $( document ).find( '.cn-progressbar' );
$( progressbar ).progressbar( "destroy" );
}
} );
$( modal ).trigger( 'click' );
$( document ).on( 'click', '.cn-skip-button', function( e ) {
$( '#modaal-close' ).trigger( 'click' );
} );
}
}
function initProgressBar( progressbar ) {
var progressbarObj,
progressLabel = $( document ).find( '.cn-progress-label' ),
complianceResults = $( document ).find( '.cn-compliance-results' ),
currentProgress = 0,
timerId;
if ( progressbar ) {
$( document ).on( 'click', '.cn-screen-button', function( e ) {
e.preventDefault();
clearInterval( timerId );
} );
$( progressbar ).progressbar( {
value: 5,
max: 100,
create: function( event, ui ) {
timerId = setInterval( function() {
// increment progress bar
currentProgress += 5;
// update progressbar
progressbar.progressbar( 'value', currentProgress );
var lastItem = $( complianceResults ).find( 'div:visible' ).last(),
lastItemText = $( lastItem ).find( '.cn-compliance-status' ).text();
$( lastItem ).find( '.cn-compliance-status' ).text( lastItemText + ' .' );
switch ( currentProgress ) {
case 25:
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-passed' ).text( cnWelcomeArgs.statusPassed );
$( lastItem ).next().slideDown( 200 );
break;
case 50:
if ( cnWelcomeArgs.complianceStatus === 'active' ) {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-passed' ).text( cnWelcomeArgs.statusPassed );
} else {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-failed' ).text( cnWelcomeArgs.statusFailed );
}
$( lastItem ).next().slideDown( 200 );
break;
case 75:
if ( cnWelcomeArgs.complianceStatus === 'active' ) {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-passed' ).text( cnWelcomeArgs.statusPassed );
} else {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-failed' ).text( cnWelcomeArgs.statusFailed );
}
$( lastItem ).next().slideDown( 200 );
break;
case 100:
if ( cnWelcomeArgs.complianceStatus === 'active' ) {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-passed' ).text( cnWelcomeArgs.statusPassed );
} else {
$( lastItem ).find( '.cn-compliance-status' ).addClass( 'cn-failed' ).text( cnWelcomeArgs.statusFailed );
}
break;
}
// complete
if ( currentProgress >= 100 )
clearInterval( timerId );
}, 300 );
},
change: function( event, ui ) {
progressLabel.text( progressbar.progressbar( 'value' ) + '%' );
},
complete: function( event, ui ) {
setTimeout( function() {
if ( cnWelcomeArgs.complianceStatus )
$( '.cn-compliance-check' ).find( '.cn-compliance-feedback' ).html( '<p class="cn-message">' + cnWelcomeArgs.compliancePassed + '</p>' ).removeClass( 'cn-hidden' );
else
$( '.cn-compliance-check' ).find( '.cn-compliance-feedback' ).html( '<p class="cn-error">' + cnWelcomeArgs.complianceFailed + '</p>' ).removeClass( 'cn-hidden' );
}, 500 );
}
} );
progressbarObj = $( progressbar ).progressbar( "instance" );
return timerId;
}
}
$( document ).on( 'click', '.cn-run-upgrade, .cn-run-welcome', function( e ) {
e.preventDefault();
// modal
initModal();
} );
$( document ).ready( function() {
var welcome = false;
welcome = cnGetUrlParam( 'welcome' );
if ( welcome ) {
// modal
initModal();
}
} );
$( document ).on( 'click', '.cn-sign-up', function( e ) {
e.preventDefault();
$( '.cn-screen-button' ).trigger( 'click' );
} );
var cnGetUrlParam = function cnGetUrlParam( parameter ) {
var pageURL = window.location.search.substring( 1 ),
urlVars = pageURL.split( '&' ),
parameterName,
i;
for ( i = 0; i < urlVars.length; i ++ ) {
parameterName = urlVars[i].split( '=' );
if ( parameterName[0] === parameter )
return typeof parameterName[1] === undefined ? true : decodeURIComponent( parameterName[1] );
}
return false;
};
} )( jQuery );
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
// initialize color picker
$( '.cn_color' ).wpColorPicker();
// purge cache
$( '#cn_app_purge_cache a' ).on( 'click', function( e ) {
e.preventDefault();
var el = this;
$( el ).parent().addClass( 'loading' ).append( '<span class="spinner is-active" style="float: none"></span>' );
var ajaxArgs = {
action: 'cn_purge_cache',
nonce: cnArgs.nonce
};
// network area?
if ( cnArgs.network )
ajaxArgs.cn_network = 1;
$.ajax( {
url: cnArgs.ajaxURL,
type: 'POST',
dataType: 'json',
data: ajaxArgs
} ).always( function( result ) {
$( el ).parent().find( '.spinner' ).remove();
} );
} );
// global override
$( 'input[name="cookie_notice_options[global_override]"]' ).on( 'change', function() {
$( '.cookie-notice-settings form' ).toggleClass( 'cn-options-disabled' );
} );
// refuse option
$( '#cn_refuse_opt' ).on( 'change', function() {
if ( $( this ).is( ':checked' ) )
$( '#cn_refuse_opt_container' ).slideDown( 'fast' );
else
$( '#cn_refuse_opt_container' ).slideUp( 'fast' );
} );
// revoke option
$( '#cn_revoke_cookies' ).on( 'change', function() {
if ( $( this ).is( ':checked' ) )
$( '#cn_revoke_opt_container' ).slideDown( 'fast' );
else
$( '#cn_revoke_opt_container' ).slideUp( 'fast' );
} );
// privacy policy option
$( '#cn_see_more' ).on( 'change', function() {
if ( $( this ).is( ':checked' ) )
$( '#cn_see_more_opt' ).slideDown( 'fast' );
else
$( '#cn_see_more_opt' ).slideUp( 'fast' );
} );
// on scroll option
$( '#cn_on_scroll' ).on( 'change', function() {
if ( $( this ).is( ':checked' ) )
$( '#cn_on_scroll_offset' ).slideDown( 'fast' );
else
$( '#cn_on_scroll_offset' ).slideUp( 'fast' );
} );
// conditional display option
$( '#cn_conditional_display_opt' ).on( 'change', function() {
if ( $( this ).is( ':checked' ) )
$( '#cn_conditional_display_opt_container' ).slideDown( 'fast' );
else
$( '#cn_conditional_display_opt_container' ).slideUp( 'fast' );
} );
// privacy policy link
$( '#cn_see_more_link-custom, #cn_see_more_link-page' ).on( 'change', function() {
if ( $( '#cn_see_more_link-custom:checked' ).val() === 'custom' ) {
$( '#cn_see_more_opt_page' ).slideUp( 'fast', function() {
$( '#cn_see_more_opt_link' ).slideDown( 'fast' );
} );
} else if ( $( '#cn_see_more_link-page:checked' ).val() === 'page' ) {
$( '#cn_see_more_opt_link' ).slideUp( 'fast', function() {
$( '#cn_see_more_opt_page' ).slideDown( 'fast' );
} );
}
} );
// script blocking
$( '#cn_refuse_code_fields' ).find( 'a' ).on( 'click', function( e ) {
e.preventDefault();
$( '#cn_refuse_code_fields' ).find( 'a' ).removeClass( 'nav-tab-active' );
$( '.refuse-code-tab' ).removeClass( 'active' );
var id = $( this ).attr( 'id' ).replace( '-tab', '' );
$( '#' + id ).addClass( 'active' );
$( this ).addClass( 'nav-tab-active' );
} );
// add new group of rules
$( document ).on( 'click', '.add-rule-group', function( e ) {
e.preventDefault();
var html = $( '#rules-group-template' ).html();
var group = $( '#rules-groups' );
var groups = group.find( '.rules-group' );
var groupID = ( groups.length > 0 ? parseInt( groups.last().attr( 'id' ).split( '-' )[2] ) + 1 : 1 );
html = html.replace( /__GROUP_ID__/g, groupID );
html = html.replace( /__RULE_ID__/g, 1 );
group.append( '<div class="rules-group" id="rules-group-' + groupID + '">' + html + '</div>' );
group.find( '.rules-group' ).last().fadeIn( 'fast' );
} );
// remove single rule or group
$( document ).on( 'click', '.remove-rule', function( e ) {
e.preventDefault();
var number = $( this ).closest( 'tbody' ).find( 'tr' ).length;
if ( number === 1 ) {
$( this ).closest( '.rules-group' ).fadeOut( 'fast', function() {
$( this ).remove();
} );
} else {
$( this ).closest( 'tr' ).fadeOut( 'fast', function() {
$( this ).remove();
} );
}
} );
// handle changing values for specified type of rules
$( document ).on( 'change', '.rule-type', function() {
var el = $( this );
var td = el.closest( 'tr' ).find( 'td.value' );
var select = td.find( 'select' );
var spinner = td.find( '.spinner' );
select.hide();
spinner.fadeIn( 'fast' ).css( 'visibility', 'visible' );
$.post( ajaxurl, {
action: 'cn-get-group-rules-values',
cn_param: el.val(),
cn_nonce: cnArgs.nonceConditional
} ).done( function( data ) {
spinner.hide().css( 'visibility', 'hidden' );
try {
var response = $.parseJSON( data );
// replace old select options with new ones
select.fadeIn( 'fast' ).find( 'option' ).remove().end().append( response.select );
} catch( e ) {
//
}
} ).fail(function() {
//
} );
} );
} );
$( document ).on( 'click', 'input#reset_cookie_notice_options', function() {
return confirm( cnArgs.resetToDefaults );
} );
} )( jQuery );
\ No newline at end of file
!function(e){e(function(){e(".cn_color").wpColorPicker(),e("#cn_app_purge_cache a").on("click",function(n){n.preventDefault();var o=this;e(o).parent().addClass("loading").append('<span class="spinner is-active" style="float: none"></span>');var t={action:"cn_purge_cache",nonce:cnArgs.nonce};cnArgs.network&&(t.cn_network=1),e.ajax({url:cnArgs.ajaxURL,type:"POST",dataType:"json",data:t}).always(function(n){e(o).parent().find(".spinner").remove()})}),e('input[name="cookie_notice_options[global_override]"]').on("change",function(){e(".cookie-notice-settings form").toggleClass("cn-options-disabled")}),e("#cn_refuse_opt").on("change",function(){e(this).is(":checked")?e("#cn_refuse_opt_container").slideDown("fast"):e("#cn_refuse_opt_container").slideUp("fast")}),e("#cn_revoke_cookies").on("change",function(){e(this).is(":checked")?e("#cn_revoke_opt_container").slideDown("fast"):e("#cn_revoke_opt_container").slideUp("fast")}),e("#cn_see_more").on("change",function(){e(this).is(":checked")?e("#cn_see_more_opt").slideDown("fast"):e("#cn_see_more_opt").slideUp("fast")}),e("#cn_on_scroll").on("change",function(){e(this).is(":checked")?e("#cn_on_scroll_offset").slideDown("fast"):e("#cn_on_scroll_offset").slideUp("fast")}),e("#cn_conditional_display_opt").on("change",function(){e(this).is(":checked")?e("#cn_conditional_display_opt_container").slideDown("fast"):e("#cn_conditional_display_opt_container").slideUp("fast")}),e("#cn_see_more_link-custom, #cn_see_more_link-page").on("change",function(){"custom"===e("#cn_see_more_link-custom:checked").val()?e("#cn_see_more_opt_page").slideUp("fast",function(){e("#cn_see_more_opt_link").slideDown("fast")}):"page"===e("#cn_see_more_link-page:checked").val()&&e("#cn_see_more_opt_link").slideUp("fast",function(){e("#cn_see_more_opt_page").slideDown("fast")})}),e("#cn_refuse_code_fields").find("a").on("click",function(n){n.preventDefault(),e("#cn_refuse_code_fields").find("a").removeClass("nav-tab-active"),e(".refuse-code-tab").removeClass("active");var o=e(this).attr("id").replace("-tab","");e("#"+o).addClass("active"),e(this).addClass("nav-tab-active")}),e(document).on("click",".add-rule-group",function(n){n.preventDefault();var o=e("#rules-group-template").html(),t=e("#rules-groups"),s=t.find(".rules-group"),c=s.length>0?parseInt(s.last().attr("id").split("-")[2])+1:1;o=(o=o.replace(/__GROUP_ID__/g,c)).replace(/__RULE_ID__/g,1),t.append('<div class="rules-group" id="rules-group-'+c+'">'+o+"</div>"),t.find(".rules-group").last().fadeIn("fast")}),e(document).on("click",".remove-rule",function(n){n.preventDefault(),1===e(this).closest("tbody").find("tr").length?e(this).closest(".rules-group").fadeOut("fast",function(){e(this).remove()}):e(this).closest("tr").fadeOut("fast",function(){e(this).remove()})}),e(document).on("change",".rule-type",function(){var n=e(this),o=n.closest("tr").find("td.value"),t=o.find("select"),s=o.find(".spinner");t.hide(),s.fadeIn("fast").css("visibility","visible"),e.post(ajaxurl,{action:"cn-get-group-rules-values",cn_param:n.val(),cn_nonce:cnArgs.nonceConditional}).done(function(n){s.hide().css("visibility","hidden");try{var o=e.parseJSON(n);t.fadeIn("fast").find("option").remove().end().append(o.select)}catch(c){}}).fail(function(){})})}),e(document).on("click","input#reset_cookie_notice_options",function(){return confirm(cnArgs.resetToDefaults)})}(jQuery);
\ No newline at end of file
( function( $ ) {
// ready event
$( function() {
var cnHiddenElements = {};
// listen for the load
document.addEventListener( 'load.hu', function( e ) {
// set widget text strings
hu.setTexts( cnFrontWelcome.textStrings );
} );
// listen for the reload
document.addEventListener( 'reload.hu', function( e ) {
var container = $( '#hu' );
var customOptions = { config: {
dontSellLink: true,
privacyPolicyLink: true,
privacyPaper: true,
privacyContact: true
} };
// set widget options
hu.setOptions( customOptions );
} );
// listen for the display
document.addEventListener( 'display.hu', function( e ) {
var val = [];
var container = $( '#hu' );
var customOptions = { config: {
// make it empty
} };
$( parent.document ).find( 'input[name="cn_laws"]:checked' ).each( function() {
val.push( $( this ).val() );
} );
// hide paper and contact
if ( $( parent.document ).find( 'input[name="cn_privacy_paper"]' ).prop( 'checked' ) === true )
$( container ).find( '#hu-cookies-paper' ).show();
else
$( container ).find( '#hu-cookies-paper' ).hide();
if ( $( parent.document ).find( 'input[name="cn_privacy_contact"]' ).prop( 'checked' ) === true )
$( container ).find( '#hu-cookies-contact' ).show();
else
$( container ).find( '#hu-cookies-contact' ).hide();
if ( $.inArray( 'ccpa', val ) !== -1 ) {
var htmlElement = $( $( container ).find( '#hu-cookies-notice-dontsell-btn' ) );
if ( htmlElement.length === 0 ) {
$( '#hu-policy-links' ).append( cnHiddenElements.ccpa );
delete cnHiddenElements.ccpa;
}
$.extend( customOptions.config, { dontSellLink: true } );
} else {
var htmlElement = $( $( container ).find( '#hu-cookies-notice-dontsell-btn' ) );
// add to hidden elements
if ( htmlElement ) {
cnHiddenElements['ccpa'] = htmlElement;
// remove el
$( htmlElement ).remove();
}
$.extend( customOptions.config, { dontSellLink: false } );
}
if ( $.inArray( 'gdpr', val ) !== -1 ) {
var htmlElement = $( $( container ).find( '#hu-cookies-notice-privacy-btn' ) );
if ( htmlElement.length === 0 ) {
$( '#hu-policy-links' ).prepend( cnHiddenElements.gdpr );
delete cnHiddenElements.gdpr;
}
$.extend( customOptions.config, { privacyPolicyLink: true } );
} else {
var htmlElement = $( $( container ).find( '#hu-cookies-notice-privacy-btn' ) );
// add to hidden elements
if ( htmlElement ) {
cnHiddenElements['gdpr'] = htmlElement;
// remove el
$( htmlElement ).remove();
}
$.extend( customOptions.config, { privacyPolicyLink: false } );
}
// set widget options
hu.setOptions( customOptions );
} );
// listen for the parent
window.addEventListener( 'message', function( event ) {
var iframe = $( parent.document ).find( '#cn_iframe_id' );
var form = $( parent.document ).find( '#cn-form-configure' );
// add spinner
$( iframe ).closest( '.has-loader' ).addClass( 'cn-loading' ).append( '<span class="cn-spinner"></span>' );
// lock options
$( form ).addClass( 'cn-form-disabled' );
// emit loader
window.setTimeout( function() {
if ( typeof event.data == 'object' ) {
var container = $( '#hu' );
var option = event.data.call;
var customOptions = {};
var customTexts = {};
switch ( option ) {
case 'position':
$( container ).removeClass( 'hu-position-bottom hu-position-top hu-position-left hu-position-right hu-position-center' );
$( container ).addClass( 'hu-position-' + event.data.value );
customOptions = { design: { position: event.data.value } }
break;
case 'naming':
var level1 = $( '.hu-cookies-notice-consent-choices-1' );
var level2 = $( '.hu-cookies-notice-consent-choices-2' );
var level3 = $( '.hu-cookies-notice-consent-choices-3' );
var text1 = cnFrontWelcome.levelNames[event.data.value][1];
var text2 = cnFrontWelcome.levelNames[event.data.value][2];
var text3 = cnFrontWelcome.levelNames[event.data.value][3];
// apply text to dom elements
$( level1 ).find( '.hu-toggle-label' ).text( text1 );
$( level2 ).find( '.hu-toggle-label' ).text( text2 );
$( level3 ).find( '.hu-toggle-label' ).text( text3 );
// apply text to text strings
customTexts = {
levelNameText_1: text1,
levelNameText_2: text2,
levelNameText_3: text3
}
break;
case 'laws':
customOptions.config = {}
if ( $.inArray( 'ccpa', event.data.value ) !== -1 ) {
var htmlElement = $( container ).find( '#hu-cookies-notice-dontsell-btn' );
if ( htmlElement.length === 0 ) {
$( '#hu-policy-links' ).append( cnHiddenElements.ccpa );
delete cnHiddenElements.ccpa;
}
$.extend( customOptions.config, { dontSellLink: true } );
} else {
var htmlElement = $( container ).find( '#hu-cookies-notice-dontsell-btn' );
// add to hidden elements
if ( htmlElement && ! cnHiddenElements.hasOwnProperty( 'ccpa' ) ) {
cnHiddenElements['ccpa'] = htmlElement;
// remove el
$( htmlElement ).remove();
}
$.extend( customOptions.config, { dontSellLink: false } );
}
if ( $.inArray( 'gdpr', event.data.value ) !== -1 ) {
var htmlElement = $( container ).find( '#hu-cookies-notice-privacy-btn' );
if ( htmlElement.length === 0 ) {
$( '#hu-policy-links' ).prepend( cnHiddenElements.gdpr );
delete cnHiddenElements.gdpr;
}
$.extend( customOptions.config, { privacyPolicyLink: true } );
} else {
var htmlElement = $( container ).find( '#hu-cookies-notice-privacy-btn' );
// add to hidden elements
if ( htmlElement && ! cnHiddenElements.hasOwnProperty( 'gdpr' ) ) {
cnHiddenElements['gdpr'] = htmlElement;
// remove el
$( htmlElement ).remove();
}
$.extend( customOptions.config, { privacyPolicyLink: false } );
}
break;
case 'privacy_paper':
var value = event.data.value === true;
var htmlElement = $( container ).find( '#hu-cookies-paper' );
if ( value )
$( htmlElement ).show();
else
$( htmlElement ).hide();
$.extend( customOptions.config, { privacyPaper: value } );
break;
case 'privacy_contact':
var value = event.data.value === true;
var htmlElement = $( container ).find( '#hu-cookies-contact');
if ( value )
$( htmlElement ).show();
else
$( htmlElement ).hide();
$.extend( customOptions.config, { privacyContact: value } );
break;
case 'color_primary':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-primaryColor', event.data.value );
customOptions = { design: { primaryColor: event.data.value } }
break;
case 'color_background':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-bannerColor', event.data.value );
customOptions = { design: { bannerColor: event.data.value } }
break;
case 'color_border':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-borderColor', event.data.value );
customOptions = { design: { borderColor: event.data.value } }
break;
case 'color_text':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-textColor', event.data.value );
customOptions = { design: { textColor: event.data.value } }
break;
case 'color_heading':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-headingColor', event.data.value );
customOptions = { design: { headingColor: event.data.value } }
break;
case 'color_button_text':
var iframeContents = $( iframe ).contents()[0];
iframeContents.documentElement.style.setProperty( '--hu-btnTextColor', event.data.value );
customOptions = { design: { btnTextColor: event.data.value } }
break;
}
// set widget options
hu.setOptions( customOptions );
// set widget texts
hu.setTexts( customTexts );
}
// remove spinner
$( iframe ).closest( '.has-loader' ).find( '.cn-spinner' ).remove();
$( iframe ).closest( '.has-loader' ).removeClass( 'cn-loading' );
// unlock options
$( form ).removeClass( 'cn-form-disabled' );
}, 500 );
}, false );
// is it iframe?
if ( document !== parent.document && typeof cnFrontWelcome !== 'undefined' && cnFrontWelcome.previewMode ) {
var iframe = $( parent.document ).find( '#cn_iframe_id' );
// inject links into initial document
$( document.body ).find( 'a[href], area[href]' ).each( function() {
cnAddPreviewModeToLink( this, iframe );
} );
// inject links into initial document
$( document.body ).find( 'form' ).each( function() {
cnAddPreviewModeToForm( this, iframe );
} );
// inject links for new elements added to the page
if ( typeof MutationObserver !== 'undefined' ) {
var observer = new MutationObserver( function( mutations ) {
_.each( mutations, function( mutation ) {
$( mutation.target ).find( 'a[href], area[href]' ).each( function() {
cnAddPreviewModeToLink( this, iframe );
} );
$( mutation.target ).find( 'form' ).each( function() {
cnAddPreviewModeToForm( this, iframe );
} );
} );
} );
observer.observe( document.documentElement, {
childList: true,
subtree: true
} );
} else {
// If mutation observers aren't available, fallback to just-in-time injection.
$( document.documentElement ).on( 'click focus mouseover', 'a[href], area[href]', function() {
cnAddPreviewModeToLink( this, iframe );
} );
}
// remove spinner
$( iframe ).closest( '.has-loader' ).find( '.cn-spinner' ).remove();
$( iframe ).closest( '.has-loader' ).removeClass( 'cn-loading' );
}
} );
/**
* Inject preview mode parameter into specific links on the frontend.
*/
function cnAddPreviewModeToLink( element, iframe ) {
var params, $element = $( element );
// skip elements with no href attribute
if ( ! element.hasAttribute( 'href' ) )
return;
// skip links in admin bar
if ( $element.closest( '#wpadminbar' ).length )
return;
// ignore links with href="#", href="#id", or non-HTTP protocols (e.g. javascript: and mailto:)
if ( '#' === $element.attr( 'href' ).substr( 0, 1 ) || ! /^https?:$/.test( element.protocol ) )
return;
// make sure links in preview use HTTPS if parent frame uses HTTPS.
// if ( api.settings.channel && 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.host ) )
// element.protocol = 'https:';
// ignore links with special class
if ( $element.hasClass( 'wp-playlist-caption' ) )
return;
// check special links
if ( ! cnIsLinkPreviewable( element ) )
return;
$( element ).on( 'click', function() {
$( iframe ).closest( '.has-loader' ).addClass( 'cn-loading' );
} );
// parse query string
params = cnParseQueryString( element.search.substring( 1 ) );
// set preview mode
params.cn_preview_mode = 1;
element.search = $.param( params );
}
/**
* Inject preview mode parameter into specific forms on the frontend.
*/
function cnAddPreviewModeToForm( element, iframe ) {
var input = document.createElement( 'input' );
input.setAttribute( 'type', 'hidden' );
input.setAttribute( 'name', 'cn_preview_mode' );
input.setAttribute( 'value', 1 );
element.appendChild( input );
}
/**
* Parse query string.
*/
function cnParseQueryString( string ) {
var params = {};
_.each( string.split( '&' ), function( pair ) {
var parts, key, value;
parts = pair.split( '=', 2 );
if ( ! parts[0] )
return;
key = decodeURIComponent( parts[0].replace( /\+/g, ' ' ) );
key = key.replace( / /g, '_' );
if ( _.isUndefined( parts[1] ) )
value = null;
else
value = decodeURIComponent( parts[1].replace( /\+/g, ' ' ) );
params[ key ] = value;
} );
return params;
}
/**
* Whether the supplied link is previewable.
*/
function cnIsLinkPreviewable( element ) {
var matchesAllowedUrl, parsedAllowedUrl, elementHost;
if ( 'javascript:' === element.protocol )
return true;
// only web urls can be previewed
if ( element.protocol !== 'https:' && element.protocol !== 'http:' )
return false;
elementHost = element.host.replace( /:(80|443)$/, '' );
parsedAllowedUrl = document.createElement( 'a' );
matchesAllowedUrl = ! _.isUndefined( _.find( cnFrontWelcome.allowedURLs, function( allowedUrl ) {
parsedAllowedUrl.href = allowedUrl;
return parsedAllowedUrl.protocol === element.protocol && parsedAllowedUrl.host.replace( /:(80|443)$/, '' ) === elementHost && 0 === element.pathname.indexOf( parsedAllowedUrl.pathname.replace( /\/$/, '' ) );
} ) );
if ( ! matchesAllowedUrl )
return false;
// skip wp login and signup pages
if ( /\/wp-(login|signup)\.php$/.test( element.pathname ) )
return false;
// allow links to admin ajax as faux frontend URLs
if ( /\/wp-admin\/admin-ajax\.php$/.test( element.pathname ) )
return false;
// disallow links to admin, includes, and content
if ( /\/wp-(admin|includes|content)(\/|$)/.test( element.pathname ) )
return false;
return true;
};
} )( jQuery );
\ No newline at end of file
// CustomEvent polyfil for IE support
( function() {
if ( typeof window.CustomEvent === "function" )
return false;
function CustomEvent( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
} )();
// ClassList polyfil for IE/Safari support
( function() {
var regExp = function ( name ) {
return new RegExp( '(^| )' + name + '( |$)' );
};
var forEach = function ( list, fn, scope ) {
for ( var i = 0; i < list.length; i++ ) {
fn.call( scope, list[i] );
}
};
function ClassList( element ) {
this.element = element;
}
ClassList.prototype = {
add: function() {
forEach( arguments, function ( name ) {
if ( !this.contains( name ) ) {
this.element.className += this.element.className.length > 0 ? ' ' + name : name;
}
}, this );
},
remove: function() {
forEach( arguments, function ( name ) {
this.element.className =
this.element.className.replace( regExp( name ), '' );
}, this );
},
toggle: function ( name ) {
return this.contains( name )
? ( this.remove( name ), false ) : ( this.add( name ), true );
},
contains: function ( name ) {
return regExp( name ).test( this.element.className );
},
// bonus..
replace: function ( oldName, newName ) {
this.remove( oldName ), this.add( newName );
}
};
// IE8/9, Safari
if ( !( 'classList' in Element.prototype ) ) {
Object.defineProperty( Element.prototype, 'classList', {
get: function() {
return new ClassList( this );
}
} );
}
if ( window.DOMTokenList && DOMTokenList.prototype.replace == null )
DOMTokenList.prototype.replace = ClassList.prototype.replace;
} )();
// cookieNotice
( function ( window, document, undefined ) {
var cookieNotice = new function() {
// cookie status
this.cookiesAccepted = null;
// notice container
this.noticeContainer = null;
// set cookie value
this.setStatus = function ( cookieValue ) {
var _this = this;
var cookieDomain = '';
var cookiePath = '';
var date = new Date();
var laterDate = new Date();
// remove listening to scroll event
if ( cnArgs.onScroll )
window.removeEventListener( 'scroll', this.handleScroll );
// set cookie type and expiry time in seconds
if ( cookieValue === 'accept' ) {
cookieValue = 'true';
laterDate.setTime( parseInt( date.getTime() ) + parseInt( cnArgs.cookieTime ) * 1000 );
} else {
cookieValue = 'false';
laterDate.setTime( parseInt( date.getTime() ) + parseInt( cnArgs.cookieTimeRejected ) * 1000 );
}
if ( cnArgs.globalCookie )
cookieDomain = this.getDomain( document.location.hostname );
// get domain path in localhost
if ( document.location.hostname === 'localhost' )
cookiePath = document.location.pathname.split( '/' )[1];
var secureValue = '';
if ( document.location.protocol === 'https:' )
secureValue = ';secure';
// set cookie
document.cookie = cnArgs.cookieName + '=' + cookieValue + ';expires=' + laterDate.toUTCString() + ';path=/' + cookiePath + ';domain=' + cookieDomain + secureValue;
// update global status
this.cookiesAccepted = cookieValue === 'true';
// trigger custom event
var event = new CustomEvent(
'setCookieNotice',
{
detail: {
value: cookieValue,
time: date,
expires: laterDate,
data: cnArgs
}
}
);
document.dispatchEvent( event );
this.setBodyClass( [ 'cookies-set', cookieValue === 'true' ? 'cookies-accepted' : 'cookies-refused' ] );
this.hideCookieNotice();
// show revoke notice if enabled
if ( cnArgs.revokeCookiesOpt === 'automatic' ) {
// show cookie notice after the revoke is hidden
this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.showRevokeNotice();
} );
this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.showRevokeNotice();
} );
}
// redirect?
if ( cnArgs.redirection && ( ( cookieValue === 'true' && this.cookiesAccepted === null ) || ( cookieValue !== this.cookiesAccepted && this.cookiesAccepted !== null ) ) ) {
var url = window.location.protocol + '//',
hostname = window.location.host + '/' + window.location.pathname;
// is cache enabled?
if ( cnArgs.cache ) {
url = url + hostname.replace( '//', '/' ) + ( window.location.search === '' ? '?' : window.location.search + '&' ) + 'cn-reloaded=1' + window.location.hash;
window.location.href = url;
} else {
url = url + hostname.replace( '//', '/' ) + window.location.search + window.location.hash;
window.location.reload( true );
}
return;
}
};
// get domain
this.getDomain = function( url ) {
var regex = new RegExp( /https?:\/\// );
if ( ! regex.test( url ) )
url = 'http://' + url;
var parts = new URL( url ).hostname.split( '.' );
return parts.slice( 0 ).slice( -( parts.length === 4 ? 3 : 2 ) ).join( '.' );
}
// get cookie value
this.getStatus = function ( bool ) {
var value = "; " + document.cookie,
parts = value.split( '; cookie_notice_accepted=' );
if ( parts.length === 2 ) {
var val = parts.pop().split( ';' ).shift();
if ( bool )
return val === 'true';
else
return val;
} else
return null;
};
// display cookie notice
this.showCookieNotice = function() {
var _this = this;
// trigger custom event
var event = new CustomEvent(
'showCookieNotice',
{
detail: {
data: cnArgs
}
}
);
document.dispatchEvent( event );
this.noticeContainer.classList.remove( 'cookie-notice-hidden' );
this.noticeContainer.classList.add( 'cn-animated' );
this.noticeContainer.classList.add( 'cookie-notice-visible' );
// detect animation
this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
} );
this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
} );
};
// hide cookie notice
this.hideCookieNotice = function() {
var _this = this;
// trigger custom event
var event = new CustomEvent(
'hideCookieNotice',
{
detail: {
data: cnArgs
}
}
);
document.dispatchEvent( event );
this.noticeContainer.classList.add( 'cn-animated' );
this.noticeContainer.classList.remove( 'cookie-notice-visible' );
// detect animation
this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
_this.noticeContainer.classList.add( 'cookie-notice-hidden' );
} );
this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
_this.noticeContainer.classList.add( 'cookie-notice-hidden' );
} );
};
// display revoke notice
this.showRevokeNotice = function() {
var _this = this;
// trigger custom event
var event = new CustomEvent(
'showRevokeNotice',
{
detail: {
data: cnArgs
}
}
);
document.dispatchEvent( event );
this.noticeContainer.classList.remove( 'cookie-revoke-hidden' );
this.noticeContainer.classList.add( 'cn-animated' );
this.noticeContainer.classList.add( 'cookie-revoke-visible' );
// detect animation
this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
} );
this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
} );
};
// hide revoke notice
this.hideRevokeNotice = function() {
var _this = this;
// trigger custom event
var event = new CustomEvent(
'hideRevokeNotice',
{
detail: {
data: cnArgs
}
}
);
document.dispatchEvent( event );
this.noticeContainer.classList.add( 'cn-animated' );
this.noticeContainer.classList.remove( 'cookie-revoke-visible' );
// detect animation
this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
_this.noticeContainer.classList.add( 'cookie-revoke-hidden' );
} );
this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.noticeContainer.classList.remove( 'cn-animated' );
_this.noticeContainer.classList.add( 'cookie-revoke-hidden' );
} );
};
// change body classes
this.setBodyClass = function ( classes ) {
// remove body classes
document.body.classList.remove( 'cookies-revoke' );
document.body.classList.remove( 'cookies-accepted' );
document.body.classList.remove( 'cookies-refused' );
document.body.classList.remove( 'cookies-set' );
document.body.classList.remove( 'cookies-not-set' );
// add body classes
for ( var i = 0; i < classes.length; i++ ) {
document.body.classList.add( classes[i] );
}
};
// handle mouse scrolling
this.handleScroll = function() {
var scrollTop = window.pageYOffset || ( document.documentElement || document.body.parentNode || document.body ).scrollTop
// accept cookie
if ( scrollTop > parseInt( cnArgs.onScrollOffset ) )
this.setStatus( 'accept' );
};
// cross browser compatible closest function
this.getClosest = function ( elem, selector ) {
// element.matches() polyfill
if ( !Element.prototype.matches ) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function ( s ) {
var matches = ( this.document || this.ownerDocument ).querySelectorAll( s ),
i = matches.length;
while ( --i >= 0 && matches.item( i ) !== this ) {
}
return i > -1;
};
}
// get the closest matching element
for ( ; elem && elem !== document; elem = elem.parentNode ) {
if ( elem.matches( selector ) )
return elem;
}
return null;
};
// check if displaye in an iframe
this.inIframe = function() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
// initialize
this.init = function() {
var _this = this;
// bail if in iframe
if ( this.inIframe() === true )
return;
this.cookiesAccepted = this.getStatus( true );
this.noticeContainer = document.getElementById( 'cookie-notice' );
// no container?
if ( ! this.noticeContainer )
return;
var cookieButtons = document.getElementsByClassName( 'cn-set-cookie' ),
revokeButtons = document.getElementsByClassName( 'cn-revoke-cookie' ),
closeIcon = document.getElementById( 'cn-close-notice' );
// add effect class
this.noticeContainer.classList.add( 'cn-effect-' + cnArgs.hideEffect );
// check cookies status
if ( this.cookiesAccepted === null ) {
// handle on scroll
if ( cnArgs.onScroll )
window.addEventListener( 'scroll', function ( e ) {
_this.handleScroll();
} );
// handle on click
if ( cnArgs.onClick )
window.addEventListener( 'click', function ( e ) {
var outerContainer = _this.getClosest( e.target, '#cookie-notice' );
// accept notice if clicked element is not inside the container
if ( outerContainer === null )
_this.setStatus( 'accept' );
}, true );
this.setBodyClass( [ 'cookies-not-set' ] );
// show cookie notice
this.showCookieNotice();
} else {
this.setBodyClass( [ 'cookies-set', this.cookiesAccepted === true ? 'cookies-accepted' : 'cookies-refused' ] );
// show revoke notice if enabled
if ( cnArgs.revokeCookies && cnArgs.revokeCookiesOpt === 'automatic' )
this.showRevokeNotice();
}
// handle cookie buttons click
for ( var i = 0; i < cookieButtons.length; i++ ) {
cookieButtons[i].addEventListener( 'click', function ( e ) {
e.preventDefault();
// Chrome double click event fix
e.stopPropagation();
_this.setStatus( this.dataset.cookieSet );
} );
}
// handle close icon
if ( closeIcon !== null ) {
closeIcon.addEventListener( 'click', function ( e ) {
e.preventDefault();
// Chrome double click event fix
e.stopPropagation();
_this.setStatus( 'reject' );
} );
}
// handle revoke buttons click
for ( var i = 0; i < revokeButtons.length; i++ ) {
revokeButtons[i].addEventListener( 'click', function ( e ) {
e.preventDefault();
// hide revoke notice
if ( _this.noticeContainer.classList.contains( 'cookie-revoke-visible' ) ) {
_this.hideRevokeNotice();
// show cookie notice after the revoke is hidden
_this.noticeContainer.addEventListener( 'animationend', function handler() {
_this.noticeContainer.removeEventListener( 'animationend', handler );
_this.showCookieNotice();
} );
_this.noticeContainer.addEventListener( 'webkitAnimationEnd', function handler() {
_this.noticeContainer.removeEventListener( 'webkitAnimationEnd', handler );
_this.showCookieNotice();
} );
// show cookie notice
} else if ( _this.noticeContainer.classList.contains( 'cookie-notice-hidden' ) && _this.noticeContainer.classList.contains( 'cookie-revoke-hidden' ) )
_this.showCookieNotice();
} );
}
};
}
// initialize plugin
window.addEventListener( 'load', function() {
cookieNotice.init();
}, false );
} )( window, document, undefined );
\ No newline at end of file
!function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),n}e.prototype=window.Event.prototype,window.CustomEvent=e}(),function(){var e=function(e){return RegExp("(^| )"+e+"( |$)")},t=function(e,t,n){for(var i=0;i<e.length;i++)t.call(n,e[i])};function n(e){this.element=e}n.prototype={add:function(){t(arguments,function(e){this.contains(e)||(this.element.className+=this.element.className.length>0?" "+e:e)},this)},remove:function(){t(arguments,function(t){this.element.className=this.element.className.replace(e(t),"")},this)},toggle:function(e){return this.contains(e)?(this.remove(e),!1):(this.add(e),!0)},contains:function(t){return e(t).test(this.element.className)},replace:function(e,t){this.remove(e),this.add(t)}},"classList"in Element.prototype||Object.defineProperty(Element.prototype,"classList",{get:function(){return new n(this)}}),window.DOMTokenList&&null==DOMTokenList.prototype.replace&&(DOMTokenList.prototype.replace=n.prototype.replace)}(),function(e,t,n){var i=new function(){this.cookiesAccepted=null,this.noticeContainer=null,this.setStatus=function(n){var i=this,o="",s="",c=new Date,a=new Date;cnArgs.onScroll&&e.removeEventListener("scroll",this.handleScroll),"accept"===n?(n="true",a.setTime(parseInt(c.getTime())+1e3*parseInt(cnArgs.cookieTime))):(n="false",a.setTime(parseInt(c.getTime())+1e3*parseInt(cnArgs.cookieTimeRejected))),cnArgs.globalCookie&&(o=this.getDomain(t.location.hostname)),"localhost"===t.location.hostname&&(s=t.location.pathname.split("/")[1]);var r="";"https:"===t.location.protocol&&(r=";secure"),t.cookie=cnArgs.cookieName+"="+n+";expires="+a.toUTCString()+";path=/"+s+";domain="+o+r,this.cookiesAccepted="true"===n;var d=new CustomEvent("setCookieNotice",{detail:{value:n,time:c,expires:a,data:cnArgs}});if(t.dispatchEvent(d),this.setBodyClass(["cookies-set","true"===n?"cookies-accepted":"cookies-refused"]),this.hideCookieNotice(),"automatic"===cnArgs.revokeCookiesOpt&&(this.noticeContainer.addEventListener("animationend",function e(){i.noticeContainer.removeEventListener("animationend",e),i.showRevokeNotice()}),this.noticeContainer.addEventListener("webkitAnimationEnd",function e(){i.noticeContainer.removeEventListener("webkitAnimationEnd",e),i.showRevokeNotice()})),cnArgs.redirection&&("true"===n&&null===this.cookiesAccepted||n!==this.cookiesAccepted&&null!==this.cookiesAccepted)){var l=e.location.protocol+"//",h=e.location.host+"/"+e.location.pathname;cnArgs.cache?(l=l+h.replace("//","/")+(""===e.location.search?"?":e.location.search+"&")+"cn-reloaded=1"+e.location.hash,e.location.href=l):(l=l+h.replace("//","/")+e.location.search+e.location.hash,e.location.reload(!0));return}},this.getDomain=function(e){RegExp(/https?:\/\//).test(e)||(e="http://"+e);var t=new URL(e).hostname.split(".");return t.slice(0).slice(-(4===t.length?3:2)).join(".")},this.getStatus=function(e){var n=("; "+t.cookie).split("; cookie_notice_accepted=");if(2!==n.length)return null;var i=n.pop().split(";").shift();return e?"true"===i:i},this.showCookieNotice=function(){var e=this,n=new CustomEvent("showCookieNotice",{detail:{data:cnArgs}});t.dispatchEvent(n),this.noticeContainer.classList.remove("cookie-notice-hidden"),this.noticeContainer.classList.add("cn-animated"),this.noticeContainer.classList.add("cookie-notice-visible"),this.noticeContainer.addEventListener("animationend",function t(){e.noticeContainer.removeEventListener("animationend",t),e.noticeContainer.classList.remove("cn-animated")}),this.noticeContainer.addEventListener("webkitAnimationEnd",function t(){e.noticeContainer.removeEventListener("webkitAnimationEnd",t),e.noticeContainer.classList.remove("cn-animated")})},this.hideCookieNotice=function(){var e=this,n=new CustomEvent("hideCookieNotice",{detail:{data:cnArgs}});t.dispatchEvent(n),this.noticeContainer.classList.add("cn-animated"),this.noticeContainer.classList.remove("cookie-notice-visible"),this.noticeContainer.addEventListener("animationend",function t(){e.noticeContainer.removeEventListener("animationend",t),e.noticeContainer.classList.remove("cn-animated"),e.noticeContainer.classList.add("cookie-notice-hidden")}),this.noticeContainer.addEventListener("webkitAnimationEnd",function t(){e.noticeContainer.removeEventListener("webkitAnimationEnd",t),e.noticeContainer.classList.remove("cn-animated"),e.noticeContainer.classList.add("cookie-notice-hidden")})},this.showRevokeNotice=function(){var e=this,n=new CustomEvent("showRevokeNotice",{detail:{data:cnArgs}});t.dispatchEvent(n),this.noticeContainer.classList.remove("cookie-revoke-hidden"),this.noticeContainer.classList.add("cn-animated"),this.noticeContainer.classList.add("cookie-revoke-visible"),this.noticeContainer.addEventListener("animationend",function t(){e.noticeContainer.removeEventListener("animationend",t),e.noticeContainer.classList.remove("cn-animated")}),this.noticeContainer.addEventListener("webkitAnimationEnd",function t(){e.noticeContainer.removeEventListener("webkitAnimationEnd",t),e.noticeContainer.classList.remove("cn-animated")})},this.hideRevokeNotice=function(){var e=this,n=new CustomEvent("hideRevokeNotice",{detail:{data:cnArgs}});t.dispatchEvent(n),this.noticeContainer.classList.add("cn-animated"),this.noticeContainer.classList.remove("cookie-revoke-visible"),this.noticeContainer.addEventListener("animationend",function t(){e.noticeContainer.removeEventListener("animationend",t),e.noticeContainer.classList.remove("cn-animated"),e.noticeContainer.classList.add("cookie-revoke-hidden")}),this.noticeContainer.addEventListener("webkitAnimationEnd",function t(){e.noticeContainer.removeEventListener("webkitAnimationEnd",t),e.noticeContainer.classList.remove("cn-animated"),e.noticeContainer.classList.add("cookie-revoke-hidden")})},this.setBodyClass=function(e){t.body.classList.remove("cookies-revoke"),t.body.classList.remove("cookies-accepted"),t.body.classList.remove("cookies-refused"),t.body.classList.remove("cookies-set"),t.body.classList.remove("cookies-not-set");for(var n=0;n<e.length;n++)t.body.classList.add(e[n])},this.handleScroll=function(){(e.pageYOffset||(t.documentElement||t.body.parentNode||t.body).scrollTop)>parseInt(cnArgs.onScrollOffset)&&this.setStatus("accept")},this.getClosest=function(e,n){for(Element.prototype.matches||(Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(e){for(var t=(this.document||this.ownerDocument).querySelectorAll(e),n=t.length;--n>=0&&t.item(n)!==this;);return n>-1});e&&e!==t;e=e.parentNode)if(e.matches(n))return e;return null},this.inIframe=function(){try{return e.self!==e.top}catch(t){return!0}},this.init=function(){var n=this;if(!0!==this.inIframe()&&(this.cookiesAccepted=this.getStatus(!0),this.noticeContainer=t.getElementById("cookie-notice"),this.noticeContainer)){var i=t.getElementsByClassName("cn-set-cookie"),o=t.getElementsByClassName("cn-revoke-cookie"),s=t.getElementById("cn-close-notice");this.noticeContainer.classList.add("cn-effect-"+cnArgs.hideEffect),null===this.cookiesAccepted?(cnArgs.onScroll&&e.addEventListener("scroll",function(e){n.handleScroll()}),cnArgs.onClick&&e.addEventListener("click",function(e){null===n.getClosest(e.target,"#cookie-notice")&&n.setStatus("accept")},!0),this.setBodyClass(["cookies-not-set"]),this.showCookieNotice()):(this.setBodyClass(["cookies-set",!0===this.cookiesAccepted?"cookies-accepted":"cookies-refused"]),cnArgs.revokeCookies&&"automatic"===cnArgs.revokeCookiesOpt&&this.showRevokeNotice());for(var c=0;c<i.length;c++)i[c].addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),n.setStatus(this.dataset.cookieSet)});null!==s&&s.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),n.setStatus("reject")});for(var c=0;c<o.length;c++)o[c].addEventListener("click",function(e){e.preventDefault(),n.noticeContainer.classList.contains("cookie-revoke-visible")?(n.hideRevokeNotice(),n.noticeContainer.addEventListener("animationend",function e(){n.noticeContainer.removeEventListener("animationend",e),n.showCookieNotice()}),n.noticeContainer.addEventListener("webkitAnimationEnd",function e(){n.noticeContainer.removeEventListener("webkitAnimationEnd",e),n.showCookieNotice()})):n.noticeContainer.classList.contains("cookie-notice-hidden")&&n.noticeContainer.classList.contains("cookie-revoke-hidden")&&n.showCookieNotice()})}}};e.addEventListener("load",function(){i.init()},!1)}(window,document,void 0);
\ No newline at end of file
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Cookie Notice\n"
"POT-Creation-Date: 2023-08-21 13:19+0200\n"
"PO-Revision-Date: 2015-03-24 11:30+0100\n"
"Last-Translator: Bartosz Arendt <info@dfactory.eu>\n"
"Language-Team: dFactory <info@dfactory.eu>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.3.2\n"
"X-Poedit-KeywordsList: gettext;gettext_noop;__;_e;_n;esc_html__;esc_html_e\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-SearchPath-0: ..\n"
#: ../cookie-notice.php:706
msgid "Facebook Tracking Pixel Illegal in EU?"
msgstr ""
#: ../cookie-notice.php:706
msgid "The Austrian Data Protection Authority recently declared that the use of Facebook's tracking pixel directly violates the GDPR. This decision could affect many websites in the European Union. To use Facebook Pixel, prior consent from visitors for tracking is required. Click \"Run Compliance Check\" to check if your website compliance with the latest privacy regulations."
msgstr ""
#: ../cookie-notice.php:706 ../includes/dashboard.php:512
msgid "Run Compliance Check"
msgstr ""
#: ../cookie-notice.php:706
msgid "Dismiss Notice"
msgstr ""
#: ../cookie-notice.php:741
msgid "Cookie Compliance Warning"
msgstr ""
#: ../cookie-notice.php:741
#, php-format
msgid "Your website has reached the <b>%1$s visits usage limit for the Cookie Compliance Free Plan</b>. Compliance services such as Consent Record Storage, Autoblocking, and Consent Analytics have been deactivated until current usage cycle ends on %2$s."
msgstr ""
#: ../cookie-notice.php:741
#, php-format
msgid "To reactivate compliance services now, <a href=\"%s\" target=\"_blank\">upgrade your domain to a Pro plan.</a>"
msgstr ""
#: ../cookie-notice.php:1055
msgid "Cookie Notice & Compliance - Deactivation survey"
msgstr ""
#: ../cookie-notice.php:1119
msgid "Settings"
msgstr ""
#: ../cookie-notice.php:1134
msgid "Free Upgrade"
msgstr ""
#: ../cookie-notice.php:1160
msgid "We're sorry to see you go. Could you please tell us what happened?"
msgstr ""
#: ../cookie-notice.php:1164
msgid "I couldn't figure out how to make it work."
msgstr ""
#: ../cookie-notice.php:1165
msgid "I found another plugin to use for the same task."
msgstr ""
#: ../cookie-notice.php:1166
msgid "The Cookie Compliance banner is too big."
msgstr ""
#: ../cookie-notice.php:1167
msgid "The Cookie Compliance consent choices (Silver, Gold, Platinum) are confusing."
msgstr ""
#: ../cookie-notice.php:1168
msgid "The Cookie Compliance default settings are too strict."
msgstr ""
#: ../cookie-notice.php:1169
msgid "The web application user interface is not clear to me."
msgstr ""
#: ../cookie-notice.php:1170
msgid "Support isn't timely."
msgstr ""
#: ../cookie-notice.php:1171
msgid "Other"
msgstr ""
#: ../cookie-notice.php:1185
msgid "Cancel"
msgstr ""
#: ../cookie-notice.php:1186
msgid "Deactivate"
msgstr ""
#: ../cookie-notice.php:1187
msgid "Deactivate & Submit"
msgstr ""
#: ../includes/dashboard.php:72
msgid "Cookie Compliance"
msgstr ""
#: ../includes/dashboard.php:181 ../includes/dashboard.php:193
#: ../includes/dashboard.php:205
#, php-format
msgid "Level %s"
msgstr ""
#: ../includes/dashboard.php:290
msgid "Traffic Overview"
msgstr ""
#: ../includes/dashboard.php:291
msgid "Displays the general visits information for your domain."
msgstr ""
#: ../includes/dashboard.php:295
msgid "Consent Activity"
msgstr ""
#: ../includes/dashboard.php:296
msgid "Displays the chart of the domain consent activity in the last 30 days."
msgstr ""
#: ../includes/dashboard.php:316
msgid "View consent activity inside WordPress Dashboard"
msgstr ""
#: ../includes/dashboard.php:317
msgid "Display information about the visits."
msgstr ""
#: ../includes/dashboard.php:318
msgid "Get Consent logs data for the last 30 days."
msgstr ""
#: ../includes/dashboard.php:319
msgid "Enable consent purpose categories, automatic cookie blocking and more."
msgstr ""
#: ../includes/dashboard.php:320
msgid "Upgrade to Cookie Compliance"
msgstr ""
#: ../includes/dashboard.php:422
msgid "Total Visits"
msgstr ""
#: ../includes/dashboard.php:424
msgid "Last 30 days"
msgstr ""
#: ../includes/dashboard.php:427
msgid "Consent Logs"
msgstr ""
#: ../includes/dashboard.php:429
#, php-format
msgid "Updated %s"
msgstr ""
#: ../includes/dashboard.php:446
msgid "Traffic Usage"
msgstr ""
#: ../includes/dashboard.php:449
#, php-format
msgid "Visits usage: %1$s / %2$s"
msgstr ""
#: ../includes/dashboard.php:450
#, php-format
msgid "Cycle started: %s"
msgstr ""
#: ../includes/dashboard.php:451
#, php-format
msgid "Days to go: %s"
msgstr ""
#: ../includes/dashboard.php:494
msgid "Cookie Compliance Status"
msgstr ""
#: ../includes/dashboard.php:509
msgid "Your site does not have Cookie Compliance"
msgstr ""
#: ../includes/dashboard.php:511
msgid "Run Compliance Check to determine your site's compliance with updated data processing and consent rules under GDPR, CCPA and other international data privacy laws."
msgstr ""
#: ../includes/dashboard.php:515 ../includes/settings.php:234
#: ../includes/welcome.php:420
msgid "Cookie Notice"
msgstr ""
#: ../includes/settings.php:71
msgid "Page Type"
msgstr ""
#: ../includes/settings.php:72
msgid "Page"
msgstr ""
#: ../includes/settings.php:73
msgid "Post Type"
msgstr ""
#: ../includes/settings.php:74
msgid "Post Type Archive"
msgstr ""
#: ../includes/settings.php:75
msgid "User Type"
msgstr ""
#: ../includes/settings.php:79
msgid "is equal to"
msgstr ""
#: ../includes/settings.php:80
msgid "is not equal to"
msgstr ""
#: ../includes/settings.php:84
msgid "Hide the banner"
msgstr ""
#: ../includes/settings.php:85
msgid "Show the banner"
msgstr ""
#: ../includes/settings.php:89
msgid "Top"
msgstr ""
#: ../includes/settings.php:90
msgid "Bottom"
msgstr ""
#: ../includes/settings.php:94 ../includes/settings.php:137
msgid "None"
msgstr ""
#: ../includes/settings.php:95
msgid "Light"
msgstr ""
#: ../includes/settings.php:96
msgid "Dark"
msgstr ""
#: ../includes/settings.php:100
msgid "Automatic"
msgstr ""
#: ../includes/settings.php:101
msgid "Manual"
msgstr ""
#: ../includes/settings.php:105
msgid "Page link"
msgstr ""
#: ../includes/settings.php:106
msgid "Custom link"
msgstr ""
#: ../includes/settings.php:112
msgid "Banner"
msgstr ""
#: ../includes/settings.php:113 ../includes/settings.php:464
msgid "Message"
msgstr ""
#: ../includes/settings.php:117
msgid "Text color"
msgstr ""
#: ../includes/settings.php:118
msgid "Button color"
msgstr ""
#: ../includes/settings.php:119
msgid "Bar color"
msgstr ""
#: ../includes/settings.php:125
msgid "An hour"
msgstr ""
#: ../includes/settings.php:126
msgid "1 day"
msgstr ""
#: ../includes/settings.php:127
msgid "1 week"
msgstr ""
#: ../includes/settings.php:128
msgid "1 month"
msgstr ""
#: ../includes/settings.php:129
msgid "3 months"
msgstr ""
#: ../includes/settings.php:130
msgid "6 months"
msgstr ""
#: ../includes/settings.php:131
msgid "1 year"
msgstr ""
#: ../includes/settings.php:132
msgid "infinity"
msgstr ""
#: ../includes/settings.php:138
msgid "Fade"
msgstr ""
#: ../includes/settings.php:139
msgid "Slide"
msgstr ""
#: ../includes/settings.php:143
msgid "Header"
msgstr ""
#: ../includes/settings.php:144
msgid "Footer"
msgstr ""
#: ../includes/settings.php:149
msgid "Silver"
msgstr ""
#: ../includes/settings.php:150
msgid "Gold"
msgstr ""
#: ../includes/settings.php:151
msgid "Platinum"
msgstr ""
#: ../includes/settings.php:154
msgid "Private"
msgstr ""
#: ../includes/settings.php:155
msgid "Balanced"
msgstr ""
#: ../includes/settings.php:156
msgid "Personalized"
msgstr ""
#: ../includes/settings.php:159
msgid "Reject All"
msgstr ""
#: ../includes/settings.php:160
msgid "Accept Some"
msgstr ""
#: ../includes/settings.php:161
msgid "Accept All"
msgstr ""
#: ../includes/settings.php:166
msgid "Save my preferences"
msgstr ""
#: ../includes/settings.php:167 ../includes/settings.php:191
#: ../includes/settings.php:466
msgid "Privacy policy"
msgstr ""
#: ../includes/settings.php:168
msgid "Do Not Sell"
msgstr ""
#: ../includes/settings.php:169
msgid "Preferences"
msgstr ""
#: ../includes/settings.php:170
msgid "We believe your data is your property and support your right to privacy and transparency."
msgstr ""
#: ../includes/settings.php:171
msgid "Select a Data Access Level and Duration to choose how we use and share your data."
msgstr ""
#: ../includes/settings.php:172
msgid "Highest level of privacy. Data accessed for necessary site operations only. Data shared with 3rd parties to ensure the site is secure and works on your device."
msgstr ""
#: ../includes/settings.php:173
msgid "Balanced experience. Data accessed for content personalisation and site optimisation. Data shared with 3rd parties may be used to track and store your preferences for this site."
msgstr ""
#: ../includes/settings.php:174
msgid "Highest level of personalisation. Data accessed to make ads and media more relevant. Data shared with 3rd parties may be use to track you on this site and other sites you visit."
msgstr ""
#: ../includes/settings.php:178
msgid "month"
msgstr ""
#: ../includes/settings.php:179
msgid "months"
msgstr ""
#: ../includes/settings.php:186
msgid "We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it."
msgstr ""
#: ../includes/settings.php:187
msgid "Ok"
msgstr ""
#: ../includes/settings.php:188
msgid "No"
msgstr ""
#: ../includes/settings.php:189
msgid "You can revoke your consent any time using the Revoke consent button."
msgstr ""
#: ../includes/settings.php:190 ../includes/settings.php:468
msgid "Revoke consent"
msgstr ""
#: ../includes/settings.php:234
msgid "Cookies"
msgstr ""
#: ../includes/settings.php:253
msgid "Cookie Notice & Compliance for GDPR/CCPA"
msgstr ""
#: ../includes/settings.php:265
msgid "Your Cookie Compliance plan:"
msgstr ""
#: ../includes/settings.php:266 ../includes/welcome.php:332
msgid "Professional"
msgstr ""
#: ../includes/settings.php:266 ../includes/welcome.php:310
#: ../includes/welcome.php:590 ../includes/welcome.php:688
msgid "Basic"
msgstr ""
#: ../includes/settings.php:269 ../includes/welcome.php:314
#: ../includes/welcome.php:345
msgid "GDPR, CCPA, LGPD, PECR requirements"
msgstr ""
#: ../includes/settings.php:270 ../includes/welcome.php:315
#: ../includes/welcome.php:346
msgid "Consent Analytics Dashboard"
msgstr ""
#: ../includes/settings.php:271 ../includes/welcome.php:347
#, php-format
msgid "%sUnlimited%s visits"
msgstr ""
#: ../includes/settings.php:272 ../includes/welcome.php:348
#, php-format
msgid "%sLifetime%s consent storage"
msgstr ""
#: ../includes/settings.php:273 ../includes/welcome.php:318
#: ../includes/welcome.php:349
#, php-format
msgid "%sGoogle & Facebook%s consent modes"
msgstr ""
#: ../includes/settings.php:274 ../includes/welcome.php:319
#: ../includes/welcome.php:350
#, php-format
msgid "%sGeolocation%s support"
msgstr ""
#: ../includes/settings.php:275 ../includes/welcome.php:351
#, php-format
msgid "%sUnlimited%s languages"
msgstr ""
#: ../includes/settings.php:276 ../includes/welcome.php:352
#, php-format
msgid "%sPriority%s Support"
msgstr ""
#: ../includes/settings.php:281
msgid "Upgrade to Pro"
msgstr ""
#: ../includes/settings.php:288
msgid "Protect your business"
msgstr ""
#: ../includes/settings.php:289
msgid "with Cookie Compliance&trade;"
msgstr ""
#: ../includes/settings.php:291
msgid "Deliver better consent experiences and comply with GDPR, CCPA and other data privacy laws more effectively."
msgstr ""
#: ../includes/settings.php:293
msgid "Cookie Compliance dashboard"
msgstr ""
#: ../includes/settings.php:294
msgid "Learn more"
msgstr ""
#: ../includes/settings.php:304
msgid "F.A.Q."
msgstr ""
#: ../includes/settings.php:308
msgid "Does the Cookie Notice make my site fully compliant with GDPR?"
msgstr ""
#: ../includes/settings.php:309
msgid "It is not possible to provide the required technical compliance features using only a WordPress plugin. Features like consent record storage, purpose categories and script blocking that bring your site into full compliance with GDPR are only available through the Cookie Compliance integration."
msgstr ""
#: ../includes/settings.php:313
msgid "Does the Cookie Compliance integration make my site fully compliant with GDPR?"
msgstr ""
#: ../includes/settings.php:314
msgid "Yes! The plugin + web application version includes technical compliance features to meet requirements for over 100 countries and legal jurisdictions."
msgstr ""
#: ../includes/settings.php:318
msgid "Is Cookie Compliance free?"
msgstr ""
#: ../includes/settings.php:319
msgid "Yes, but with limits. Cookie Compliance includes both free and paid plans to choose from depending on your needs and your website monthly traffic."
msgstr ""
#: ../includes/settings.php:323
msgid "Where can I find pricing options?"
msgstr ""
#: ../includes/settings.php:324
msgid "You can learn more about the features and pricing by visiting the Cookie Compliance website here:"
msgstr ""
#: ../includes/settings.php:380
msgid "Reset to defaults"
msgstr ""
#: ../includes/settings.php:407 ../includes/settings.php:412
msgid "Network Settings"
msgstr ""
#: ../includes/settings.php:408
msgid "Global Settings Override"
msgstr ""
#: ../includes/settings.php:409
msgid "Global Cookie"
msgstr ""
#: ../includes/settings.php:441 ../includes/settings.php:457
msgid "Compliance Settings"
msgstr ""
#: ../includes/settings.php:442 ../includes/settings.php:458
msgid "Compliance status"
msgstr ""
#: ../includes/settings.php:443 ../includes/settings.php:459
msgid "App ID"
msgstr ""
#: ../includes/settings.php:444 ../includes/settings.php:460
msgid "App Key"
msgstr ""
#: ../includes/settings.php:447
msgid "Miscellaneous Settings"
msgstr ""
#: ../includes/settings.php:448 ../includes/settings.php:552
#: ../includes/settings.php:566 ../includes/settings.php:585
#: ../includes/welcome.php:421
msgid "Autoblocking"
msgstr ""
#: ../includes/settings.php:449
msgid "Debug mode"
msgstr ""
#: ../includes/settings.php:450
msgid "Caching compatibility"
msgstr ""
#: ../includes/settings.php:451
msgid "Cache"
msgstr ""
#: ../includes/settings.php:452 ../includes/settings.php:475
msgid "Conditional display"
msgstr ""
#: ../includes/settings.php:453 ../includes/settings.php:477
msgid "Deactivation"
msgstr ""
#: ../includes/settings.php:463
msgid "Notice Settings"
msgstr ""
#: ../includes/settings.php:465
msgid "Button text"
msgstr ""
#: ../includes/settings.php:467
msgid "Refuse consent"
msgstr ""
#: ../includes/settings.php:469
msgid "Script blocking"
msgstr ""
#: ../includes/settings.php:470
msgid "Reloading"
msgstr ""
#: ../includes/settings.php:471
msgid "On scroll"
msgstr ""
#: ../includes/settings.php:472
msgid "On click"
msgstr ""
#: ../includes/settings.php:473
msgid "Accepted expiry"
msgstr ""
#: ../includes/settings.php:474
msgid "Rejected expiry"
msgstr ""
#: ../includes/settings.php:476
msgid "Script placement"
msgstr ""
#: ../includes/settings.php:480
msgid "Notice Design"
msgstr ""
#: ../includes/settings.php:481
msgid "Position"
msgstr ""
#: ../includes/settings.php:482
msgid "Animation"
msgstr ""
#: ../includes/settings.php:483
msgid "Colors"
msgstr ""
#: ../includes/settings.php:484
msgid "Button class"
msgstr ""
#: ../includes/settings.php:496
msgid "Enable global network settings override."
msgstr ""
#: ../includes/settings.php:497
msgid "Every site in the network will use the same settings. Site administrators will not be able to change them."
msgstr ""
#: ../includes/settings.php:511
msgid "This option works only for domain-based networks."
msgstr ""
#: ../includes/settings.php:517
msgid "Enable global network cookie consent."
msgstr ""
#: ../includes/settings.php:518
msgid "Cookie consent in one of the network sites results in a consent in all of the sites on the network."
msgstr ""
#: ../includes/settings.php:529
msgid "Global network settings override is active. Every site will use the same network settings. Please contact super administrator if you want to have more control over the settings."
msgstr ""
#: ../includes/settings.php:551 ../includes/settings.php:565
#: ../includes/settings.php:584
msgid "Notice"
msgstr ""
#: ../includes/settings.php:551 ../includes/settings.php:552
#: ../includes/settings.php:553 ../includes/settings.php:554
#: ../includes/settings.php:565 ../includes/settings.php:584
msgid "Active"
msgstr ""
#: ../includes/settings.php:553 ../includes/settings.php:567
#: ../includes/settings.php:586 ../includes/welcome.php:422
msgid "Cookie Categories"
msgstr ""
#: ../includes/settings.php:554 ../includes/settings.php:568
#: ../includes/settings.php:587 ../includes/welcome.php:423
msgid "Proof-of-Consent"
msgstr ""
#: ../includes/settings.php:557
msgid "Log in & Configure"
msgstr ""
#: ../includes/settings.php:558
msgid "Log into the Cookie Compliance&trade; web application to configure the appearance and functionality of the banner."
msgstr ""
#: ../includes/settings.php:566 ../includes/settings.php:567
#: ../includes/settings.php:568
msgid "Pending"
msgstr ""
#: ../includes/settings.php:571
msgid "Log in & configure"
msgstr ""
#: ../includes/settings.php:572
msgid "Log into the Cookie Compliance&trade; web application and complete the setup process."
msgstr ""
#: ../includes/settings.php:585 ../includes/settings.php:586
#: ../includes/settings.php:587
msgid "Inactive"
msgstr ""
#: ../includes/settings.php:590
msgid "Add Compliance features"
msgstr ""
#: ../includes/settings.php:591
#, php-format
msgid "Sign up to %s and add GDPR, CCPA and other international data privacy laws compliance features."
msgstr ""
#: ../includes/settings.php:606
msgid "Enter your Cookie Compliance&trade; application ID."
msgstr ""
#: ../includes/settings.php:619
msgid "Enter your Cookie Compliance&trade; application secret key."
msgstr ""
#: ../includes/settings.php:636
msgid "Enable to automatically block 3rd party scripts before user consent is set."
msgstr ""
#: ../includes/settings.php:637
msgid "This option has been temporarily disabled because your website has reached the usage limit for the Cookie Compliance Basic plan. It will become available again when the current visits cycle resets or you upgrade your website to a Professional plan."
msgstr ""
#: ../includes/settings.php:650
msgid "Purge Cache"
msgstr ""
#: ../includes/settings.php:652
msgid "Click the Purge Cache button to refresh the app configuration."
msgstr ""
#: ../includes/settings.php:667
msgid "Enable conditional display of the banner."
msgstr ""
#: ../includes/settings.php:680
msgid "Determine what should happen when the following conditions are met."
msgstr ""
#: ../includes/settings.php:713
msgid "Enable to run the consent banner in debug mode."
msgstr ""
#: ../includes/settings.php:734
msgid "Currently detected active caching plugins"
msgstr ""
#: ../includes/settings.php:742
msgid "No compatible cache plugins found."
msgstr ""
#: ../includes/settings.php:746
msgid "Enable to apply changes improving compatibility with caching plugins."
msgstr ""
#: ../includes/settings.php:759
msgid "Enter the cookie notice message."
msgstr ""
#: ../includes/settings.php:772
msgid "The text of the option to accept the notice and make it disappear."
msgstr ""
#: ../includes/settings.php:787
msgid "Enable to give to the user the possibility to refuse third party non functional cookies."
msgstr ""
#: ../includes/settings.php:791
msgid "The text of the button to refuse the consent."
msgstr ""
#: ../includes/settings.php:813
msgid "Head"
msgstr ""
#: ../includes/settings.php:814
msgid "Body"
msgstr ""
#: ../includes/settings.php:817
msgid "The code to be used in your site header, before the closing head tag."
msgstr ""
#: ../includes/settings.php:821
msgid "The code to be used in your site footer, before the closing body tag."
msgstr ""
#: ../includes/settings.php:825
msgid "Enter non functional cookies Javascript code here (for e.g. Google Analitycs) to be used after the notice is accepted."
msgstr ""
#: ../includes/settings.php:825
#, php-format
msgid "To get the user consent status use the %scn_cookies_accepted()%s function."
msgstr ""
#: ../includes/settings.php:840
#, php-format
msgid "Enable to give to the user the possibility to revoke their consent %s(requires \"Refuse consent\" option enabled)%s."
msgstr ""
#: ../includes/settings.php:843
msgid "Enter the revoke message."
msgstr ""
#: ../includes/settings.php:845
msgid "The text of the button to revoke the consent."
msgstr ""
#: ../includes/settings.php:853
#, php-format
msgid "Select the method for displaying the revoke button - automatic (in the banner) or manual using %s[cookies_revoke]%s shortcode."
msgstr ""
#: ../includes/settings.php:866
msgid "Enable to reload the page after the notice is accepted."
msgstr ""
#: ../includes/settings.php:897
msgid "Enable privacy policy link."
msgstr ""
#: ../includes/settings.php:900
msgid "The text of the privacy policy button."
msgstr ""
#: ../includes/settings.php:910
msgid "Select where to redirect user for more information."
msgstr ""
#: ../includes/settings.php:913
msgid "-- select page --"
msgstr ""
#: ../includes/settings.php:924
msgid "Select from one of your site's pages."
msgstr ""
#: ../includes/settings.php:930
msgid "Synchronize with WordPress Privacy Policy page."
msgstr ""
#: ../includes/settings.php:937
msgid "Enter the full URL starting with http(s)://"
msgstr ""
#: ../includes/settings.php:947
msgid "Select the privacy policy link target."
msgstr ""
#: ../includes/settings.php:957
msgid "Select the privacy policy link position."
msgstr ""
#: ../includes/settings.php:980
msgid "The amount of time that the cookie should be stored for when user accepts the notice."
msgstr ""
#: ../includes/settings.php:1001
msgid "The amount of time that the cookie should be stored for when the user doesn't accept the notice."
msgstr ""
#: ../includes/settings.php:1020
msgid "Select where all the plugin scripts should be placed."
msgstr ""
#: ../includes/settings.php:1039
msgid "Select location for the notice."
msgstr ""
#: ../includes/settings.php:1058
msgid "Select the animation style."
msgstr ""
#: ../includes/settings.php:1073
msgid "Enable to accept the notice when user scrolls."
msgstr ""
#: ../includes/settings.php:1076
msgid "Number of pixels user has to scroll to accept the notice and make it disappear."
msgstr ""
#: ../includes/settings.php:1089
msgid "Enable to accept the notice on any click on the page."
msgstr ""
#: ../includes/settings.php:1101
msgid "Enable if you want all plugin data to be deleted on deactivation."
msgstr ""
#: ../includes/settings.php:1114
msgid "Enter additional button CSS classes separated by spaces."
msgstr ""
#: ../includes/settings.php:1139
msgid "Bar opacity"
msgstr ""
#: ../includes/settings.php:1516
msgid "Settings saved."
msgstr ""
#: ../includes/settings.php:1520
msgid "Settings restored to defaults."
msgstr ""
#: ../includes/settings.php:1608
msgid "Are you sure you want to reset these settings to defaults?"
msgstr ""
#: ../includes/settings.php:1725
msgid "or"
msgstr ""
#: ../includes/settings.php:1792
msgid "+ Add rule"
msgstr ""
#: ../includes/settings.php:1793
msgid "Create a set of rules to define the exact conditions for displaying or hiding the banner."
msgstr ""
#: ../includes/settings.php:1896
msgid "-- no public archives --"
msgstr ""
#: ../includes/settings.php:1992
#, php-format
msgid "Untitled Page %d"
msgstr ""
#: ../includes/settings.php:2006
msgid "Front Page"
msgstr ""
#: ../includes/settings.php:2007
msgid "Home Page"
msgstr ""
#: ../includes/settings.php:2018
msgid "Logged in"
msgstr ""
#: ../includes/settings.php:2019
msgid "Guest"
msgstr ""
#: ../includes/welcome-api.php:35 ../includes/welcome-api.php:39
#: ../includes/welcome-api.php:46 ../includes/welcome-api.php:59
#: ../includes/welcome.php:207 ../includes/welcome.php:235
#: ../includes/welcome.php:238
msgid "You do not have permission to access this page."
msgstr ""
#: ../includes/welcome-api.php:115 ../includes/welcome-api.php:349
#: ../includes/welcome-api.php:391 ../includes/welcome-api.php:550
#: ../includes/welcome-api.php:624 ../includes/welcome-api.php:1163
#: ../includes/welcome.php:128
msgid "Unexpected error occurred. Please try again later."
msgstr ""
#: ../includes/welcome-api.php:152
msgid "Empty plan or payment method data."
msgstr ""
#: ../includes/welcome-api.php:187
msgid "Unable to create customer data."
msgstr ""
#: ../includes/welcome-api.php:226
msgid "Unable to create payment mehotd."
msgstr ""
#: ../includes/welcome-api.php:232
msgid "No payment method token."
msgstr ""
#: ../includes/welcome-api.php:276
msgid "Please accept the Terms of Service to proceed."
msgstr ""
#: ../includes/welcome-api.php:285 ../includes/welcome-api.php:518
msgid "Email is not allowed to be empty."
msgstr ""
#: ../includes/welcome-api.php:295 ../includes/welcome-api.php:527
msgid "Password is not allowed to be empty."
msgstr ""
#: ../includes/welcome-api.php:301
msgid "The password contains illegal characters or does not meet the conditions."
msgstr ""
#: ../includes/welcome-api.php:307
msgid "Passwords do not match."
msgstr ""
#: ../includes/welcome.php:129
msgid "Passed"
msgstr ""
#: ../includes/welcome.php:130
msgid "Failed"
msgstr ""
#: ../includes/welcome.php:131 ../includes/welcome.php:333
#: ../includes/welcome.php:591 ../includes/welcome.php:689
msgid "monthly"
msgstr ""
#: ../includes/welcome.php:132
msgid "yearly"
msgstr ""
#: ../includes/welcome.php:136
#, php-format
msgid "%sCompliance Failed!%sYour website does not achieve minimum viable compliance. %sSign up to Cookie Compliance%s to bring your site into compliance with the latest data privacy rules and regulations."
msgstr ""
#: ../includes/welcome.php:137
#, php-format
msgid "%sCompliance Passed!%sCongratulations. Your website meets minimum viable compliance."
msgstr ""
#: ../includes/welcome.php:138 ../includes/welcome.php:691
msgid "available"
msgstr ""
#: ../includes/welcome.php:139
msgid "Please fill all the required fields."
msgstr ""
#: ../includes/welcome.php:253 ../includes/welcome.php:290
msgid "The next generation of Cookie Notice"
msgstr ""
#: ../includes/welcome.php:255
msgid "Cookie Compliance is a free web application that enables websites to take a proactive approach to data protection and consent laws."
msgstr ""
#: ../includes/welcome.php:261
#, php-format
msgid "It is the first solution to offer %sintentional consent%s, a new consent framework that incorporates the latest guidelines from over 100+ countries, and emerging standards from leading international organizations like the IEEE."
msgstr ""
#: ../includes/welcome.php:262
#, php-format
msgid "Cookie Notice includes %sseamless integration%s with Cookie Compliance to help your site comply with the latest updates to existing consent laws and provide a beautiful, multi-level experience to engage visitors in data privacy decisions."
msgstr ""
#: ../includes/welcome.php:266
msgid "Sign up to Cookie Compliance"
msgstr ""
#: ../includes/welcome.php:267
msgid "Skip for now"
msgstr ""
#: ../includes/welcome.php:292
msgid "Take a proactive approach to data protection and consent laws by signing up for Cookie Compliance account. Then select a limited Basic Plan for free or get one of the Professional Plans for unlimited visits, consent storage, languages and customizations."
msgstr ""
#: ../includes/welcome.php:296
msgid "Compliance Plans"
msgstr ""
#: ../includes/welcome.php:299
msgid "Monthly"
msgstr ""
#: ../includes/welcome.php:302
msgid "Yearly"
msgstr ""
#: ../includes/welcome.php:302
msgid "Save 12%"
msgstr ""
#: ../includes/welcome.php:311
msgid "Free"
msgstr ""
#: ../includes/welcome.php:316
#, php-format
msgid "%s1,000%s visits / month"
msgstr ""
#: ../includes/welcome.php:317
#, php-format
msgid "%s30 days%s consent storage"
msgstr ""
#: ../includes/welcome.php:320
#, php-format
msgid "%s1 additional%s language"
msgstr ""
#: ../includes/welcome.php:321
#, php-format
msgid "%sBasic%s Support"
msgstr ""
#: ../includes/welcome.php:324
msgid "Start Basic"
msgstr ""
#: ../includes/welcome.php:334
msgid "Recommended"
msgstr ""
#: ../includes/welcome.php:336
msgid "Pricing options"
msgstr ""
#: ../includes/welcome.php:337 ../includes/welcome.php:338
#: ../includes/welcome.php:339 ../includes/welcome.php:340
#, php-format
msgid "%s domain license"
msgstr ""
#: ../includes/welcome.php:355
msgid "Start Professional"
msgstr ""
#: ../includes/welcome.php:361
msgid "I don’t want to create an account now"
msgstr ""
#: ../includes/welcome.php:379
msgid "Congratulations"
msgstr ""
#: ../includes/welcome.php:380
msgid "You have successfully signed up to a Professional plan."
msgstr ""
#: ../includes/welcome.php:380
msgid "You have successfully signed up to a limited, Basic plan."
msgstr ""
#: ../includes/welcome.php:382
msgid "Log in to your Cookie Compliance account and continue configuring your Privacy Experience."
msgstr ""
#: ../includes/welcome.php:385
msgid "Go to Application"
msgstr ""
#: ../includes/welcome.php:410
msgid "Compliance check"
msgstr ""
#: ../includes/welcome.php:411
msgid "This is a Compliance Check to determine your site’s compliance with updated data processing and consent rules under GDPR, CCPA and other international data privacy laws."
msgstr ""
#: ../includes/welcome.php:413
msgid "Site URL"
msgstr ""
#: ../includes/welcome.php:414
msgid "Site Name"
msgstr ""
#: ../includes/welcome.php:417
msgid "Checking..."
msgstr ""
#: ../includes/welcome.php:420
msgid "Notifies visitors that site uses cookies."
msgstr ""
#: ../includes/welcome.php:421
msgid "Non-essential cookies blocked until consent is registered."
msgstr ""
#: ../includes/welcome.php:422
msgid "Separate consent requested per purpose of use."
msgstr ""
#: ../includes/welcome.php:423
msgid "Proof-of-consent stored in secure audit format."
msgstr ""
#: ../includes/welcome.php:439
msgid "Live Setup"
msgstr ""
#: ../includes/welcome.php:440
msgid "Configure your Cookie Notice & Compliance design and compliance features through the options below. Click Apply Setup to save the configuration and go to selecting your preferred cookie solution."
msgstr ""
#: ../includes/welcome.php:444
msgid "Banner Compliance"
msgstr ""
#: ../includes/welcome.php:465
msgid "Select the laws that apply to your business"
msgstr ""
#: ../includes/welcome.php:467
msgid "GDPR"
msgstr ""
#: ../includes/welcome.php:468
msgid "CCPA"
msgstr ""
#: ../includes/welcome.php:472
msgid "Select a naming style for the consent choices"
msgstr ""
#: ../includes/welcome.php:474
msgid "Silver, Gold, Platinum (Default)​"
msgstr ""
#: ../includes/welcome.php:475
msgid "Private, Balanced, Personalized"
msgstr ""
#: ../includes/welcome.php:476
msgid "Reject All, Accept Some, Accept All​"
msgstr ""
#: ../includes/welcome.php:480
msgid "Select additional information to include in the banner: *"
msgstr ""
#: ../includes/welcome.php:482
#, php-format
msgid "Display %sPrivacy Paper%s to provide helpful data privacy and consent information to visitors."
msgstr ""
#: ../includes/welcome.php:483
#, php-format
msgid "Display %sPrivacy Contact%s to provide Data Controller contact information and links to external data privacy resources."
msgstr ""
#: ../includes/welcome.php:486 ../includes/welcome.php:514
msgid "available for Cookie Compliance&trade; Pro plans only"
msgstr ""
#: ../includes/welcome.php:490
msgid "Banner Design"
msgstr ""
#: ../includes/welcome.php:494
msgid "Select your preferred display position"
msgstr ""
#: ../includes/welcome.php:504
msgid "Adjust the banner color scheme"
msgstr ""
#: ../includes/welcome.php:506
msgid "Color of the buttons and interactive elements."
msgstr ""
#: ../includes/welcome.php:507
msgid "Color of the banner background."
msgstr ""
#: ../includes/welcome.php:508
msgid "Color of the body text."
msgstr ""
#: ../includes/welcome.php:509
msgid "Color of the borders and inactive elements."
msgstr ""
#: ../includes/welcome.php:510
msgid "Color of the heading text."
msgstr ""
#: ../includes/welcome.php:511
msgid "Color of the button text."
msgstr ""
#: ../includes/welcome.php:519
msgid "Apply Setup"
msgstr ""
#: ../includes/welcome.php:537
msgid "Compliance account"
msgstr ""
#: ../includes/welcome.php:539
msgid "Create a Cookie Compliance&trade; account and select your preferred plan."
msgstr ""
#: ../includes/welcome.php:543
msgid "Create Account"
msgstr ""
#: ../includes/welcome.php:559
#, php-format
msgid "I have read and agree to the %sTerms of Service%s"
msgstr ""
#: ../includes/welcome.php:563
msgid "Sign Up"
msgstr ""
#: ../includes/welcome.php:577
msgid "Already have an account?"
msgstr ""
#: ../includes/welcome.php:577 ../includes/welcome.php:663
msgid "Sign in"
msgstr ""
#: ../includes/welcome.php:584 ../includes/welcome.php:682
msgid "Select Plan"
msgstr ""
#: ../includes/welcome.php:591 ../includes/welcome.php:689
#, php-format
msgid "%sProfessional%s"
msgstr ""
#: ../includes/welcome.php:595 ../includes/welcome.php:696
#: ../includes/welcome.php:735
msgid "Confirm"
msgstr ""
#: ../includes/welcome.php:600 ../includes/welcome.php:701
msgid "Payment Method"
msgstr ""
#: ../includes/welcome.php:602 ../includes/welcome.php:703
msgid "Credit Card"
msgstr ""
#: ../includes/welcome.php:603 ../includes/welcome.php:704
msgid "PayPal"
msgstr ""
#: ../includes/welcome.php:609 ../includes/welcome.php:710
msgid "Card Number"
msgstr ""
#: ../includes/welcome.php:613 ../includes/welcome.php:714
msgid "Expiration Date"
msgstr ""
#: ../includes/welcome.php:617 ../includes/welcome.php:718
msgid "CVC/CVV"
msgstr ""
#: ../includes/welcome.php:621 ../includes/welcome.php:722
msgid "Submit"
msgstr ""
#: ../includes/welcome.php:646
msgid "Compliance Sign in"
msgstr ""
#: ../includes/welcome.php:648
msgid "Sign in to your existing Cookie Compliance&trade; account and select your preferred plan."
msgstr ""
#: ../includes/welcome.php:652
msgid "Account Login"
msgstr ""
#: ../includes/welcome.php:677
msgid "Don't have an account yet?"
msgstr ""
#: ../includes/welcome.php:677
msgid "Sign up"
msgstr ""
#: ../includes/welcome.php:691
msgid "Use License"
msgstr ""
#: ../includes/welcome.php:731
msgid "Select subscription"
msgstr ""
#: ../includes/welcome.php:755
msgid "Success!"
msgstr ""
#: ../includes/welcome.php:756
msgid "You have successfully integrated your website to Cookie Compliance&trade;"
msgstr ""
#: ../includes/welcome.php:756
#, php-format
msgid "Go to Cookie Compliance application now. Or access it anytime from your %sCookie Notice settings page%s."
msgstr ""
=== Cookie Notice & Compliance for GDPR / CCPA ===
Contributors: humanityco
Tags: gdpr, ccpa, cookies, consent, compliance, privacy
Requires at least: 4.9.6
Requires PHP: 5.4
Tested up to: 6.3
Stable tag: 2.4.10
License: MIT License
License URI: http://opensource.org/licenses/MIT
Cookie Notice allows you to you elegantly inform users that your site uses cookies and helps you comply with GDPR, CCPA and other data privacy laws.
== Description ==
<strong>Cookie Notice</strong> provides a simple, customizable website banner that can be used to help your website comply with certain cookie consent requirements under the EU GDPR cookie law and CCPA regulations and includes <strong>seamless integration</strong> with Cookie Compliance to help your site comply with the latest updates to existing consent laws.
<strong>Cookie Compliance</strong> is a fully featured Consent Management Platform (CMP) that provides automated compliance features and enhanced design controls in a state-of-the-art web application. Cookie Compliance enables websites to <strong>take a proactive approach to data protection and consent laws</strong>. It is the first solution to offer Intentional Consent, a new consent framework that incorporates the latest guidelines from over 100+ countries, and emerging standards from leading international organizations like the IEEE and European Center for Digital Rights (noyb.eu). Cookie Compliance provides a beautiful, multi-level experience and includes new choices and controls for site visitors to better understand and engage in data privacy decisions.
> Our Cookie Compliance web application introduces a more ethical, proactive way to capture and manage consent. This early version of the emerging Intentional Consent framework is a result of Hu-manity.co’s ongoing work with top Fortune 500 companies, governments, and standards organizations, who believe that the imbalanced relationship between consumers and corporations is unsustainable when it comes to data privacy and consent online. We are making it available for all website owners and operators who share this belief and support our mission to eliminate the dark patterns in online consent.<br>
> Matt Sinderbrand - Chief Platform Officer, Hu-manity.co
## Cookie Notice (plugin only)
Cookie Notice provides a simple, customizable website banner to help your website comply with certain cookie consent requirements.
= Banner features: =
* Customizable notice message
* Consent on click, scroll or close
* Multiple cookie expiry options
* Link to Privacy Policy page
* WordPress Privacy Policy page synchronization
* WPML and Polylang compatible
* SEO friendly
## Cookie Compliance (plugin + web application)
Cookie Compliance gives you access to the most up-to-date formatting guidelines and technical compliance requirements for over 100 countries and legal jurisdictions.
= Banner features: =
* <strong>Intentional Consent</strong> provides 3 equal buttons to give site visitors the ability to accept none, some, or all cookies through packaged choices called Data Access Levels. Data Access Levels improve consent conversion and eliminate the dark pattern of deceptive, non-equal choices in the first layer. <em>Complies with equal choice principle prescribed under GDPR and other data protection laws.</em>
* <strong>Consent duration selector</strong> gives visitor control over how long their consent remains valid for your site. <em>Enables your site to align with recent guidelines from EU Data Protection Authorities, which state that cookie consent should be valid for no longer than a period of 6 months.</em>
* <strong>Cookie purpose categories</strong> make it easy for website visitors to customize their consent by category. <em>Complies with affirmative, opt-in consent requirements prescribed under GDPR and other data protection laws.</em>
* <strong>Consent metrics</strong> displays the visitor's consent record and a list of blocked / allowed 3rd parties directly in the expanded level of the banner. <em>Complies with latest guidance from EU Data Protection Authorities like CNIL (France) and ICO (UK). </em>
* <strong>Customizable Privacy Paper</strong> provides helpful information to improve visitor comprehension and understanding of the data sharing risks and benefits. Allows you to summarize core components of your sites privacy notice and <em>aligns with the informed principle prescribed by GDPR rules for valid consent capture. </em>
* <strong>Configurable Privacy Contact</strong> allows you to provide contact information for a business’ data privacy admin, as well as helpful links to data subject request forms and other data privacy resources. <em>Aligns with the informed principle prescribed by GDPR rules for valid consent capture.</em>
= Web Application features: =
* <strong>Consent analytics dashboard</strong> shows event data for number of visits and provides a “trust score” to help you track how site visitors are setting their consent. Make adjustments to your banner to improve your cookie acceptance rate and monitor progress via the consent activity graph.
* <strong>Default configurations</strong> for GDPR, CCPA and more help to remove dark patterns and allow for quick and easy deployment of the consent banner without any guesswork. Customize the design of any default configuration to match the look and feel of your site.
* <strong>Automatic script blocking</strong> blocks all non-essential cookie scripts and iFrames by default and <em>complies with valid consent rules under GDPR and other data protection laws</em>; in order to be compliant, your site must record visitor consent before setting or sending cookies.
* <strong>Consent record storage</strong> automatically stores a record of each consent and makes these records available for export. <em>Complies with proof-of-consent requirements prescribed under GDPR and other data protection laws.</em>
* <strong>Multilingual support</strong> automatically translates all banner text strings and allows you to provide custom translations for every text field to ensure visitors get a consistent consent experience.
* <strong>Multidomain management</strong> allows you to manage additional Free or Professional domains under a single account and enables you to customize banner configuration and design for each domain independently.
= Cookie Compliance proactive approach: =
For all businesses, the resources required to stay ahead of the latest regulations increases with the passage of each new law. With enforcement of compliance violations increasing daily, we believe it is critical for us as a trusted consent vendor to do everything in our power to help you stay ahead of these laws and remove the risk to your business
<strong>Cookie Compliance covers all current and upcoming regulations:</strong>
* GDPR (EU)
* ePrivacy Directive (EU)
* ePrivacy Regulation (EU)
* PECR (UK)
* LGPD (Brazil)
* PIPEDA (Canada)
* PDPB (India)
* CCPA (California, US)
* VCDPA (Virginia, US)
* Colorado Privacy Act (US)
* CPRA (California, US)
<strong>Cookie Compliance incorporates all recent formatting guidance:</strong>
* European Data Protection Supervisor (EDPS)
* ICO (United Kingdom)
* CNIL (France)
* GPDP (Italy)
* BfDl (Germany)
* AEPD (Spain)
* European Center for Digital Rights (noyb.eu)
<strong>Cookie Compliance targets dark patterns</strong>
Dark Patterns are user interface (UI) techniques that push site visitors to make decisions (such as agreeing to the installation of cookies on their devices) that they might not otherwise make. The most common Dark Pattern is the lack of an equal “reject all” button on the first layer of the consent notice. Dark Patterns are explicitly banned under GDPR and other data protection laws.
As a part of our proactive approach, Cookie Compliance is configured by default to prevent Dark Patterns through our unique Intentional Consent design.
== Installation ==
1. Install Cookie Notice either via the WordPress.org plugin directory, or by uploading the files to your server
2. Activate the plugin through the 'Plugins' menu in WordPress
3. Go to the Cookie Notice settings and set your options.
4. Click "Add Compliance features" button to start Cookie Compliance integration.
5. Create Cookie Compliance account and select plan.
6. Log in to Cookie Compliance web application anytime to customize the settings.
== Frequently Asked Questions ==
= Is Cookie Notice free? =
Yes! Cookie Notice is a free software.
= Is Cookie Compliance free? =
Yes, but with limits. Cookie Compliance includes both free and paid plans to choose from depending on your needs and your website traffic.
= Does the Cookie Notice make my site fully compliant with GDPR or US Privacy Laws? =
No. The plugin-only version DOES NOT include technical compliance features such as automatic script blocking, consent purpose categories, or consent record storage. These features are only available through the Cookie Compliance integration.
= Does the Cookie Compiance integration make my site fully compliant with GDPR and US Privacy Laws? =
Yes! The plugin + web appliaction version includes technical compliance features to meet requirements for over 100 countries and legal jurisdictions.
== Screenshots ==
1. Cookie Notice settings, Compliance itegration inactive
2. Cookie Notice settings, Compliance itegration active
3. Cookie Compliance dashboard overview
4. Cookie Compliance settings
== Changelog ==
= 2.4.10 =
* New: Option to enable/disable caching compatibility
* New: WP Fastest Cache plugin compatibility
* Fix: Potential security issue with purging cache
* Fix: Improved refreshing Compliance analytics data
* Tweak: Chart.js updated to 4.3.2
= 2.4.9 =
* New: WP Rocket plugin compatibility
* New: LiteSpeed Cache plugin compatibility
* New: Google Consent Mode support (Cookie Compliance only)
* New: Facebook Pixel Consent Mode support (Cookie Compliance only)
= 2.4.8 =
* New: Added Pages to Conditional display
* Fix: Homepage display issue
* Fix: Background color issue
* Tweak: Improved WP Rocket support
* Tweak: Improved SG Optimizer support
= 2.4.7 =
* New: Conditional display of the banner
* Tweak: Improved sanitization and validation of data
* Tweak: PHP 8.1 and 8.2 compatibility
* Tweak: Added async attribute when autoblocking is disabled
= 2.4.6 =
* Fix: Cookie Compliance inactive status issue
= 2.4.5 =
* Tweak: Remove the notice from the Elementor page builder
* Tweak: Remove the notice from widgets screen
* Fix: Improved Contact Form 7 reCaptcha compatibility
= 2.4.4 =
* Fix: Undefined index: status and subscription
= 2.4.3 =
* Fix: Deprecated preg_replace() notice in PHP 8.1
= 2.4.2 =
* New: Compatibility with Autoptimize plugin
* Fix: Improved Contact Form 7 reCaptcha support
* Fix: Fixed non-static method cookies_set()
= 2.4.1 =
* New: Contact Form 7 reCaptcha support
* Tweak: Switched health status from critical to recommended when Cookie Compliance is not integrated
* Tweak: Add SimeSite=Lax for created cookies
= 2.4.0 =
* New: Advanced Multisite support
* Fix: Polylang translation not working for shortcode
* Fix: Parse error: syntax error, unexpected ‘[‘
= 2.3.1 =
* New: Option to run consent banner in debug mode
* Fix: Invalid validation of dismissable notices
= 2.3.0 =
* New: Compliance Multi-license pricing options
* Tweak: WordPress 6.0 compatibility
= 2.2.3 =
* Fix: Undefined notice in WP dashboard
* Fix: Close icon event not firing
* Tweak: Remove aria-label from the close icon
* Tweak: CSS tweaks in the admin
= 2.2.2 =
* Fix: Uncrawlable close notice link
* Tweak: WordPress 5.9 compatibility
* Tweak: Prevent displaying the notice in an iframe
* Tweak: Send site language to a web app on signup
= 2.2.1 =
* Fix: Missing variable definition in frontend
= 2.2.0 =
* New: Option to hide banner for logged in users (Compliance only)
= 2.1.5 =
* Tweak: Additional sanitization applied
= 2.1.4 =
* Fix: Wordpress 5.8 widgets compatibility
= 2.1.3 =
* Fix: HTML attributes removed from text strings
* Tweak: Improved sanitization of options
= 2.1.2 =
* Tweak: Improved escaping of button labels
= 2.1.1 =
* Fix: Security bug related to compliance caching
= 2.1.0 =
* New: Introducing Cookie Compliance Free plan
= 2.0.4 =
* Fix: Undefined constant HOURS_IN_SECONDS
* Fix: Button style none adding CSS classes "cn-set-cookie cn-button"
* Tweak: Switched the behavior of close icon from accept to reject
* Tweak: Minified frontend and admin js files
= 2.0.3 =
* Fix: Cookies accepted function issue when Compliance activated
= 2.0.2 =
* Tweak: UI/UX improvements
= 2.0.1 =
* Fix: Pending Compliance update blocking the notice
* Fix: PHP Warning: Cannot modify header information
* Tweak: UI/UX fixes for the settings screen
= 2.0.0 =
* New: Introducing Cookie Compliance for GDPR/CCPA
= 1.3.2 =
* Tweak: Speed up Corona Banner loading by moving JS file to footer with async parameter
* Tweak: Improve buttons CSS padding
* Tweak: Accessibility improvements on links
= 1.3.1 =
* Fix: Unable to select Privacy policy link
* Fix: Blank Cookies policy link in a message
* Fix: Undefined index: on_click
* Tweak: Adjusted default opacity back to 100
= 1.3.0 =
* New: Introducing Corona Banner that displays data about Coronavirus pandemia and five steps recommended by the WHO (World Health Organization)
* New: Option to set bar opacity
* New: Accept the notice with close icon
* Fix: Policy link added to message without policy option enabled
= 1.2.51 =
* Fix: Problems with iOS and OK/Reject button
* Tweak: Added Separate cookie expiry for Reject, props Carlos Buchart
= 1.2.50 =
* Fix: The body css class always set to "cookies-refused"
* Tweak: Improve IE & Safari CustomEvent and ClassList support
* Tweak: Change the plugin js init event
= 1.2.49 =
* New: Option to accept the notice with any page click
* Tweak: Remove jQuery dependency
* Tweak: Swtich from jQuery to CSS3 animations
* Tweak: Improve the CSS and HTML structure
= 1.2.48 =
* Fix: HTML tags stripped from cookie message
* Fix: Link target not accepted in inline privacy link
= 1.2.47 =
* New: Option to select the privacy policy link position
* Tweak: Do not relad the page on refuse button click
* Tweak: Added aria-label attribute to cookie notice container
= 1.2.46 =
* Tweak: Remove WP Super Cache cookie on deactivation
* Tweak: Remove plugin version from the db on deactivation
= 1.2.45 =
* Tweak: Improved WP Super Cache support
* Tweak: CSS container style issue and media query for mobile
= 1.2.44 =
* Fix: The text of the revoke button ignored in shortcode
* Fix: Revoke consent button not displayed automatically in top position
* Tweak: Add shortcode parsing for content of [cookies_accepted], thanks to [dsturm](https://github.com/dsturm)
= 1.2.43 =
* New: Option to revoke the user consent
* New: Script blocking extended to header and footer
* New: Synchronization with WordPress 4.9.6 Privacy Policy page
* New: Custom button class option
* Tweak: Added 1 hour cookie expiry option
= 1.2.42 =
* New: Introducing [cookies_accepted][/cookies_accepted] shortcode
* Fix: Infinite cookie expiry issue
= 1.2.41 =
* Fix: Infinite redirection loop with scroll enabled
= 1.2.40 =
* Fix: Div align center on some themes
* Tweak: Extended list of allowed HTML tags in refuse code
* Tweak: Minified CSS and JS
= 1.2.39 =
* New: Option to reload the page after cookies are accepted
= 1.2.38 =
* Tweak: Move frontend cookie js functions before the document ready call, thanks to [fgreinus](https://github.com/fgreinus)
* Tweak: Adjust functional javascript code handling
* Fix: Chhromium infinity expiration date not valid
* Fix: Remove deprecated screen_icon() function
= 1.2.37 =
* Tweak: Add aria landmark role="banner"
* Tweak: Extend cn_cookie_notice_args with button class
= 1.2.36.1 =
* Fix: Repository upload issue with 1.2.36
= 1.2.36 =
* Fix: String translation support for WMPL 3.2+
* Fix: Global var possible conflict with other plugins
* Tweak: Add $options array to "cn_cookie_notice_output" filter, thanks to [chesio](https://github.com/chesio).
* Tweak: Removed local translation files in favor of WP repository translations.
= 1.2.35 =
* Tweak: Use html_entity_decode on non-functional code block
* Tweak: get_pages() function placement optimization
* Tweak: Filterable manage cookie notice capability
= 1.2.34 =
* Fix: Empty href in links HTML validation issue
= 1.2.33 =
* New: Greek translation thanks to Elias Stefanidis
= 1.2.32 =
* Fix: Accept cookie button hidden on acceptance instead of the cookie message container
= 1.2.31 =
* New: Non functional Javascript code field
* Fix: Minified Javascript caching issue
= 1.2.30 =
* Fix: jQuery error after accepting cookies
= 1.2.29 =
* Tweak: Add class to body element when displayed
* Tweak: Italian translation update
= 1.2.28 =
* New: Option to set on scroll offset
= 1.2.27 =
* Tweak: Correctly remove scroll event, limit possible conflicts
* Tweak: Italian translation update
= 1.2.26 =
* Fix: Accept cookies on scroll option working unchecked.
* Fix: call_user_func() warning on lower version of WP
= 1.2.25 =
* New: Option to accept cookies on scroll, thanks to [Cristian Pascottini](http://cristian.pascottini.net/)
= 1.2.24 =
* New: Option to refuse to accept cookies
* New: setCookieNotice custom jQuery event
* Tweak: Italian translation updated, thanks to Luca Speranza
= 1.2.23 =
* New: Finnish translation, thanks to [Daniel Storgards](www.danielstorgards.com)
= 1.2.22 =
* Tweak: Swedish translation updated, thx to Ove Kaufeldt
= 1.2.21 =
* New: Plugin development moved to [dFactory GitHub Repository](https://github.com/dfactoryplugins)
* Tweak: Code cleanup
= 1.2.20 =
* New: Option to select scripts placement, header or footer
= 1.2.19 =
* New: Danish translation, thanks to Lui Wallentin Gottler
= 1.2.18.1 =
* Fix: Quick fix for 1.2.18 print_r in code
= 1.2.18 =
* New: More info link target option
* Tweak: Additional HTML ids, for more flexible customization
= 1.2.17 =
* New: Hebrew translation, thanks to [Ahrale Shrem](http://atar4u.com/)
= 1.2.16 =
* Tweak: Dutch translation missing due to a typo
= 1.2.15 =
* New: Danish translation, thanks to Hans C. Jorgensen
* Fix: Notice bar not visible if no animation selected
= 1.2.14 =
* New: Hungarian translation, thanks to [Surbma](http://surbma.hu)
= 1.2.13 =
* New: Croatian translation, thanks to [Marko Beus](http://www.markobeus.com/)
= 1.2.12 =
* New: Slovenian translation, thanks to Thomas Cuk
= 1.2.11 =
* New: Swedish translation, thanks to [Daniel Storgards](http://www.danielstorgards.com/)
= 1.2.10 =
* New: Italian translation, thanks to [Luca](http://www.lucacicca.it)
* Tweak: Confirmed WP 4.0 compatibility
= 1.2.9.1 =
* Tweak: Enable HTML in cookie message text
* New: Option to donate this plugin :)
= 1.2.8 =
* New: Czech translation, thanks to [Adam Laita](http://laita.cz)
= 1.2.7 =
* New: French translation, thanks to [Laura Orsal](http://www.traductrice-independante.fr)
* New: Deleting plugin settings on deactivation as an option
= 1.2.6 =
* New: German translation, thanks to Alex Ernst
= 1.2.5 =
* New: Spanish translation, thanks to Fernando Blasco
= 1.2.4 =
* New: Added filter hooks to customize where and how display the cookie notice
= 1.2.3 =
* New: Portuguese translation, thanks to Luis Maia
= 1.2.2 =
* Fix: Read more linking to default site language in WPML & Polylang
= 1.2.1 =
* Tweak: UI improvements for WP 3.8
= 1.2.0 =
* Fix: Cookie not saving in IE
* Fix: Notice hidden under Admin bar bug
* Tweak: Improved WPML & Polylang compatibility
= 1.1.0 =
* New: Rewritten cookie setting method to pure JS
* Fix: Compatibility with WP Super Cache and other caching plugins
= 1.0.2 =
* New: Dutch translation, thanks to Heleen van den Bos
= 1.0.1 =
* Tweak: Changed setting cookie mode from AJAX to JS driven
= 1.0.0 =
Initial release
== Upgrade Notice ==
= 2.4.10 =
New: Option to enable/disable caching compatibility, WP Fastest Cache plugin compatibility, Fix: Potential security issue with purging cache
\ No newline at end of file
<!-- BLOCKED -->
\ No newline at end of file
......@@ -96,11 +96,17 @@ class Mandrill {
if( 200 == $response_code ) {
return $body;
} else {
$code = 'Unknown' ? !array_key_exists('code', $body) : $body['code'];
$message = 'Unknown' ? !array_key_exists('message', $body) : $body['message'];;
if( !is_array( $body ) ) {
$code = 'Unknown';
$message = 'Unknown';
} else {
$code = 'Unknown' ? !array_key_exists('code', $body) : $body['code'];
$message = 'Unknown' ? !array_key_exists('message', $body) : $body['message'];
}
error_log("wpMandrill Error: Error {$code}: {$message}");
throw new Mandrill_Exception( "wpMandrill Error: {$code}: {$message}", $response_code);
throw new Mandrill_Exception("wpMandrill Error: {$code}: {$message}", $response_code);
}
}
......
......@@ -1073,9 +1073,11 @@ class wpMandrill {
* saved stats if found... and if there's none saved, it creates it directly from Mandrill.
*/
static function getCurrentStats() {
if( array_key_exists('fetch_new', $_GET) && $_GET['fetch_new']=='asap'){
$stats = self::saveProcessedStats();
return $stats;
if( is_array($_GET) ){
if( array_key_exists('fetch_new', $_GET) && $_GET['fetch_new']=='asap'){
$stats = self::saveProcessedStats();
return $stats;
}
}
$stats = get_transient('wpmandrill-stats');
......
......@@ -3,8 +3,8 @@ Contributors: MillerMediaNow, mikemm01, MC_Will, MC_Amanda, cornelraiu-1, crstau
Tags: mandrill, mailchimp, transactional email, email, email reliability, smtp, wp_mail, email templates
Requires PHP: 5.6
Requires at least: 3.0
Tested up to: 5.9
Stable tag: 1.3
Tested up to: 6.1.1
Stable tag: 1.3.1
License: GPLv2
The Send Emails with Mandrill plugin sends emails that are generated by WordPress through Mandrill, a transactional email service powered by MailChimp.
......@@ -112,6 +112,9 @@ If your account has more than 20 senders registered or more than 40 tags used, t
4. Dashboard widget Settings
== Changelog ==
= 1.3.1 =
* Check for error messages parameters before processing (was throwing an error)
= 1.3 =
* Added setting to turn off Dashboard Widget
* Added ability to manually fetch new data from Reports screen
......
......@@ -4,7 +4,7 @@ Plugin Name: Send E-mails with Mandrill
Description: Send e-mails using Mandrill. This is a forked version of the now unsupported plugin <a href="https://wordpress.org/plugins/wpmandrill/">wpMandrill</a>.
Author: Miller Media ( Matt Miller )
Author URI: http://www.millermedia.io
Version: 1.3
Version: 1.3.1
Requires PHP: 5.6
Text Domain: send-emails-with-mandrill
*/
......@@ -32,7 +32,7 @@ if ( ! defined( 'ABSPATH' ) ) exit;
// Define plugin constants
if ( !defined('SEWM_VERSION'))
define( 'SEWM_VERSION', '1.3' );
define( 'SEWM_VERSION', '1.3.1' );
if ( !defined( 'SEWM_BASE' ) )
define( 'SEWM_BASE', plugin_basename( __FILE__ ) );
......@@ -46,4 +46,4 @@ if ( !defined( 'SEWM_PATH' ) )
include( plugin_dir_path( __FILE__ ) . 'lib/pluginActivation.class.php');
include( plugin_dir_path( __FILE__ ) . 'lib/wpMandrill.class.php');
wpMandrill::on_load();
\ No newline at end of file
wpMandrill::on_load();
......
<?php
/**
* The template for displaying 404 pages (not found)
*
* @package Understrap
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
get_header();
$container = get_theme_mod( 'understrap_container_type' );
?>
<div class="wrapper" id="error-404-wrapper" style="background-image:url('wp-content/uploads/2023/08/iStock-1090668452_Recoloured-scaled.jpg');">
<div class="<?php echo esc_attr( $container ); ?>" id="content" tabindex="-1">
<div class="row">
<div class="col-md-12 content-area" id="primary">
<main class="site-main" id="main">
<section class="error-404 not-found">
<header class="page-header">
<h1 class="page-title"><?php esc_html_e( '404', 'understrap' ); ?></h1>
</header><!-- .page-header -->
<div class="page-content">
<p><?php esc_html_e( 'Oops! That page can&rsquo;t be found. It looks like nothing was found at this location.', 'understrap' ); ?></p>
<?php if ( 1 == 2 ) : // Only show the widget if site has multiple categories. ?>
<?php get_search_form(); ?>
<?php the_widget( 'WP_Widget_Recent_Posts' ); ?>
<div class="widget widget_categories">
<h2 class="widget-title"><?php esc_html_e( 'Most Used Categories', 'understrap' ); ?></h2>
<ul>
<?php
wp_list_categories(
array(
'orderby' => 'count',
'order' => 'DESC',
'show_count' => 1,
'title_li' => '',
'number' => 10,
)
);
?>
</ul>
</div><!-- .widget -->
<?php endif; ?>
<?php
?>
</div><!-- .page-content -->
</section><!-- .error-404 -->
</main>
</div><!-- #primary -->
</div><!-- .row -->
</div><!-- #content -->
</div><!-- #error-404-wrapper -->
<?php
get_footer();
......@@ -15588,6 +15588,49 @@ body, html {
gap: 0px;
}
}
.grecaptcha-badge {
display: none !important;
}
div#error-404-wrapper {
min-height: 100vh;
background-size: cover;
background-repeat: no-repeat;
background-position: 0% 100%;
}
.error-404 {
padding-top: 160px;
padding-bottom: 100px;
text-align: center;
}
.error-404 h1, .error-404 .h1 {
font-size: 300px;
line-height: 300px;
margin-bottom: 20px;
}
@media (max-width: 786px) {
.error-404 h1, .error-404 .h1 {
font-size: 150px;
line-height: 150px;
}
}
.error-404 p {
color: #000;
width: 70%;
margin: auto;
font-size: 26px;
line-height: 40px;
font-weight: 700;
background-color: rgba(255, 255, 255, 0.7);
}
@media (max-width: 786px) {
.error-404 p {
font-size: 20px;
line-height: 26px;
}
}
.has-blue-color,
.has-blue-color:visited {
color: #0d6efd;
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
@import url("https://use.typekit.net/lov0ylb.css");
......@@ -125,4 +126,44 @@ body,html{
.extra-wide{
gap:0px;
}
}
.grecaptcha-badge{
display: none !important;
}
div#error-404-wrapper {
min-height: 100vh;
background-size: cover;
background-repeat: no-repeat;
background-position: 0% 100%;
}
.error-404{
padding-top: 160px;
padding-bottom: 100px;
text-align: center;
h1{
font-size: 300px;
line-height: 300px;
margin-bottom: 20px;
@media (max-width: 786px) {
font-size: 150px;
line-height: 150px;
}
}
p{
color: #000;
width: 70%;
margin: auto;
font-size: 26px;
line-height: 40px;
font-weight: 700;
background-color: rgba(255,255,255,.7);
@media (max-width: 786px) {
font-size: 20px;
line-height: 26px;
}
}
}
\ No newline at end of file
......
......@@ -5,7 +5,7 @@
Author: the Understrap Contributors
Author URI: https://github.com/understrap/understrap-child/graphs/contributors
Template: understrap
Version: 1.2.13
Version: 1.2.14
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: understrap-child
......