├── 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 |
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 |
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: ' '
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:' ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'{{children}}
',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 |
--------------------------------------------------------------------------------