@dargmuesli/nuxt-cookie-control 10.0.0-beta.1 → 10.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/module.d.mts +6 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -1
- package/dist/runtime/components/CookieControl.vue +4 -1
- package/dist/runtime/styles.css +1 -1
- package/dist/runtime/types.d.ts +6 -0
- package/dist/runtime/types.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,11 @@ if (cookieControl.cookiesEnabledIds.value.includes('google-analytics')) {
|
|
|
105
105
|
// 'top-left', 'top-right', 'top-full', 'bottom-left', 'bottom-right', 'bottom-full'
|
|
106
106
|
barPosition: 'bottom-full',
|
|
107
107
|
|
|
108
|
+
// Position of the cookie control button.
|
|
109
|
+
// 'top-left', 'top-right', 'bottom-left', 'bottom-right'
|
|
110
|
+
// @default 'bottom-right'
|
|
111
|
+
controlButtonPosition: 'bottom-right',
|
|
112
|
+
|
|
108
113
|
// Switch to toggle if clicking the overlay outside the configuration modal closes the modal.
|
|
109
114
|
closeModalOnClickOutside: true,
|
|
110
115
|
|
package/dist/module.d.mts
CHANGED
|
@@ -33,6 +33,12 @@ interface LocaleStrings {
|
|
|
33
33
|
interface ModuleOptions {
|
|
34
34
|
_isPrerendered: boolean | undefined;
|
|
35
35
|
barPosition: 'top-left' | 'top-right' | 'top-full' | 'bottom-left' | 'bottom-right' | 'bottom-full';
|
|
36
|
+
/**
|
|
37
|
+
* Position of the control button.
|
|
38
|
+
* 'top-left', 'top-right', 'bottom-left', 'bottom-right', or undefined.
|
|
39
|
+
* @default 'bottom-right'
|
|
40
|
+
*/
|
|
41
|
+
controlButtonPosition: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
36
42
|
closeModalOnClickOutside: boolean;
|
|
37
43
|
colors: false | Record<string, unknown>;
|
|
38
44
|
cookieExpiryOffsetMs: number;
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -49,6 +49,7 @@ const replaceCodePlugin = (config) => {
|
|
|
49
49
|
const DEFAULTS = {
|
|
50
50
|
_isPrerendered: void 0,
|
|
51
51
|
barPosition: "bottom-full",
|
|
52
|
+
controlButtonPosition: "bottom-right",
|
|
52
53
|
closeModalOnClickOutside: false,
|
|
53
54
|
colors: {
|
|
54
55
|
barBackground: "#000",
|
|
@@ -105,7 +106,7 @@ const DEFAULTS = {
|
|
|
105
106
|
};
|
|
106
107
|
|
|
107
108
|
const name = "@dargmuesli/nuxt-cookie-control";
|
|
108
|
-
const version = "10.0.0-beta.
|
|
109
|
+
const version = "10.0.0-beta.2";
|
|
109
110
|
|
|
110
111
|
const resolver = createResolver(import.meta.url);
|
|
111
112
|
const runtimeDir = resolver.resolve("./runtime");
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
<button
|
|
38
38
|
v-if="moduleOptions.isControlButtonEnabled && isConsentGiven"
|
|
39
39
|
aria-label="Cookie control"
|
|
40
|
-
class="
|
|
40
|
+
:class="[
|
|
41
|
+
'cookieControl__ControlButton',
|
|
42
|
+
`cookieControl__ControlButton--${moduleOptions.controlButtonPosition}`
|
|
43
|
+
]"
|
|
41
44
|
data-testid="nuxt-cookie-control-control-button"
|
|
42
45
|
type="button"
|
|
43
46
|
@click="isModalActive = true"
|
package/dist/runtime/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.cookieControl__Modal-enter-active,.cookieControl__Modal-leave-active{transition:opacity .25s}.cookieControl__Modal-enter,.cookieControl__Modal-leave-to{opacity:0}.cookieControl__Bar--center{left:50%;top:50%;transform:translate(-50%,-50%)}.cookieControl__Bar--bottom-full-enter-active,.cookieControl__Bar--bottom-full-leave-active,.cookieControl__Bar--bottom-left-enter-active,.cookieControl__Bar--bottom-left-leave-active,.cookieControl__Bar--bottom-right-enter-active,.cookieControl__Bar--bottom-right-leave-active,.cookieControl__Bar--center-enter-active,.cookieControl__Bar--center-leave-active,.cookieControl__Bar--top-full-enter-active,.cookieControl__Bar--top-full-leave-active,.cookieControl__Bar--top-left-enter-active,.cookieControl__Bar--top-left-leave-active,.cookieControl__Bar--top-right-enter-active,.cookieControl__Bar--top-right-leave-active{transition:transform .25s}.cookieControl__Bar--top-full-enter,.cookieControl__Bar--top-full-leave-to,.cookieControl__Bar--top-left-enter,.cookieControl__Bar--top-left-leave-to,.cookieControl__Bar--top-right-enter,.cookieControl__Bar--top-right-leave-to{transform:translateY(-100%)}.cookieControl__Bar--bottom-full-enter,.cookieControl__Bar--bottom-full-leave-to,.cookieControl__Bar--bottom-left-enter,.cookieControl__Bar--bottom-left-leave-to,.cookieControl__Bar--bottom-right-enter,.cookieControl__Bar--bottom-right-leave-to{transform:translateY(100%)}.cookieControl__Bar--center-enter,.cookieControl__Bar--center-leave-to{transform:translate(-50%,-50%) scale(.95)}.cookieControl{position:relative;z-index:100000}.cookieControl button{backface-visibility:hidden;border:0;cursor:pointer;font-size:16px;outline:0;padding:12px 20px;transition:background-color .2s,color .2s}.cookieControl__Bar{background-color:var(--cookie-control-barBackground);font-family:Arial,Helvetica Neue,Helvetica,sans-serif;position:fixed}.cookieControl__Bar h2,.cookieControl__Bar p{color:var(--cookie-control-barTextColor);max-width:900px}.cookieControl__Bar h2{font-size:20px;margin:0}.cookieControl__Bar p{font-size:16px;margin:5px 0 0}.cookieControl__Bar button{background-color:var(--cookie-control-barButtonBackground);color:var(--cookie-control-barButtonColor)}.cookieControl__Bar button:hover{background-color:var(--cookie-control-barButtonHoverBackground);color:var(--cookie-control-barButtonHoverColor)}.cookieControl__Bar button:focus{box-shadow:0 0 0 3px var(--cookie-control-focusRingColor)}.cookieControl__Bar button+button{margin-left:10px}.cookieControl__BarContainer{align-items:flex-end;display:flex;justify-content:space-between;padding:20px}.cookieControl__Bar--bottom-full,.cookieControl__Bar--top-full{left:0;right:0}.cookieControl__Bar--top-full{top:0}.cookieControl__Bar--bottom-full{bottom:0}.cookieControl__Bar--bottom-left p,.cookieControl__Bar--bottom-right p,.cookieControl__Bar--center p,.cookieControl__Bar--top-left p,.cookieControl__Bar--top-right p{max-width:400px}.cookieControl__Bar--bottom-left .cookieControl__BarContainer,.cookieControl__Bar--bottom-right .cookieControl__BarContainer,.cookieControl__Bar--center .cookieControl__BarContainer,.cookieControl__Bar--top-left .cookieControl__BarContainer,.cookieControl__Bar--top-right .cookieControl__BarContainer{flex-direction:column}.cookieControl__Bar--bottom-left .cookieControl__BarButtons,.cookieControl__Bar--bottom-right .cookieControl__BarButtons,.cookieControl__Bar--center .cookieControl__BarButtons,.cookieControl__Bar--top-left .cookieControl__BarButtons,.cookieControl__Bar--top-right .cookieControl__BarButtons{margin-top:20px}.cookieControl__Bar--top-left,.cookieControl__Bar--top-right{top:20px}.cookieControl__Bar--bottom-left,.cookieControl__Bar--bottom-right{bottom:20px}.cookieControl__Bar--bottom-left,.cookieControl__Bar--top-left{left:20px}.cookieControl__Bar--bottom-right,.cookieControl__Bar--top-right{right:20px}.cookieControl__BarButtons{display:flex}.cookieControl__Modal{bottom:0;font-size:0;left:0;position:fixed;right:0;text-align:center;top:0;z-index:1}.cookieControl__Modal:before{content:"";display:inline-block;min-height:100vh;vertical-align:middle}.cookieControl__Modal:after{background-color:var(--cookie-control-modalOverlay);bottom:0;content:"";left:0;opacity:var(--cookie-control-modalOverlayOpacity);position:absolute;right:0;top:0;z-index:-1}.cookieControl__Modal>div{font-size:medium}.cookieControl__Modal button{background-color:var(--cookie-control-modalButtonBackground);color:var(--cookie-control-modalButtonColor)}.cookieControl__Modal button:hover{background-color:var(--cookie-control-modalButtonHoverBackground);color:var(--cookie-control-modalButtonHoverColor)}.cookieControl__Modal button:focus{box-shadow:0 0 0 3px var(--cookie-control-focusRingColor)}.cookieControl__ModalContent{background-color:var(--cookie-control-modalBackground);display:inline-block;max-height:80vh;max-width:550px;overflow-y:scroll;position:relative;text-align:left;vertical-align:middle;width:100%}.cookieControl__ModalContent,.cookieControl__ModalContent :not(button){color:var(--cookie-control-modalTextColor)}.cookieControl__ModalContent h2{font-size:24px;margin:15px 0}.cookieControl__ModalContent h2:first-of-type{margin-top:0}.cookieControl__ModalContent ul{font-size:16px;list-style-type:none;padding:0}.cookieControl__ModalContent ul ul{padding:5px 56px 0}.cookieControl__ModalContent ul ul li+li{margin-top:5px}.cookieControl__ModalContent li{align-items:center}.cookieControl__ModalContent li+li{margin-top:20px}.cookieControl__ModalContent input{display:none}.cookieControl__ModalContent input:checked+button{background-color:var(--cookie-control-checkboxActiveBackground)}.cookieControl__ModalContent input:checked+button:before{background-color:var(--cookie-control-checkboxActiveCircleBackground);transform:translate3d(100%,-50%,0)}.cookieControl__ModalContent input:checked:disabled+button{background-color:var(--cookie-control-checkboxDisabledBackground)}.cookieControl__ModalContent input:checked:disabled+button:before{background-color:var(--cookie-control-checkboxDisabledCircleBackground)}.cookieControl__ModalContent input+button{backface-visibility:hidden;background-color:var(--cookie-control-checkboxInactiveBackground);border-radius:20px;display:block;font-size:0;margin-right:20px;min-height:20px;min-width:36px;position:relative;transition:background-color .2s}.cookieControl__ModalContent input+button:before{background-color:var(--cookie-control-checkboxInactiveCircleBackground);border-radius:50%;content:"";height:15px;left:3px;position:absolute;top:50%;transform:translate3d(0,-50%,0);transition:transform .2s;width:15px}.cookieControl__ModalContentInner{display:flex;flex-direction:column;gap:10px;padding:40px}.cookieControl__ModalInputWrapper{align-items:flex-start;display:flex}.cookieControl__ModalCookieName{font-weight:700;text-transform:uppercase}.cookieControl__ModalCookieName span{font-weight:400;text-transform:none}.cookieControl__ModalClose{align-self:flex-end;right:20px;top:20px}.cookieControl__ModalButtons{align-items:stretch;display:flex;gap:20px;margin-top:40px}.cookieControl__ModalUnsaved{bottom:40px;color:var(--cookie-control-modalUnsavedColor);font-size:14px;left:50%;margin:0;position:absolute;transform:translateX(-50%)}.cookieControl__BlockedIframe{border:2px solid #ddd;padding:20px}.cookieControl__BlockedIframe a,.cookieControl__BlockedIframe p{font-family:Arial,Helvetica Neue,Helvetica,sans-serif}@media screen and (max-width:768px){.cookieControl__Bar{flex-direction:column;left:0;right:0}.cookieControl__Bar h2,.cookieControl__Bar p{max-width:100%}.cookieControl__Bar--top-full,.cookieControl__Bar--top-left,.cookieControl__Bar--top-right{top:0}.cookieControl__Bar--bottom-full,.cookieControl__Bar--bottom-left,.cookieControl__Bar--bottom-right{bottom:0}.cookieControl__ModalContent{bottom:0;left:0;max-height:100%;max-width:none;position:absolute;right:0;top:0}.cookieControl__ModalContentInner{padding:20px}.cookieControl__BarButtons{flex-direction:column;justify-content:center;margin-top:20px;width:100%}.cookieControl__BarButtons button{width:100%}.cookieControl__BarButtons button+button{margin:10px 0 0}.cookieControl__BarContainer,.cookieControl__ModalButtons{flex-direction:column;gap:10px}.cookieControl__ModalButtons button{width:100%}}.cookieControl__ControlButton{backface-visibility:hidden;background:var(--cookie-control-controlButtonBackground);border:0;border-radius:50%;
|
|
1
|
+
.cookieControl__Modal-enter-active,.cookieControl__Modal-leave-active{transition:opacity .25s}.cookieControl__Modal-enter,.cookieControl__Modal-leave-to{opacity:0}.cookieControl__Bar--center{left:50%;top:50%;transform:translate(-50%,-50%)}.cookieControl__Bar--bottom-full-enter-active,.cookieControl__Bar--bottom-full-leave-active,.cookieControl__Bar--bottom-left-enter-active,.cookieControl__Bar--bottom-left-leave-active,.cookieControl__Bar--bottom-right-enter-active,.cookieControl__Bar--bottom-right-leave-active,.cookieControl__Bar--center-enter-active,.cookieControl__Bar--center-leave-active,.cookieControl__Bar--top-full-enter-active,.cookieControl__Bar--top-full-leave-active,.cookieControl__Bar--top-left-enter-active,.cookieControl__Bar--top-left-leave-active,.cookieControl__Bar--top-right-enter-active,.cookieControl__Bar--top-right-leave-active{transition:transform .25s}.cookieControl__Bar--top-full-enter,.cookieControl__Bar--top-full-leave-to,.cookieControl__Bar--top-left-enter,.cookieControl__Bar--top-left-leave-to,.cookieControl__Bar--top-right-enter,.cookieControl__Bar--top-right-leave-to{transform:translateY(-100%)}.cookieControl__Bar--bottom-full-enter,.cookieControl__Bar--bottom-full-leave-to,.cookieControl__Bar--bottom-left-enter,.cookieControl__Bar--bottom-left-leave-to,.cookieControl__Bar--bottom-right-enter,.cookieControl__Bar--bottom-right-leave-to{transform:translateY(100%)}.cookieControl__Bar--center-enter,.cookieControl__Bar--center-leave-to{transform:translate(-50%,-50%) scale(.95)}.cookieControl{position:relative;z-index:100000}.cookieControl button{backface-visibility:hidden;border:0;cursor:pointer;font-size:16px;outline:0;padding:12px 20px;transition:background-color .2s,color .2s}.cookieControl__Bar{background-color:var(--cookie-control-barBackground);font-family:Arial,Helvetica Neue,Helvetica,sans-serif;position:fixed}.cookieControl__Bar h2,.cookieControl__Bar p{color:var(--cookie-control-barTextColor);max-width:900px}.cookieControl__Bar h2{font-size:20px;margin:0}.cookieControl__Bar p{font-size:16px;margin:5px 0 0}.cookieControl__Bar button{background-color:var(--cookie-control-barButtonBackground);color:var(--cookie-control-barButtonColor)}.cookieControl__Bar button:hover{background-color:var(--cookie-control-barButtonHoverBackground);color:var(--cookie-control-barButtonHoverColor)}.cookieControl__Bar button:focus{box-shadow:0 0 0 3px var(--cookie-control-focusRingColor)}.cookieControl__Bar button+button{margin-left:10px}.cookieControl__BarContainer{align-items:flex-end;display:flex;justify-content:space-between;padding:20px}.cookieControl__Bar--bottom-full,.cookieControl__Bar--top-full{left:0;right:0}.cookieControl__Bar--top-full{top:0}.cookieControl__Bar--bottom-full{bottom:0}.cookieControl__Bar--bottom-left p,.cookieControl__Bar--bottom-right p,.cookieControl__Bar--center p,.cookieControl__Bar--top-left p,.cookieControl__Bar--top-right p{max-width:400px}.cookieControl__Bar--bottom-left .cookieControl__BarContainer,.cookieControl__Bar--bottom-right .cookieControl__BarContainer,.cookieControl__Bar--center .cookieControl__BarContainer,.cookieControl__Bar--top-left .cookieControl__BarContainer,.cookieControl__Bar--top-right .cookieControl__BarContainer{flex-direction:column}.cookieControl__Bar--bottom-left .cookieControl__BarButtons,.cookieControl__Bar--bottom-right .cookieControl__BarButtons,.cookieControl__Bar--center .cookieControl__BarButtons,.cookieControl__Bar--top-left .cookieControl__BarButtons,.cookieControl__Bar--top-right .cookieControl__BarButtons{margin-top:20px}.cookieControl__Bar--top-left,.cookieControl__Bar--top-right{top:20px}.cookieControl__Bar--bottom-left,.cookieControl__Bar--bottom-right{bottom:20px}.cookieControl__Bar--bottom-left,.cookieControl__Bar--top-left{left:20px}.cookieControl__Bar--bottom-right,.cookieControl__Bar--top-right{right:20px}.cookieControl__BarButtons{display:flex}.cookieControl__Modal{bottom:0;font-size:0;left:0;position:fixed;right:0;text-align:center;top:0;z-index:1}.cookieControl__Modal:before{content:"";display:inline-block;min-height:100vh;vertical-align:middle}.cookieControl__Modal:after{background-color:var(--cookie-control-modalOverlay);bottom:0;content:"";left:0;opacity:var(--cookie-control-modalOverlayOpacity);position:absolute;right:0;top:0;z-index:-1}.cookieControl__Modal>div{font-size:medium}.cookieControl__Modal button{background-color:var(--cookie-control-modalButtonBackground);color:var(--cookie-control-modalButtonColor)}.cookieControl__Modal button:hover{background-color:var(--cookie-control-modalButtonHoverBackground);color:var(--cookie-control-modalButtonHoverColor)}.cookieControl__Modal button:focus{box-shadow:0 0 0 3px var(--cookie-control-focusRingColor)}.cookieControl__ModalContent{background-color:var(--cookie-control-modalBackground);display:inline-block;max-height:80vh;max-width:550px;overflow-y:scroll;position:relative;text-align:left;vertical-align:middle;width:100%}.cookieControl__ModalContent,.cookieControl__ModalContent :not(button){color:var(--cookie-control-modalTextColor)}.cookieControl__ModalContent h2{font-size:24px;margin:15px 0}.cookieControl__ModalContent h2:first-of-type{margin-top:0}.cookieControl__ModalContent ul{font-size:16px;list-style-type:none;padding:0}.cookieControl__ModalContent ul ul{padding:5px 56px 0}.cookieControl__ModalContent ul ul li+li{margin-top:5px}.cookieControl__ModalContent li{align-items:center}.cookieControl__ModalContent li+li{margin-top:20px}.cookieControl__ModalContent input{display:none}.cookieControl__ModalContent input:checked+button{background-color:var(--cookie-control-checkboxActiveBackground)}.cookieControl__ModalContent input:checked+button:before{background-color:var(--cookie-control-checkboxActiveCircleBackground);transform:translate3d(100%,-50%,0)}.cookieControl__ModalContent input:checked:disabled+button{background-color:var(--cookie-control-checkboxDisabledBackground)}.cookieControl__ModalContent input:checked:disabled+button:before{background-color:var(--cookie-control-checkboxDisabledCircleBackground)}.cookieControl__ModalContent input+button{backface-visibility:hidden;background-color:var(--cookie-control-checkboxInactiveBackground);border-radius:20px;display:block;font-size:0;margin-right:20px;min-height:20px;min-width:36px;position:relative;transition:background-color .2s}.cookieControl__ModalContent input+button:before{background-color:var(--cookie-control-checkboxInactiveCircleBackground);border-radius:50%;content:"";height:15px;left:3px;position:absolute;top:50%;transform:translate3d(0,-50%,0);transition:transform .2s;width:15px}.cookieControl__ModalContentInner{display:flex;flex-direction:column;gap:10px;padding:40px}.cookieControl__ModalInputWrapper{align-items:flex-start;display:flex}.cookieControl__ModalCookieName{font-weight:700;text-transform:uppercase}.cookieControl__ModalCookieName span{font-weight:400;text-transform:none}.cookieControl__ModalClose{align-self:flex-end;right:20px;top:20px}.cookieControl__ModalButtons{align-items:stretch;display:flex;gap:20px;margin-top:40px}.cookieControl__ModalUnsaved{bottom:40px;color:var(--cookie-control-modalUnsavedColor);font-size:14px;left:50%;margin:0;position:absolute;transform:translateX(-50%)}.cookieControl__BlockedIframe{border:2px solid #ddd;padding:20px}.cookieControl__BlockedIframe a,.cookieControl__BlockedIframe p{font-family:Arial,Helvetica Neue,Helvetica,sans-serif}@media screen and (max-width:768px){.cookieControl__Bar{flex-direction:column;left:0;right:0}.cookieControl__Bar h2,.cookieControl__Bar p{max-width:100%}.cookieControl__Bar--top-full,.cookieControl__Bar--top-left,.cookieControl__Bar--top-right{top:0}.cookieControl__Bar--bottom-full,.cookieControl__Bar--bottom-left,.cookieControl__Bar--bottom-right{bottom:0}.cookieControl__ModalContent{bottom:0;left:0;max-height:100%;max-width:none;position:absolute;right:0;top:0}.cookieControl__ModalContentInner{padding:20px}.cookieControl__BarButtons{flex-direction:column;justify-content:center;margin-top:20px;width:100%}.cookieControl__BarButtons button{width:100%}.cookieControl__BarButtons button+button{margin:10px 0 0}.cookieControl__BarContainer,.cookieControl__ModalButtons{flex-direction:column;gap:10px}.cookieControl__ModalButtons button{width:100%}}.cookieControl__ControlButton{backface-visibility:hidden;background:var(--cookie-control-controlButtonBackground);border:0;border-radius:50%;box-shadow:0 0 10px rgba(0,0,0,.3);cursor:pointer;height:40px;min-height:40px;min-width:40px;outline:0;position:fixed;transition:background-color .2s;width:40px}.cookieControl__ControlButton--top-left{left:20px;top:20px}.cookieControl__ControlButton--top-right{right:20px;top:20px}.cookieControl__ControlButton--bottom-left{bottom:20px;left:20px}.cookieControl__ControlButton--bottom-right{bottom:20px;right:20px}.cookieControl__ControlButton svg{backface-visibility:hidden;color:var(--cookie-control-controlButtonIconColor);left:50%;max-height:24px;max-width:24px;min-height:24px;min-width:24px;position:absolute;top:50%;transform:translate(-50%,-50%);transition:color .2s}.cookieControl__ControlButton:hover{background-color:var(--cookie-control-controlButtonHoverBackground)}.cookieControl__ControlButton:hover svg{color:var(--cookie-control-controlButtonIconHoverColor)}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -35,6 +35,12 @@ export interface LocaleStrings {
|
|
|
35
35
|
}
|
|
36
36
|
export interface ModuleOptions {
|
|
37
37
|
barPosition: 'top-left' | 'top-right' | 'top-full' | 'bottom-left' | 'bottom-right' | 'bottom-full';
|
|
38
|
+
/**
|
|
39
|
+
* Position of the control button.
|
|
40
|
+
* 'top-left', 'top-right', 'bottom-left' or 'bottom-right'.
|
|
41
|
+
* @default 'bottom-right'
|
|
42
|
+
*/
|
|
43
|
+
controlButtonPosition: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
38
44
|
closeModalOnClickOutside: boolean;
|
|
39
45
|
colors: false | Record<string, unknown>;
|
|
40
46
|
cookieExpiryOffsetMs: number;
|
package/dist/runtime/types.js
CHANGED
package/package.json
CHANGED