Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@oddbird/slide-deck

Package Overview
Dependencies
Maintainers
3
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@oddbird/slide-deck - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

favicon.ico

40

CHANGELOG.md

@@ -7,2 +7,42 @@ # Changes

## v0.1.2 - 2024-01-16
- 💥 BREAKING: Disabled the full-screen keyboard shortcut,
until we have a chance to address the various
fullscreen browser issues
- 💥 BREAKING: Removed the 'end presentation' event
and keyboard shortcuts, which were more confusing than useful
- 💥 BREAKING: Removed the shadow DOM content wrapper,
and all shadow DOM styles for slide layout
- 💥 BREAKING: The `reset` event targets the first slide
rather than the slide-deck container
- 🚀 NEW / 💥 BREAKING: Renamed and added control-panel parts,
to allow for more customization of the default panel
including pressed buttons with `:part(button pressed)`
- 🚀 NEW: Set `aria-current='true'` on active slide
- 🚀 NEW: View settings are maintained across page refresh
using `sessionStorage`
- 🚀 NEW: Add support for slide parts – `slide-canvas` & `slide-note`
- 🚀 NEW: Each slide is labeled with either
`slide-item='container'` (if it has nested parts)
or `slide-item='canvas' slide-canvas` (if there are no nested parts)
- 🚀 NEW: The slide-deck has a `--slide-count` property,
and each slide has a `--slide-index`
- 🚀 NEW: Default styles are in `slide-deck.css`
and can be applied from the light DOM
- 🚀 NEW: The entire control panel can be replaced
from the light DOM using `slot=control-panel`
on a slotted `dialog` element
- 🚀 NEW: Blank slides are implemented as shadow DOM dialogues,
which can be replaced from the light DOM using `slot=blank-slide`
on a slotted `dialog` element
- 🚀 NEW: When `key-control` is activated (including on-load),
we target the stored active slide (or the first slide)
- 🚀 NEW: Support for keyboard shortcuts on Windows/Linux
using `control` instead of `command`
- 🐞 FIXED: Slotted controls are no longer treated as slides
- 🐞 FIXED: When restoring the active slide from memory,
we go to the first slide if there's no stored state
- 🐞 FIXED: Use any key to exit a blank-slide mode
## v0.1.1 - 2023-12-26

@@ -9,0 +49,0 @@

2

package.json
{
"name": "@oddbird/slide-deck",
"version": "0.1.1",
"version": "0.1.2",
"description": "A Web Component for web presentations",

@@ -5,0 +5,0 @@ "main": "slide-deck.js",

@@ -82,4 +82,5 @@ # `slide-deck`

- `command-.`: End presentation
- `command-shift-f`: Toggle full-screen mode
*Windows and Linux users can use Ctrl instead of Command.*
When presenting (key-control is active):

@@ -112,2 +113,3 @@

<!-- Host yourself -->
<link rel="stylesheet" href="slide-deck.css">
<script type="module" src="slide-deck.js"></script>

@@ -118,5 +120,6 @@ ```

<!-- 3rd party CDN, not recommended for production use -->
<link rel="stylesheet" href="https://www.unpkg.com/@oddbird/slide-deck/slide-deck.css">
<script
type="module"
src="https://www.unpkg.com/@oddbird/slide-deck@0.1.0/slide-deck.js"
src="https://www.unpkg.com/@oddbird/slide-deck/slide-deck.js"
></script>

@@ -127,5 +130,6 @@ ```

<!-- 3rd party CDN, not recommended for production use -->
<link rel="stylesheet" href="https://esm.sh/@oddbird/slide-deck/slide-deck.css">
<script
type="module"
src="https://esm.sh/@oddbird/slide-deck@0.1.0"
src="https://esm.sh/@oddbird/slide-deck"
></script>

@@ -132,0 +136,0 @@ ```

class slideDeck extends HTMLElement {
// template
static appendShadowTemplate = (node) => {
static #appendShadowTemplate = (node) => {
const template = document.createElement("template");
template.innerHTML = `
<dialog part="controls">
<form method="dialog"><button>close</button></form>
<div>
<slot name="slide-controls">
<button slide-event='toggleControl'>keyboard controls</button>
<slot></slot>
<slot name="control-panel">
<dialog part="control-panel">
<div part="panel-header">
<strong>Slide-Deck Controls</strong>
<form method="dialog">
<button part="button close-controls">close</button>
</form>
</div>
<div part="controls">
<button part="button" slide-event='toggleControl'>
keyboard navigation
</button>
<hr>
<p><strong>Presentation:</strong></p>
<button slide-event>start</button>
<button slide-event>end</button>
<button slide-event="joinWithNotes">speaker view</button>
<button part="button event" slide-event>
start
</button>
<button part="button event" slide-event>
reset
</button>
<button part="button event" slide-event="joinWithNotes">
speaker view
</button>
<hr>
<p><strong>View:</strong></p>
<button set-view>grid</button>
<button set-view>list</button>
</slot>
</div>
</dialog>
<div part="contents">
<slot></slot>
</div>
<button part="button view" set-view>
grid
</button>
<button part="button view" set-view>
solo
</button>
<button part="button view" set-view>
script
</button>
</div>
</dialog>
</slot>
<slot name="blank-slide">
<dialog part="blank-slide">
<form method="dialog">
<button part="close-blank-slide">
<span aria-label="close">x<span>
</button>
</form>
</dialog>
</slot>
`;

@@ -32,88 +63,34 @@ const shadowRoot = node.attachShadow({ mode: "open" });

// css
static adoptShadowStyles = (node) => {
static #adoptShadowStyles = (node) => {
const shadowStyle = new CSSStyleSheet();
shadowStyle.replaceSync(`
:host {
position: relative;
[part=blank-slide],
::slotted([slot=blank-slide]) {
block-size: 100%;
border: 0;
color-scheme: var(--sd-blank-slide-scheme, dark);
inline-size: 100%;
max-block-size: unset;
max-inline-size: unset;
}
:host:not(:fullscreen) {
container: host / inline-size;
}
[part=blank-slide] {
padding: 0;
:host(:fullscreen) {
background-color: white;
overflow-x: clip;
overflow-y: auto;
&[open] { display: grid; }
form { display: grid; }
}
:host([slide-view=grid]) {
---slide-grid-ratio: 16/9;
---slide-grid-border: var(--slide-grid-border, thin solid);
---slide-grid-active-outline: medium dotted hotpink;
---slide-grid-scroll-margin: clamp(10px, 4cqi, 40px);
---slide-list-border: var(--slide-grid-border, thin solid);
:host([blank-slide=white]) {
--sd-blank-slide-scheme: light;
}
:host([slide-view=list]) {
---slide-list-border: var(--slide-list-border, thin solid);
}
:host([blank-slide])::after {
content: '';
position: absolute;
inset: 0;
background-color: var(--blank-slide-color, black);
}
:host([blank-slide='white'])::after {
--blank-slide-color: white;
}
[part=contents] {
---slide-gap: clamp(5px, 1.5cqi, 15px);
[part=close-blank-slide] {
background: transparent;
border: 0;
color: inherit;
display: grid;
:host([slide-view=grid]) & {
grid-template-columns: var(
--slide-grid-columns,
repeat(auto-fit, minmax(min(50ch, 100%), 1fr))
);
gap: var(--slide-grid-gap, var(---slide-gap));
padding: var(--slide-grid-padding, var(---slide-gap));
}
:host([slide-view=list]) & {
grid-auto-rows: var(--slide-list-rows, 100svh);
}
font: inherit;
place-items: start end;
}
::slotted([id^=slide_]) {
aspect-ratio: var(--slide-grid-ratio, var(---slide-grid-ratio));
container-name: slide;
container-type: var(--slide-container, inline-size);
border: var(---slide-grid-border);
border-block-end: var(---slide-list-border);
padding: var(---slide-gap);
scroll-margin: var(
--slide-grid-scroll-margin,
var(---slide-grid-scroll-margin)
);
}
::slotted([id^=slide_]:target) {
outline: var(
--slide-grid-active-outline,
var(---slide-grid-active-outline)
);
outline-offset: var(--slide-active-outline-offset, 3px);
}
button[aria-pressed=true] {
box-shadow: inset 0 0 2px black;
&::before {
content: ' ✅ ';
}
}
`);

@@ -131,8 +108,14 @@ node.shadowRoot.adoptedStyleSheets = [shadowStyle];

static attrToPropMap = {
'key-control': 'keyControl',
'follow-active': 'followActive',
'full-screen': 'fullScreen',
'slide-view': 'slideView',
};
get keyControl(){
return this.hasAttribute('key-control');
}
get followActive(){
return this.hasAttribute('follow-active');
}
get fullScreen(){
return this.hasAttribute('full-screen');
}
get slideView(){
return this.getAttribute('slide-view');
}

@@ -148,3 +131,4 @@ static storageKeys = [

'grid',
'list',
'solo',
'script',
];

@@ -175,27 +159,28 @@

',': 'whiteOut',
// end
'-': 'endPresentation'
}
// dynamic
store = {};
#store = {};
slides;
slideCount;
controlPanel;
eventButtons;
viewButtons;
activeSlide;
body;
#controlPanel;
#blankSlide;
#eventButtons;
#viewButtons;
#body;
// callbacks
attributeChangedCallback(name, oldValue, newValue) {
this[slideDeck.attrToPropMap[name]] = newValue || this.hasAttribute(name);
attributeChangedCallback(name) {
switch (name) {
case 'key-control':
this.#keyControlChange();
break;
case 'follow-active':
this.followActiveChange();
this.#followActiveChange();
this.#updateEventButtons();
break;
case 'slide-view':
this.updateViewButtons();
this.scrollToActive();
this.#onViewChange();
break;

@@ -206,3 +191,3 @@ default:

this.updateEventButtons();
this.#updateEventButtons();
}

@@ -214,30 +199,39 @@

// shadow dom and ID
slideDeck.appendShadowTemplate(this);
slideDeck.adoptShadowStyles(this);
this.setDeckID();
slideDeck.#appendShadowTemplate(this);
slideDeck.#adoptShadowStyles(this);
this.#setDeckID();
// relevant nodes
this.body = document.querySelector('body');
this.controlPanel = this.shadowRoot.querySelector(`[part="controls"]`);
this.#body = document.querySelector('body');
this.#controlPanel = this.querySelector(`[slot="control-panel"]`) ??
this.shadowRoot.querySelector(`[part="control-panel"]`);
this.#blankSlide = this.querySelector(`[slot="blank-slide"]`) ??
this.shadowRoot.querySelector(`[part="blank-slide"]`);
// initial setup
this.slideCount = this.childElementCount;
this.defaultAttrs();
this.setSlideIDs();
this.#defaultAttrs();
this.#setupSlides();
this.goTo();
// buttons
this.setupEventButtons();
this.setupViewButtons();
this.#setupEventButtons();
this.#setupViewButtons();
// event listeners
// shadow DOM event listeners
this.shadowRoot.addEventListener('keydown', (event) => {
event.stopPropagation();
if ((event.key === 'k' && event.metaKey) || event.key === 'Escape') {
if (this.hasAttribute('blank-slide')) {
event.preventDefault();
this.controlPanel.close();
this.blankSlideEvent();
} else if ((event.key === 'k' && this.#cmdOrCtrl(event)) || event.key === 'Escape') {
event.preventDefault();
this.#controlPanel.close();
}
});
this.#blankSlide.addEventListener('close', (event) => {
this.removeAttribute('blank-slide');
})
// custom events

@@ -247,5 +241,2 @@ this.addEventListener('toggleControl', (e) => this.toggleAttribute('key-control'));

this.addEventListener('toggleFullscreen', (e) => this.fullScreenEvent());
this.addEventListener('toggleView', (e) => this.toggleView());
this.addEventListener('grid', (e) => this.toggleView('grid'));
this.addEventListener('list', (e) => this.toggleView('list'));

@@ -256,21 +247,20 @@ this.addEventListener('join', (e) => this.joinEvent());

this.addEventListener('resume', (e) => this.resumeEvent());
this.addEventListener('end', (e) => this.endEvent());
this.addEventListener('reset', (e) => this.resetEvent());
this.addEventListener('blankSlide', (e) => this.blankSlideEvent());
this.addEventListener('nextSlide', (e) => this.move(1));
this.addEventListener('next', (e) => this.move(1));
this.addEventListener('savedSlide', (e) => this.goToSaved());
this.addEventListener('previousSlide', (e) => this.move(-1));
this.addEventListener('previous', (e) => this.move(-1));
};
connectedCallback() {
this.body.addEventListener('keydown', this.keyEventActions);
this.#body.addEventListener('keydown', this.#keyEventActions);
}
disconnectedCallback() {
this.body.removeEventListener('keydown', this.keyEventActions);
this.#body.removeEventListener('keydown', this.#keyEventActions);
}
// setup methods
newDeckId = (from, count) => {
#newDeckId = (from, count) => {
const base = from || window.location.pathname.split('.')[0];

@@ -280,3 +270,3 @@ const ID = count ? `${base}-${count}` : base;

if (document.getElementById(ID)) {
return this.newDeckId(base, (count || 0) + 1);
return this.#newDeckId(base, (count || 0) + 1);
}

@@ -287,25 +277,46 @@

setDeckID = () => {
this.id = this.id || this.newDeckId();
#setDeckID = () => {
this.id = this.id || this.#newDeckId();
// storage keys based on slide ID
slideDeck.storageKeys.forEach((key) => {
this.store[key] = `${this.id}.${key}`;
this.#store[key] = `${this.id}.${key}`;
});
}
slideId = (n) => `slide_${this.id}-${n}`;
#slideId = (n) => `slide_${this.id}-${n}`;
setSlideIDs = () => {
const slides = this.querySelectorAll(':scope > *');
#setupSlides = () => {
this.slides = this.querySelectorAll(':scope > :not([slot])');
this.slideCount = this.slides.length;
this.style.setProperty('--slide-count', this.slideCount);
slides.forEach((slide, index) => {
slide.id = this.slideId(index + 1);
this.slides.forEach((slide, index) => {
const slideIndex = index + 1;
slide.id = this.#slideId(slideIndex);
slide.style.setProperty('--slide-index', slideIndex);
if (slide.querySelector(':scope [slide-canvas]')) {
if (!slide.hasAttribute('slide-item')) {
slide.setAttribute('slide-item', 'container');
}
} else {
if (!slide.hasAttribute('slide-item')) {
slide.setAttribute('slide-item', 'canvas');
}
if (!slide.hasAttribute('slide-canvas')) {
slide.toggleAttribute('slide-canvas', true);
}
}
});
};
defaultAttrs = () => {
#defaultAttrs = () => {
// view required
if (!this.hasAttribute('slide-view')) {
this.setAttribute('slide-view', 'grid');
if (!this.slideView) {
this.setAttribute(
'slide-view',
sessionStorage.getItem(this.#store.view) || 'grid'
);
}

@@ -318,57 +329,84 @@

// buttons
getButtonEvent = (btn) => btn.getAttribute('slide-event') || btn.innerText;
#findButtons = (attr) => [
...this.querySelectorAll(`:scope button[${attr}]`),
...this.shadowRoot.querySelectorAll(`button[${attr}]`),
];
updateEventButtons = () => {
this.eventButtons.forEach((btn) => {
const btnEvent = this.getButtonEvent(btn);
let isActive = {
'toggleControl': this.keyControl,
'toggleFollow': this.followActive,
'toggleFullscreen': this.fullScreen,
#getButtonValue = (btn, attr) => btn.getAttribute(attr) || btn.innerText;
#setButtonPressed = (btn, isPressed) => {
btn.setAttribute('aria-pressed', isPressed);
if (btn.hasAttribute('part')) {
const currentNames = btn.getAttribute('part').split(' ');
let newNames;
if (isPressed) {
newNames = currentNames.includes('pressed')
? currentNames
: [...currentNames, 'pressed'];
} else if (!isPressed) {
newNames = currentNames.filter((name) => name !== 'pressed')
}
if (Object.keys(isActive).includes(btnEvent)) {
btn.setAttribute('aria-pressed', isActive[btnEvent]);
}
});
btn.setAttribute('part', newNames.join(' '));
}
}
setupEventButtons = () => {
this.eventButtons = [
...this.querySelectorAll(`button[slide-event]`),
...this.shadowRoot.querySelectorAll(`button[slide-event]`),
];
#setToggleState = (btn, attr, state) => {
const isActive = this.#getButtonValue(btn, attr) === state;
this.#setButtonPressed(btn, isActive);
}
this.eventButtons.forEach((btn) => {
#setupViewButtons = () => {
this.#viewButtons = this.#findButtons('set-view');
this.#viewButtons.forEach((btn) => {
btn.addEventListener('click', (e) => {
const event = this.getButtonEvent(btn);
this.dispatchEvent(new Event(event, { view: window, bubbles: false }));
this.setAttribute('slide-view', this.#getButtonValue(btn, 'set-view'));
});
this.#setToggleState(btn, 'set-view', this.slideView);
});
}
this.updateEventButtons();
#updateViewButtons = () => {
this.#viewButtons.forEach((btn) => {
this.#setToggleState(btn, 'set-view', this.slideView);
});
}
getButtonView = (btn) => btn.getAttribute('set-view') || btn.innerText;
// attribute changes
#onViewChange = () => {
this.#updateViewButtons();
this.scrollToActive();
sessionStorage.setItem(this.#store.view, this.slideView);
}
setupViewButtons = () => {
this.viewButtons = [
...this.querySelectorAll(`button[set-view]`),
...this.shadowRoot.querySelectorAll(`button[set-view]`),
];
// event buttons
#setupEventButtons = () => {
this.#eventButtons = this.#findButtons('slide-event');
this.viewButtons.forEach((btn) => {
this.#eventButtons.forEach((btn) => {
btn.addEventListener('click', (e) => {
this.setAttribute('slide-view', this.getButtonView(btn));
const event = this.#getButtonValue(btn, 'slide-event');
this.dispatchEvent(new Event(event, { view: window, bubbles: false }));
});
});
this.slideView = this.slideView || this.getAttribute('slide-view');
this.updateViewButtons();
this.#updateEventButtons();
}
updateViewButtons = () => {
this.viewButtons.forEach((btn) => {
const isActive = this.getButtonView(btn) === this.slideView;
btn.setAttribute('aria-pressed', isActive);
#updateEventButtons = () => {
this.#eventButtons.forEach((btn) => {
const btnEvent = this.#getButtonValue(btn, 'slide-event');
let isActive = {
'toggleControl': this.keyControl,
'toggleFollow': this.followActive,
'toggleFullscreen': this.fullScreen,
}
if (Object.keys(isActive).includes(btnEvent)) {
this.#setButtonPressed(btn, isActive[btnEvent]);
}
});

@@ -378,11 +416,6 @@ }

// event handlers
toggleView = (to) => {
if (!to) {
const current = this.getAttribute('slide-view');
const l = slideDeck.slideViews - 1; // adjust for 0-index
const i = slideDeck.slideViews.indexOf(current);
const next = slideDeck.slideViews[(i + 1) % l];
}
this.setAttribute('slide-view', to || next || 'grid');
#startPresenting = () => {
this.setAttribute('slide-view', 'solo');
this.setAttribute('key-control', '');
this.setAttribute('follow-active', '');
}

@@ -392,3 +425,3 @@

this.goTo(1);
this.startPresenting();
this.#startPresenting();
}

@@ -398,13 +431,7 @@

this.goToSaved();
this.startPresenting();
this.#startPresenting();
}
startPresenting = () => {
this.setAttribute('slide-view', 'list');
this.setAttribute('key-control', '');
this.setAttribute('follow-active', '');
}
joinWithNotesEvent = () => {
this.setAttribute('slide-view', 'grid');
this.setAttribute('slide-view', 'script');
this.setAttribute('key-control', '');

@@ -419,18 +446,12 @@ this.setAttribute('follow-active', '');

endEvent = () => {
this.setAttribute('slide-view', 'grid');
this.removeAttribute('key-control');
this.removeAttribute('follow-active');
this.resetEvent();
}
resetEvent = () => {
window.location.hash = this.id;
this.resetActive();
this.goTo(1);
}
blankSlideEvent = (color) => {
if (this.hasAttribute('blank-slide')) {
if (this.#blankSlide.open) {
this.#blankSlide.close();
this.removeAttribute('blank-slide');
} else {
this.#blankSlide.showModal();
this.setAttribute('blank-slide', color || 'black');

@@ -451,3 +472,9 @@ }

// dynamic attribute methods
followActiveChange = () => {
#keyControlChange = () => {
if (this.keyControl) {
this.goToSaved();
}
}
#followActiveChange = () => {
if (this.followActive) {

@@ -462,21 +489,23 @@ this.goToSaved();

// storage
asSlideInt = (string) => parseInt(string, 10);
#asSlideInt = (string) => parseInt(string, 10);
#indexFromId = (string) => this.#asSlideInt(string.split('-').pop());
slideFromHash = () => window.location.hash.startsWith('#slide_')
? this.asSlideInt(window.location.hash.split('-').pop())
#slideFromHash = () => window.location.hash.startsWith('#slide_')
? this.#indexFromId(window.location.hash)
: null;
slideFromStore = () => this.asSlideInt(
localStorage.getItem(this.store.slide)
);
slideToHash = (to) => {
#slideFromStore = (fallback = 1) => this.#asSlideInt(
localStorage.getItem(this.#store.slide)
) || fallback;
#slideToHash = (to) => {
if (to) {
window.location.hash = this.slideId(to);
window.location.hash = this.#slideId(to);
}
};
slideToStore = (to) => {
#slideToStore = (to) => {
if (to) {
localStorage.setItem(this.store.slide, to);
localStorage.setItem(this.#store.slide, to);
} else {
localStorage.removeItem(this.store.slide);
localStorage.removeItem(this.#store.slide);
}

@@ -486,7 +515,7 @@ };

// navigation
inRange = (slide) => slide >= 1 && slide <= this.slideCount;
getActive = () => this.slideFromHash() || this.activeSlide;
#inRange = (slide) => slide >= 1 && slide <= this.slideCount;
#getActive = () => this.#slideFromHash() || this.activeSlide;
scrollToActive = () => {
const activeEl = document.getElementById(this.slideId(this.activeSlide));
const activeEl = document.getElementById(this.#slideId(this.activeSlide));

@@ -499,23 +528,26 @@ if (activeEl) {

goTo = (to) => {
const fromHash = this.slideFromHash();
const setTo = to || this.getActive();
const fromHash = this.#slideFromHash();
const setTo = to || this.#getActive();
if (setTo && this.inRange(setTo)) {
if (setTo && this.#inRange(setTo)) {
this.activeSlide = setTo;
this.slideToStore(setTo);
this.#slideToStore(setTo);
if (setTo !== fromHash) {
this.slideToHash(setTo);
this.#slideToHash(setTo);
}
// update aria-current
this.querySelectorAll(
':scope [slide-item][aria-current]'
).forEach((slide) => {
slide.removeAttribute('aria-current');
});
this.querySelector(`:scope #${this.#slideId(setTo)}`).setAttribute('aria-current', 'true');
}
}
resetActive = () => {
this.activeSlide = null;
window.location.hash = this.id;
localStorage.removeItem(this.store.slide);
};
move = (by) => {
const to = (this.getActive() || 0) + by;
const to = (this.#getActive() || 0) + by;
this.goTo(to);

@@ -525,19 +557,23 @@ };

goToSaved = () => {
this.goTo(this.slideFromStore());
this.goTo(this.#slideFromStore());
}
keyEventActions = (event) => {
// Detect Ctrl / Cmd modifiers in a platform-agnostic way
#cmdOrCtrl = (event) => event.ctrlKey || event.metaKey;
#keyEventActions = (event) => {
// exit from blank slide
if (this.hasAttribute('blank-slide')) {
event.preventDefault();
this.removeAttribute('blank-slide');
return;
}
// always available
if (event.metaKey) {
if (this.#cmdOrCtrl(event)) {
switch (event.key) {
case 'k':
event.preventDefault();
this.controlPanel.showModal();
this.#controlPanel.showModal();
break;
case 'f':
if (event.shiftKey) {
event.preventDefault();
this.fullScreenEvent();
}
break;
case 'Enter':

@@ -552,6 +588,3 @@ if (event.shiftKey) {

break;
case '.':
event.preventDefault();
this.endEvent();
break;
default:

@@ -570,7 +603,4 @@ break;

if (event.key === 'Escape') {
if (event.target !== this.body) {
if (event.target !== this.#body) {
event.target.blur();
} else {
event.preventDefault();
this.endEvent();
}

@@ -605,6 +635,2 @@ return;

break;
case 'endPresentation':
event.preventDefault();
this.endEvent();
break;
default:

@@ -611,0 +637,0 @@ break;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc