├── Configuration ├── NodeTypes.yaml └── Settings.yaml ├── Resources ├── Private │ ├── Translations │ │ ├── en │ │ │ ├── NodeTypes │ │ │ │ └── PolicyPageMixin.xlf │ │ │ └── Main.xlf │ │ └── de │ │ │ ├── NodeTypes │ │ │ └── PolicyPageMixin.xlf │ │ │ └── Main.xlf │ ├── Templates │ │ └── FusionObjects │ │ │ └── Initialize.html │ └── Fusion │ │ └── Root.fusion └── Public │ ├── Stylesheets │ └── cookieconsent.min.css │ └── JavaScript │ └── cookieconsent.min.js ├── composer.json ├── LICENSE └── README.md /Configuration/NodeTypes.yaml: -------------------------------------------------------------------------------- 1 | 'KaufmannDigital.CookieConsent:PolicyPageMixin': 2 | abstract: true 3 | properties: 4 | policyPage: 5 | type: reference 6 | ui: 7 | label: i18n 8 | reloadIfChanged: true 9 | inspector: 10 | group: document 11 | position: 'after uriPathSegment' 12 | -------------------------------------------------------------------------------- /Resources/Private/Translations/en/NodeTypes/PolicyPageMixin.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Policy page 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Resources/Private/Translations/de/NodeTypes/PolicyPageMixin.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Policy page 7 | Seite Datenschutzerklärung 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "A ready-to-run Neos CMS Package, that adds Cookie Consent to your Neos-Site", 3 | "type": "neos-package", 4 | "name": "kaufmanndigital/cookieconsent", 5 | "license": "MIT", 6 | "homepage": "https://www.kaufmann.digital", 7 | "authors": [ 8 | { 9 | "name": "Niklas Droste", 10 | "email": "support@kaufmann.digital", 11 | "homepage": "https://www.kaufmann.digital", 12 | "role": "Developer" 13 | } 14 | ], 15 | "support": { 16 | "email": "support@kaufmann.digital", 17 | "issues": "https://github.com/KaufmannDigital/KaufmannDigital.CookieConsent/issues" 18 | }, 19 | "require": { 20 | "neos/neos": ">=3.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "KaufmannDigital\\CookieConsent\\": "Classes/" 25 | } 26 | }, 27 | "extra": { 28 | "neos": { 29 | "package-key": "KaufmannDigital.CookieConsent" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kaufmann Digital 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Resources/Private/Translations/en/Main.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Cookie Policy 7 | 8 | 9 | This website uses cookies to ensure you get the best experience on our website. 10 | 11 | 12 | Got it! 13 | 14 | 15 | Allow cookies 16 | 17 | 18 | Decline 19 | 20 | 21 | Learn more 22 | 23 | 24 | Cookie Policy 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Resources/Private/Translations/de/Main.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Cookie Richtlinien 7 | 8 | 9 | Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer 10 | 11 | 12 | Okay 13 | 14 | 15 | Cookies erlauben 16 | 17 | 18 | Cookies ablehnen 19 | 20 | 21 | Datenschutzerklärung 22 | 23 | 24 | Cookie Einstellungen 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Resources/Private/Templates/FusionObjects/Initialize.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 58 | -------------------------------------------------------------------------------- /Configuration/Settings.yaml: -------------------------------------------------------------------------------- 1 | Neos: 2 | Neos: 3 | fusion: 4 | autoInclude: 5 | KaufmannDigital.CookieConsent: true 6 | userInterface: 7 | translation: 8 | autoInclude: 9 | 'KaufmannDigital.CookieConsent': 10 | - 'NodeTypes/*' 11 | 12 | KaufmannDigital: 13 | CookieConsent: 14 | enable: true 15 | includeJavaScript: true 16 | includeCss: true 17 | type: '' 18 | 19 | #Global configuration of PolicyPage 20 | policyPageNode: 'needs-to-be-set' #UUID of global page you want to link 21 | 22 | # #Configuration per site for multisite installations 23 | # #Replace site1/site2 with your sitename (/sites/sitename/node-a2ufd/.../) 24 | # policyPageNodes: 25 | # site1: 'c7a91aa8-fbac-4c24-8326-102eb7307180' #UUID of policy-page for /sites/site1 26 | # site2: '454d85b6-289b-11e9-b210-d663bd873d93' #UUID of policy-page for /sites/site2 27 | 28 | translations: 29 | package: 'KaufmannDigital.CookieConsent' 30 | source: 'Main' 31 | position: 'bottom' 32 | static: false 33 | theme: 'block' 34 | layout: 'basic' 35 | palette: 36 | popup: 37 | background: '#000' 38 | text: '#fff' 39 | button: 40 | background: '#f1d600' 41 | text: '#000' 42 | elements: 43 | header: '{{header}} ' 44 | message: '{{message}}' 45 | messagelink: '{{message}} {{link}}' 46 | dismiss: '{{dismiss}}' 47 | allow: '{{allow}}' 48 | deny: '{{deny}}' 49 | link: '{{link}}' 50 | close: '{{close}}' 51 | compliance: 52 | 'info': '
{{dismiss}}
' 53 | 'opt-in': '
{{dismiss}}{{allow}}
' 54 | 'opt-out': '
{{deny}}{{dismiss}}
' 55 | cookie: 56 | name: 'cookieconsent_status' 57 | path: '/' 58 | domain: '' 59 | expiryDays: 365 60 | secure: false 61 | -------------------------------------------------------------------------------- /Resources/Public/Stylesheets/cookieconsent.min.css: -------------------------------------------------------------------------------- 1 | .cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s} 2 | .cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1} 3 | .cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1 0 auto;flex:1 0 auto}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{display:block;-ms-flex:1 1 auto;flex:1 1 auto;max-width:100%;margin-right:1em}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-floating .cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em} 4 | @media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-floating,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1 1 auto;flex:1 1 auto}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}.cc-window.cc-banner .cc-message{margin-right:0}} 5 | .cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block} 6 | .cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0} 7 | -------------------------------------------------------------------------------- /Resources/Private/Fusion/Root.fusion: -------------------------------------------------------------------------------- 1 | prototype(Neos.Neos:Page) { 2 | head.cookieConsent = Neos.Fusion:Template { 3 | templatePath = 'resource://KaufmannDigital.CookieConsent/Private/Templates/FusionObjects/Initialize.html' 4 | 5 | includeJavaScript = ${Configuration.setting('KaufmannDigital.CookieConsent.includeJavaScript')} 6 | includeCss = ${Configuration.setting('KaufmannDigital.CookieConsent.includeCss')} 7 | 8 | 9 | settings = Neos.Fusion:RawArray { 10 | type = ${Configuration.setting('KaufmannDigital.CookieConsent.type')} 11 | position = ${Configuration.setting('KaufmannDigital.CookieConsent.position')} 12 | static = ${Configuration.setting('KaufmannDigital.CookieConsent.static')} 13 | theme = ${Configuration.setting('KaufmannDigital.CookieConsent.theme')} 14 | layout = ${Configuration.setting('KaufmannDigital.CookieConsent.layout')} 15 | palette = ${Configuration.setting('KaufmannDigital.CookieConsent.palette')} 16 | elements = ${Configuration.setting('KaufmannDigital.CookieConsent.elements')} 17 | compliance = ${Configuration.setting('KaufmannDigital.CookieConsent.compliance')} 18 | cookie = ${Configuration.setting('KaufmannDigital.CookieConsent.cookie')} 19 | content = Neos.Fusion:RawArray { 20 | header = ${Translation.translate('header', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 21 | message = ${Translation.translate('message', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 22 | dismiss = ${Translation.translate('dismiss', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 23 | allow = ${Translation.translate('allow', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 24 | deny = ${Translation.translate('deny', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 25 | link = ${Translation.translate('link-text', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package'))} 26 | policy = ${Translation.translate('policy-link', null, [], Configuration.setting('KaufmannDigital.CookieConsent.translations.source'), Configuration.setting('KaufmannDigital.CookieConsent.translations.package')) || 'Cookie Policy'} 27 | 28 | href = Neos.Neos:NodeUri { 29 | node = Neos.Fusion:Case { 30 | policyPageProperty { 31 | condition = ${q(site).property('policyPage')} 32 | renderer = ${q(site).property('policyPage')} 33 | } 34 | 35 | policyPageNodes { 36 | condition = ${String.isBlank(Configuration.setting('KaufmannDigital.CookieConsent.policyPageNodes.' + site.name)) == false} 37 | renderer = ${q(site).find('#' + Configuration.setting('KaufmannDigital.CookieConsent.policyPageNodes.' + site.name)).get(0)} 38 | } 39 | 40 | globalConfiguration { 41 | condition = true 42 | renderer = ${q(site).find('#' + Configuration.setting('KaufmannDigital.CookieConsent.policyPageNode')).get(0)} 43 | } 44 | } 45 | 46 | 47 | absolute = true 48 | } 49 | } 50 | 51 | @process.json = ${Json.stringify(value)} 52 | } 53 | 54 | @if.enabled = ${Configuration.setting('KaufmannDigital.CookieConsent.enable') == true} 55 | @if.notInBackend = ${site.context.inBackend == false} 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | KaufmannDigital.CookieConsent 2 | ============================= 3 | 4 | A ready-to-run package, that integrates [Cookie Consent](https://cookieconsent.insites.com/) into your [Neos CMS](https://www.neos.io) site. 5 | 6 | We have created a new package with many more functions, inline maintenance and even easier configuration. 🎉 7 | Have a look at [KaufmannDigital.GDPR.CookieConsent](https://github.com/KaufmannDigital/KaufmannDigital.GDPR.CookieConsent). 8 | 9 | 10 | Installation 11 | ------------ 12 | 13 | The easiest way to install is via composer: 14 | 15 | ```bash 16 | composer require kaufmanndigital/cookieconsent 17 | ``` 18 | 19 | Afterwards, you should see the Cookie Hint on your page. 20 | 21 | To configure the policy-link, you have the following two options: 22 | 23 | * Add the NodeType-Mixin `KaufmannDigital.CookieConsent:PolicyPageMixin` to your Home-NodeType (if you have a specific NodeType for home): 24 | 25 | ```yaml 26 | 'Your.Package:Document.Home': 27 | superTypes: 28 | 'Neos.Neos:Document': true 29 | 'KaufmannDigital.CookieConsent:PolicyPageMixin': true 30 | ... 31 | ``` 32 | 33 | After that, simply select the policy page in your Neos backend. 34 | 35 | * Or use this snippet in your `Settings.yaml`: 36 | 37 | ```yaml 38 | KaufmannDigital: 39 | CookieConsent: 40 | #Global configuration of PolicyPage 41 | policyPageNode: 'c7a91aa8-fbac-4c24-8326-102eb7307180' #UUID of global page you want to link 42 | 43 | #Configuration per site for multisite installations 44 | #Replace site1/site2 with your sitename (/sites/sitename/node-a2ufd/.../) 45 | policyPageNodes: 46 | site1: 'c7a91aa8-fbac-4c24-8326-102eb7307180' #UUID of policy-page for /sites/site1 47 | site2: '454d85b6-289b-11e9-b210-d663bd873d93' #UUID of policy-page for /sites/site2 48 | ``` 49 | 50 | _Congratulations, you added Cookie Consent to your Neos CMS page. That was easy, right?_ 51 | 52 | 53 | Changing the text 54 | ----------------- 55 | 56 | The content inside Cookie Consent is managed via translations. If you want to change it, copy the `Packages/Application/KaufmannDigital.CookieConsent/Resources/Private/Translations` folder into your Site-Package and add this configuration to `Settings.yaml`: 57 | 58 | ```yaml 59 | KaufmannDigital: 60 | CookieConsent: 61 | translations: 62 | package: 'Vendor.Package' 63 | source: 'Main' 64 | ``` 65 | 66 | From now, the translation from your package (in this example "Vendor.Package") will be used. 67 | 68 | Translations for German and English are provided by this package. We are happy to get translations for your language via Pull-Request. 69 | 70 | Changing layout & colors 71 | ------------------------ 72 | 73 | You can also change colors and position. To do so, you have to add this snippet to `Settings.yaml`: 74 | 75 | ```yaml 76 | KaufmannDigital: 77 | CookieConsent: 78 | position: 'bottom' # bottom, bottom-left, bottom-right, top, top-left or top-right 79 | theme: 'block' # block, classic, or edgeless 80 | layout: 'basic' # basic, basic-close or basic-header 81 | palette: 82 | popup: 83 | background: '#000' #like in css 84 | text: 'white' #like in css 85 | button: 86 | background: 'rgb(255, 0, 0)' #like in css 87 | text: '#fff' #like in css 88 | ``` 89 | 90 | You don't have to override all values. Just pick what you want to change. More configuration-options can be found at [cookieconsent.insites.com](https://cookieconsent.insites.com) 91 | 92 | 93 | Using Opt-In or Opt-Out 94 | ----------------------- 95 | 96 | In order to use Opt-In or Opt-Out functionality, you have to activate it in Settings: 97 | 98 | ```yaml 99 | KaufmannDigital: 100 | CookieConsent: 101 | type: 'opt-in' #Or 'opt-out' (depending on what you want to do) 102 | ``` 103 | 104 | Afterwards, you can listen to the `kd-cookieconsent` event in JavaScript to en-/disable cookies: 105 | 106 | ```javascript 107 | document.addEventListener("kd-cookieconsent", function (e) { 108 | if (e.detail === 'enable-cookies') { 109 | //Enable your cookies here 110 | //For Google Analytics: 111 | window['ga-disable-UA-'] = false; 112 | } else if (e.detail === 'disable-cookies') { 113 | //Disable your cookies here 114 | //For Google Analytics: 115 | window['ga-disable-UA-'] = true; 116 | } 117 | }); 118 | ``` 119 | 120 | Compile JS & CSS into your own files 121 | ------------------------------------ 122 | 123 | If you don't want this Package to include it's own JS and CSS, you can disable it with in `Settings.yaml`: 124 | 125 | ```yaml 126 | KaufmannDigital: 127 | CookieConsent: 128 | includeJavaScript: false 129 | includeCss: false 130 | ``` 131 | 132 | If you do so, you have to include JS & CSS of Cookie Consent in your files. [Instructions can be found here](https://github.com/insites/cookieconsent/#installation) 133 | 134 | 135 | FAQs 136 | ---- 137 | * Cookie Consent isn't shown in Backend. 138 | * It's a feature, not a bug ;-) 139 | 140 | 141 | Known Bugs 142 | ---------- 143 | Known Bugs are submitted as issue. Please have a look at it, before you supply a bug you found. 144 | You did a bugfix? Great! Please submit it as PR to share it with other users. 145 | 146 | Planned Features 147 | ---------------- 148 | Planned functions are also created as issues and marked as such. 149 | You have another idea? Or would you like to help with the implementation? Gladly! Simply create new issues or PRs. 150 | 151 | Maintainer 152 | ---------- 153 | This package is maintained by [Kaufmann Digital](https://www.kaufmann.digital). 154 | Feel free to send us your questions or requests to [support@kaufmann.digital](mailto:support@kaufmann.digital) 155 | 156 | License 157 | ------- 158 | Licensed under MIT, see [LICENSE](LICENSE) 159 | -------------------------------------------------------------------------------- /Resources/Public/JavaScript/cookieconsent.min.js: -------------------------------------------------------------------------------- 1 | !function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){var i=/{{([a-z][a-z0-9\-_]*)}}/gi;return e.replace(i,function(e){return t(arguments[1])||""})},getCookie:function(e){var t="; "+document.cookie,i=t.split("; "+e+"=");return i.length<2?void 0:i.pop().split(";").shift()},setCookie:function(e,t,i,n,o,s){var r=new Date;r.setDate(r.getDate()+(i||365));var a=[e+"="+t,"expires="+r.toUTCString(),"path="+(o||"/")];n&&a.push("domain="+n),s&&a.push("secure"),document.cookie=a.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n,o=0;if(0===e.length)return o;for(t=0,n=e.length;t=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38,n=(t>>16)+i,o=(t>>8&255)+i,s=(255&t)+i,r=(16777216+65536*(n<255?n<1?0:n:255)+256*(o<255?o<1?0:o:255)+(s<255?s<1?0:s:255)).toString(16).slice(1);return"#"+r},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,i){return e&&e.parentNode?t.hasClass(e,i)?e:this.traverseDOMPath(e.parentNode,i):null}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&"undefined"!=typeof e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){function n(){this.initialise.apply(this,arguments)}function o(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function s(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function r(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var i=Object.keys(e.status),n=this.getStatus(),o=i.indexOf(n)>=0;return o&&t(n),o}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(){var e=this.options,i="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(i="floating");var n=["cc-"+i,"cc-type-"+e.type,"cc-theme-"+e.theme];e["static"]&&n.push("cc-static"),n.push.apply(n,a.call(this));p.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function l(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message),Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info),e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];return o||(o=i.layouts.basic),t.interpolateString(o,function(t){return e[t]})}function u(i){var n=this.options,o=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;o.innerHTML=i;var r=o.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=h.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function h(n){var o=t.traverseDOMPath(n.target,"cc-btn")||n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(o,"cc-revoke")&&this.revokeChoice()}function p(e){var i=t.hash(JSON.stringify(e)),n="cc-color-override-"+i,o=t.isPlainObject(e);return this.customStyleSelector=o?n:null,o&&d(i,e,"."+n),o}function d(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],a.padding&&s[o+" .cc-btn"].push("padding: "+a.padding),"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+(a.hover||v(a.background))]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[i]={references:1,element:l.sheet};var u=-1;for(var h in s)s.hasOwnProperty(h)&&l.sheet.insertRule(h+"{"+s[h].join(";")+"}",++u)}function v(e){return e=t.normaliseHex(e),"000000"==e?"#222":t.getLuminance(e)}function f(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}function m(e,t){for(var i=0,n=e.length;i=0&&(this.dismissTimeout=window.setTimeout(function(){i(e.status.dismiss),n(!0)},Math.floor(o)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function(t){window.pageYOffset>Math.floor(s)&&(i(e.status.dismiss),n(!0),window.removeEventListener("scroll",r),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var a=this.options.dismissOnWindowClick,c=this.options.ignoreClicksFrom;if(a){var l=function(o){for(var s=!1,r=o.path.length,a=c.length,u=0;us&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}var y={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
{{policy}}
',compliance:{info:'
{{dismiss}}
',"opt-in":'
{{deny}}{{allow}}
',"opt-out":'
{{deny}}{{allow}}
'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block","static":!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};return n.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},y),t.isPlainObject(e)&&t.deepExtend(this.options,e),r.call(this)&&(this.options.enabled=!1),m(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),m(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var i=this.options.window.replace("{{classes}}",c.call(this).join(" ")).replace("{{children}}",l.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(i=n),this.options["static"]){var o=u.call(this,'
'+i+"
");o.style.display="",this.element=o.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=u.call(this,i);b.call(this),g.call(this),this.options.autoOpen&&this.autoOpen()},n.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,f(this.options.palette),this.options=null},n.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},n.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},n.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&s.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options["static"]){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}var r=20;this.openingTimeout=setTimeout(o.bind(this,i),r)}},n.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),o.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options["static"]&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},n.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},n.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},n.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},n.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},n.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},n.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},n.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},n.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},n.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},n}(),e.Location=function(){function e(e){t.deepExtend(this.options={},s),t.isPlainObject(e)&&t.deepExtend(this.options,e),this.currentServiceIndex=-1}function i(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function n(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r3&&t(s)}),s.send(n)}function o(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}var s={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?o({error:i.statusMessage}):{code:i.countryCode}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){return window.geoip2?void geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(i){e(o(i))}},function(t){e(o(t))}):void e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};return e.prototype.getNextService=function(){var e;do e=this.getServiceByIdx(++this.currentServiceIndex);while(this.currentServiceIndex=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},e.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,i)),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},e}(),e.initialise=function(i,n,o){var s=new e.Law(i.law);n||(n=function(){}),o||(o=function(){});var r=Object.keys(e.status),a=t.getCookie("cookieconsent_status"),c=r.indexOf(a)>=0;return c?void n(new e.Popup(i)):void e.getCountryCode(i,function(t){delete i.law,delete i.location,t.code&&(i=s.applyLaw(i,t.code)),n(new e.Popup(i))},function(t){delete i.law,delete i.location,o(t,new e.Popup(i))})},e.getCountryCode=function(t,i,n){if(t.law&&t.law.countryCode)return void i({code:t.law.countryCode});if(t.location){var o=new e.Location(t.location);return void o.locate(function(e){i(e||{})},n)}i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{}); 2 | --------------------------------------------------------------------------------