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

videojs-hotkeys

Package Overview
Dependencies
Maintainers
0
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

videojs-hotkeys - npm Package Compare versions

Comparing version 0.2.28 to 0.2.29

60

index.d.ts

@@ -1,41 +0,41 @@

import { VideoJsPlayer } from 'video.js';
import VideoJsPlayer from "video.js/dist/types/player";
declare module 'video.js' {
interface VideoJsPlayer {
hotkeys(options?: VideoJsHotkeysOptions): void;
}
declare module "video.js/dist/types/player" {
export default interface VideoJsPlayer {
hotkeys(options?: VideoJsHotkeysOptions): void;
}
}
export interface VideoJsHotkeysOptions {
volumeStep?: number;
seekStep?: number;
enableMute?: boolean;
enableVolumeScroll?: boolean;
enableHoverScroll?: boolean;
enableFullscreen?: boolean;
enableNumbers?: boolean;
enableModifiersForNumbers?: boolean;
alwaysCaptureHotkeys?: boolean;
enableInactiveFocus?: boolean;
skipInitialFocus?: boolean;
captureDocumentHotkeys?: boolean;
documentHotkeysFocusElementFilter?: (element: HTMLElement) => boolean;
enableJogStyle?: boolean;
playPauseKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
rewindKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
forwardKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
volumeUpKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
volumeDownKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
muteKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
fullscreenKey?: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
customKeys?: VideoJsCustomHotkeyOptions;
volumeStep?: number | undefined;
seekStep?: number | undefined;
enableMute?: boolean | undefined;
enableVolumeScroll?: boolean | undefined;
enableHoverScroll?: boolean | undefined;
enableFullscreen?: boolean | undefined;
enableNumbers?: boolean | undefined;
enableModifiersForNumbers?: boolean | undefined;
alwaysCaptureHotkeys?: boolean | undefined;
enableInactiveFocus?: boolean | undefined;
skipInitialFocus?: boolean | undefined;
captureDocumentHotkeys?: boolean | undefined;
documentHotkeysFocusElementFilter?: ((element: HTMLElement) => boolean) | undefined;
enableJogStyle?: boolean | undefined;
playPauseKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
rewindKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
forwardKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
volumeUpKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
volumeDownKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
muteKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
fullscreenKey?: ((event: KeyboardEvent, player: VideoJsPlayer) => boolean) | undefined;
customKeys?: VideoJsCustomHotkeyOptions | undefined;
}
export interface VideoJsCustomHotkeyOptions {
[key: string]: VideoJsCustomHotkey;
[key: string]: VideoJsCustomHotkey;
}
export interface VideoJsCustomHotkey {
key: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
handler: (player: VideoJsPlayer, options: VideoJsHotkeysOptions, event: KeyboardEvent) => void;
key: (event: KeyboardEvent, player: VideoJsPlayer) => boolean;
handler: (player: VideoJsPlayer, options: VideoJsHotkeysOptions, event: KeyboardEvent) => void;
}

@@ -0,0 +0,0 @@ Apache License

{
"name": "videojs-hotkeys",
"version": "0.2.28",
"description": "Adds more hotkey support to video.js",
"author": "Chris Dougherty",
"license": "Apache-2.0",
"main": "videojs.hotkeys.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/ctd1500/videojs-hotkeys.git"
},
"bugs": {
"url": "https://github.com/ctd1500/videojs-hotkeys/issues"
},
"homepage": "https://github.com/ctd1500/videojs-hotkeys",
"keywords": [
"videojs",
"videojs-plugin",
"hotkeys"
],
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-clean": "^1.1.0",
"grunt-contrib-compress": "^1.4.3",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-uglify": "^3.0.1",
"grunt-github-releaser2": "^0.1.1",
"time-grunt": "^1.4.0"
},
"scripts": {
"build": "grunt",
"release": "grunt release"
}
"name": "videojs-hotkeys",
"version": "0.2.29",
"description": "Adds more hotkey support to video.js",
"author": "Chris Dougherty",
"license": "Apache-2.0",
"main": "videojs.hotkeys.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/ctd1500/videojs-hotkeys.git"
},
"bugs": {
"url": "https://github.com/ctd1500/videojs-hotkeys/issues"
},
"homepage": "https://github.com/ctd1500/videojs-hotkeys",
"keywords": [
"videojs",
"videojs-plugin",
"hotkeys"
],
"devDependencies": {
"grunt": "^1.6.1",
"grunt-contrib-clean": "^2.0.1",
"grunt-contrib-compress": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-uglify": "^5.2.2",
"grunt-github-releaser2": "^0.1.1",
"time-grunt": "^1.4.0"
},
"scripts": {
"build": "grunt",
"release": "grunt release"
},
"packageManager": "pnpm@9.12.0+sha512.4abf725084d7bcbafbd728bfc7bee61f2f791f977fd87542b3579dcb23504d170d46337945e4c66485cd12d588a0c0e570ed9c477e7ccdd8507cf05f3f92eaca"
}

@@ -1,5 +0,5 @@

videojs-hotkeys
========================
# videojs-hotkeys
>---
> ---
- **[Introduction](#introduction)**

@@ -16,3 +16,3 @@ - **[Usage](#usage)**

>---
> ---

@@ -22,13 +22,14 @@ ## Introduction

A plugin for Video.js that enables keyboard hotkeys when the player has focus.
* Space bar toggles play/pause.
* Right and Left Arrow keys seek the video forwards and back.
* Up and Down Arrow keys increase and decrease the volume.
* M key toggles mute/unmute.
* F key toggles fullscreen off and on. (Does not work in Internet Explorer, it seems to be a limitation where scripts
cannot request fullscreen without a mouse click)
* Double-clicking with the mouse toggles fullscreen off and on.
* Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%.
- Space bar toggles play/pause.
- Right and Left Arrow keys seek the video forwards and back.
- Up and Down Arrow keys increase and decrease the volume.
- M key toggles mute/unmute.
- F key toggles fullscreen off and on. (Does not work in Internet Explorer, it seems to be a limitation where scripts
cannot request fullscreen without a mouse click)
- Double-clicking with the mouse toggles fullscreen off and on.
- Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%.
**Note: clicking any of the control buttons such as Play/Pause, Fullscreen, or Mute, will remove focus on the player
which appears to "break" the hotkeys. This is for accessibility reasons so that people who do not use or know about
which appears to "break" the hotkeys. This is for accessibility reasons so that people who do not use or know about
the hotkeys can still properly use the `Tab` key to highlight the control buttons and press `space` to toggle them.**

@@ -44,10 +45,15 @@

## Usage
Include the plugin:
### CDN version
You can either load the current release:
```html
<script src="//cdn.sc.gl/videojs-hotkeys/0.2/videojs.hotkeys.min.js"></script>
```
Or always load the latest version:
```html

@@ -58,3 +64,5 @@ <script src="//cdn.sc.gl/videojs-hotkeys/latest/videojs.hotkeys.min.js"></script>

### Yarn / npm package
You can install the package:
```sh

@@ -67,2 +75,3 @@ yarn add videojs-hotkeys

Import it into your project:
```js

@@ -73,2 +82,3 @@ import "videojs-hotkeys";

### Self hosted
```html

@@ -79,23 +89,27 @@ <script src="/path/to/videojs.hotkeys.js"></script>

### Enable the plugin
Add hotkeys to your Videojs ready function.
Check the [Options](#options) section below for the available options and their meaning.
```js
videojs('vidId', {
plugins: {
hotkeys: {
volumeStep: 0.1,
seekStep: 5,
enableModifiersForNumbers: false
},
},
videojs("vidId", {
plugins: {
hotkeys: {
volumeStep: 0.1,
seekStep: 5,
enableModifiersForNumbers: false,
},
},
});
```
or
```js
videojs('vidId').ready(function() {
this.hotkeys({
volumeStep: 0.1,
seekStep: 5,
enableModifiersForNumbers: false
});
videojs("vidId").ready(function () {
this.hotkeys({
volumeStep: 0.1,
seekStep: 5,
enableModifiersForNumbers: false,
});
});

@@ -115,3 +129,3 @@ ```

- `alwaysCaptureHotkeys` (boolean): Forces the capture of hotkeys, even when control elements are focused.
The **Enter**/**Return** key may be used instead to activate the control elements. (default: `false`) (**Note:** This feature may break accessibility, and cause unexpected behavior)
The **Enter**/**Return** key may be used instead to activate the control elements. (default: `false`) (**Note:** This feature may break accessibility, and cause unexpected behavior)
- `enableInactiveFocus` (boolean): This reassigns focus to the player when the control bar fades out after a user has clicked a button on the control bar (default: `true`)

@@ -122,5 +136,5 @@ - `skipInitialFocus` (boolean): This stops focusing the player on initial Play under unique autoplay situations. More information in [Issue #44](https://github.com/ctd1500/videojs-hotkeys/issues/44) (default: `false`)

- `enableJogStyle` (boolean): Enables seeking the video in a broadcast-style jog by pressing the Up and Down Arrow keys.
`seekStep` will also need to be changed to get a proper broadcast-style jog.
This feature and the changes for seekStep are explained a bit more in [PR #12](https://github.com/ctd1500/videojs-hotkeys/pull/12) (default `false`)
(**Note:** This isn't a feature for everyone, and enabling JogStyle will disable the volume hotkeys)
`seekStep` will also need to be changed to get a proper broadcast-style jog.
This feature and the changes for seekStep are explained a bit more in [PR #12](https://github.com/ctd1500/videojs-hotkeys/pull/12) (default `false`)
(**Note:** This isn't a feature for everyone, and enabling JogStyle will disable the volume hotkeys)

@@ -131,3 +145,3 @@ **There are more options specifically for customizing hotkeys described below.**

There are 2 methods available here. Simply overriding existing hotkeys, and creating new custom hotkeys.
There are 2 methods available here. Simply overriding existing hotkeys, and creating new custom hotkeys.

@@ -151,13 +165,14 @@ ### Override existing hotkeys

Example usage:
```js
videojs('vidId', {
plugins: {
hotkeys: {
volumeStep: 0.1,
fullscreenKey: function(event, player) {
// override fullscreen to trigger when pressing the F key or Ctrl+Enter
return ((event.which === 70) || (event.ctrlKey && event.which === 13));
}
},
},
videojs("vidId", {
plugins: {
hotkeys: {
volumeStep: 0.1,
fullscreenKey: function (event, player) {
// override fullscreen to trigger when pressing the F key or Ctrl+Enter
return event.which === 70 || (event.ctrlKey && event.which === 13);
},
},
},
});

@@ -168,35 +183,37 @@ ```

- `customKeys` (object): Create an object containing 1 or more sub-objects. Each sub-object must contain a `key` function and `handler` function
- `key` (function): This function checks if the chosen keys were pressed. It **must** return a boolean, `true` if the keys match.
- `handler` (function): This function runs your custom code if the result of the `key` function was `true`.
- `customKeys` (object): Create an object containing 1 or more sub-objects. Each sub-object must contain a `key` function and `handler` function
- `key` (function): This function checks if the chosen keys were pressed. It **must** return a boolean, `true` if the keys match.
- `handler` (function): This function runs your custom code if the result of the `key` function was `true`.
```js
videojs('vidId', {
plugins: {
hotkeys: {
volumeStep: 0.1,
customKeys: {
// Create custom hotkeys
ctrldKey: {
key: function(event) {
// Toggle something with CTRL + D Key
return (event.ctrlKey && event.which === 68);
},
handler: function(player, options, event) {
// Using mute as an example
if (options.enableMute) {
player.muted(!player.muted());
}
}
}
}
},
},
videojs("vidId", {
plugins: {
hotkeys: {
volumeStep: 0.1,
customKeys: {
// Create custom hotkeys
ctrldKey: {
key: function (event) {
// Toggle something with CTRL + D Key
return event.ctrlKey && event.which === 68;
},
handler: function (player, options, event) {
// Using mute as an example
if (options.enableMute) {
player.muted(!player.muted());
}
},
},
},
},
},
});
```
There are more usage examples available in the source code of the [example file](https://github.com/ctd1500/videojs-hotkeys/blob/master/example.html).
***
---
[<img src="https://cdn.sc.gl/img/browserstack.svg" width="200">](https://www.browserstack.com)
Thanks to [BrowserStack](https://www.browserstack.com) for sponsoring cross-browser compatibility and feature testing.

@@ -9,438 +9,442 @@ /*

;(function(root, factory) {
if (typeof window !== 'undefined' && window.videojs) {
factory(window.videojs);
} else if (typeof define === 'function' && define.amd) {
define('videojs-hotkeys', ['video.js'], function (module) {
return factory(module.default || module);
});
} else if (typeof module !== 'undefined' && module.exports) {
var videojs = require('video.js');
module.exports = factory(videojs.default || videojs);
}
}(this, function (videojs) {
"use strict";
if (typeof window !== 'undefined') {
window['videojs_hotkeys'] = { version: "0.2.28" };
}
(function (root, factory) {
if (typeof window !== "undefined" && window.videojs) {
factory(window.videojs);
} else if (typeof define === "function" && define.amd) {
define("videojs-hotkeys", ["video.js"], function (module) {
return factory(module.default || module);
});
} else if (typeof module !== "undefined" && module.exports) {
var videojs = require("video.js");
module.exports = factory(videojs.default || videojs);
}
})(this, function (videojs) {
"use strict";
if (typeof window !== "undefined") {
window["videojs_hotkeys"] = { version: "0.2.29" };
}
var hotkeys = function(options) {
var player = this;
var pEl = player.el();
var doc = document;
var def_options = {
volumeStep: 0.1,
seekStep: 5,
enableMute: true,
enableVolumeScroll: true,
enableHoverScroll: false,
enableFullscreen: true,
enableNumbers: true,
enableJogStyle: false,
alwaysCaptureHotkeys: false,
captureDocumentHotkeys: false,
documentHotkeysFocusElementFilter: function () { return false },
enableModifiersForNumbers: true,
enableInactiveFocus: true,
skipInitialFocus: false,
playPauseKey: playPauseKey,
rewindKey: rewindKey,
forwardKey: forwardKey,
volumeUpKey: volumeUpKey,
volumeDownKey: volumeDownKey,
muteKey: muteKey,
fullscreenKey: fullscreenKey,
customKeys: {}
};
var hotkeys = function (options) {
var player = this;
var pEl = player.el();
var doc = document;
var def_options = {
volumeStep: 0.1,
seekStep: 5,
enableMute: true,
enableVolumeScroll: true,
enableHoverScroll: false,
enableFullscreen: true,
enableNumbers: true,
enableJogStyle: false,
alwaysCaptureHotkeys: false,
captureDocumentHotkeys: false,
documentHotkeysFocusElementFilter: function () {
return false;
},
enableModifiersForNumbers: true,
enableInactiveFocus: true,
skipInitialFocus: false,
playPauseKey: playPauseKey,
rewindKey: rewindKey,
forwardKey: forwardKey,
volumeUpKey: volumeUpKey,
volumeDownKey: volumeDownKey,
muteKey: muteKey,
fullscreenKey: fullscreenKey,
customKeys: {},
};
var cPlay = 1,
cRewind = 2,
cForward = 3,
cVolumeUp = 4,
cVolumeDown = 5,
cMute = 6,
cFullscreen = 7;
var cPlay = 1,
cRewind = 2,
cForward = 3,
cVolumeUp = 4,
cVolumeDown = 5,
cMute = 6,
cFullscreen = 7;
// Use built-in merge function from Video.js v5.0+ or v4.4.0+
var mergeOptions = videojs.mergeOptions || videojs.util.mergeOptions;
options = mergeOptions(def_options, options || {});
// Use built-in merge function from Video.js v5.0+ or v4.4.0+
var mergeOptions = videojs.obj.merge ||videojs.mergeOptions || videojs.util.mergeOptions;
options = mergeOptions(def_options, options || {});
var volumeStep = options.volumeStep,
seekStep = options.seekStep,
enableMute = options.enableMute,
enableVolumeScroll = options.enableVolumeScroll,
enableHoverScroll = options.enableHoverScroll,
enableFull = options.enableFullscreen,
enableNumbers = options.enableNumbers,
enableJogStyle = options.enableJogStyle,
alwaysCaptureHotkeys = options.alwaysCaptureHotkeys,
captureDocumentHotkeys = options.captureDocumentHotkeys,
documentHotkeysFocusElementFilter = options.documentHotkeysFocusElementFilter,
enableModifiersForNumbers = options.enableModifiersForNumbers,
enableInactiveFocus = options.enableInactiveFocus,
skipInitialFocus = options.skipInitialFocus;
var volumeStep = options.volumeStep,
seekStep = options.seekStep,
enableMute = options.enableMute,
enableVolumeScroll = options.enableVolumeScroll,
enableHoverScroll = options.enableHoverScroll,
enableFull = options.enableFullscreen,
enableNumbers = options.enableNumbers,
enableJogStyle = options.enableJogStyle,
alwaysCaptureHotkeys = options.alwaysCaptureHotkeys,
captureDocumentHotkeys = options.captureDocumentHotkeys,
documentHotkeysFocusElementFilter = options.documentHotkeysFocusElementFilter,
enableModifiersForNumbers = options.enableModifiersForNumbers,
enableInactiveFocus = options.enableInactiveFocus,
skipInitialFocus = options.skipInitialFocus;
var videojsVer = videojs.VERSION;
var videojsVer = videojs.VERSION;
// Set default player tabindex to handle keydown and doubleclick events
if (!pEl.hasAttribute('tabIndex')) {
pEl.setAttribute('tabIndex', '-1');
}
// Set default player tabindex to handle keydown and doubleclick events
if (!pEl.hasAttribute("tabIndex")) {
pEl.setAttribute("tabIndex", "-1");
}
// Remove player outline to fix video performance issue
pEl.style.outline = "none";
// Remove player outline to fix video performance issue
pEl.style.outline = "none";
if (alwaysCaptureHotkeys || !player.autoplay()) {
if (!skipInitialFocus) {
player.one('play', function() {
pEl.focus(); // Fixes the .vjs-big-play-button handing focus back to body instead of the player
});
}
}
if (alwaysCaptureHotkeys || !player.autoplay()) {
if (!skipInitialFocus) {
player.one("play", function () {
pEl.focus(); // Fixes the .vjs-big-play-button handing focus back to body instead of the player
});
}
}
if (enableInactiveFocus) {
player.on('userinactive', function() {
// When the control bar fades, re-apply focus to the player if last focus was a control button
var cancelFocusingPlayer = function() {
clearTimeout(focusingPlayerTimeout);
};
var focusingPlayerTimeout = setTimeout(function() {
player.off('useractive', cancelFocusingPlayer);
var activeElement = doc.activeElement;
var controlBar = pEl.querySelector('.vjs-control-bar');
if (activeElement && activeElement.parentElement == controlBar) {
pEl.focus();
}
}, 10);
if (enableInactiveFocus) {
player.on("userinactive", function () {
// When the control bar fades, re-apply focus to the player if last focus was a control button
var cancelFocusingPlayer = function () {
clearTimeout(focusingPlayerTimeout);
};
var focusingPlayerTimeout = setTimeout(function () {
player.off("useractive", cancelFocusingPlayer);
var activeElement = doc.activeElement;
var controlBar = pEl.querySelector(".vjs-control-bar");
if (activeElement && activeElement.parentElement == controlBar) {
pEl.focus();
}
}, 10);
player.one('useractive', cancelFocusingPlayer);
});
}
player.one("useractive", cancelFocusingPlayer);
});
}
player.on('play', function() {
// Fix allowing the YouTube plugin to have hotkey support.
var ifblocker = pEl.querySelector('.iframeblocker');
if (ifblocker && ifblocker.style.display === '') {
ifblocker.style.display = "block";
ifblocker.style.bottom = "39px";
}
});
player.on("play", function () {
// Fix allowing the YouTube plugin to have hotkey support.
var ifblocker = pEl.querySelector(".iframeblocker");
if (ifblocker && ifblocker.style.display === "") {
ifblocker.style.display = "block";
ifblocker.style.bottom = "39px";
}
});
var keyDown = function keyDown(event) {
var ewhich = event.which, wasPlaying, seekTime;
var ePreventDefault = event.preventDefault.bind(event);
var duration = player.duration();
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
var keyDown = function keyDown(event) {
var ewhich = event.which,
wasPlaying,
seekTime;
var ePreventDefault = event.preventDefault.bind(event);
var duration = player.duration();
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
// Don't catch keys if any control buttons are focused, unless alwaysCaptureHotkeys is true
var activeEl = doc.activeElement;
if (
alwaysCaptureHotkeys ||
(captureDocumentHotkeys && documentHotkeysFocusElementFilter(activeEl)) ||
activeEl == pEl ||
activeEl == pEl.querySelector(".vjs-tech") ||
activeEl == pEl.querySelector(".vjs-control-bar") ||
activeEl == pEl.querySelector(".iframeblocker")
) {
switch (checkKeys(event, player)) {
// Spacebar toggles play/pause
case cPlay:
ePreventDefault();
if (alwaysCaptureHotkeys || captureDocumentHotkeys) {
// Prevent control activation with space
event.stopPropagation();
}
// Don't catch keys if any control buttons are focused, unless alwaysCaptureHotkeys is true
var activeEl = doc.activeElement;
if (
alwaysCaptureHotkeys ||
(captureDocumentHotkeys && documentHotkeysFocusElementFilter(activeEl)) ||
if (player.paused()) {
silencePromise(player.play());
} else {
player.pause();
}
break;
activeEl == pEl ||
activeEl == pEl.querySelector('.vjs-tech') ||
activeEl == pEl.querySelector('.vjs-control-bar') ||
activeEl == pEl.querySelector('.iframeblocker')
) {
// Seeking with the left/right arrow keys
case cRewind: // Seek Backward
wasPlaying = !player.paused();
ePreventDefault();
if (wasPlaying) {
player.pause();
}
seekTime = player.currentTime() - seekStepD(event);
// The flash player tech will allow you to seek into negative
// numbers and break the seekbar, so try to prevent that.
if (seekTime <= 0) {
seekTime = 0;
}
player.currentTime(seekTime);
if (wasPlaying) {
silencePromise(player.play());
}
break;
case cForward: // Seek Forward
wasPlaying = !player.paused();
ePreventDefault();
if (wasPlaying) {
player.pause();
}
seekTime = player.currentTime() + seekStepD(event);
// Fixes the player not sending the end event if you
// try to seek past the duration on the seekbar.
if (seekTime >= duration) {
seekTime = wasPlaying ? duration - 0.001 : duration;
}
player.currentTime(seekTime);
if (wasPlaying) {
silencePromise(player.play());
}
break;
switch (checkKeys(event, player)) {
// Spacebar toggles play/pause
case cPlay:
ePreventDefault();
if (alwaysCaptureHotkeys || captureDocumentHotkeys) {
// Prevent control activation with space
event.stopPropagation();
}
// Volume control with the up/down arrow keys
case cVolumeDown:
ePreventDefault();
if (!enableJogStyle) {
player.volume(player.volume() - volumeStep);
} else {
seekTime = player.currentTime() - 1;
if (player.currentTime() <= 1) {
seekTime = 0;
}
player.currentTime(seekTime);
}
break;
case cVolumeUp:
ePreventDefault();
if (!enableJogStyle) {
player.volume(player.volume() + volumeStep);
} else {
seekTime = player.currentTime() + 1;
if (seekTime >= duration) {
seekTime = duration;
}
player.currentTime(seekTime);
}
break;
if (player.paused()) {
silencePromise(player.play());
} else {
player.pause();
}
break;
// Toggle Mute with the M key
case cMute:
if (enableMute) {
player.muted(!player.muted());
}
break;
// Seeking with the left/right arrow keys
case cRewind: // Seek Backward
wasPlaying = !player.paused();
ePreventDefault();
if (wasPlaying) {
player.pause();
}
seekTime = player.currentTime() - seekStepD(event);
// The flash player tech will allow you to seek into negative
// numbers and break the seekbar, so try to prevent that.
if (seekTime <= 0) {
seekTime = 0;
}
player.currentTime(seekTime);
if (wasPlaying) {
silencePromise(player.play());
}
break;
case cForward: // Seek Forward
wasPlaying = !player.paused();
ePreventDefault();
if (wasPlaying) {
player.pause();
}
seekTime = player.currentTime() + seekStepD(event);
// Fixes the player not sending the end event if you
// try to seek past the duration on the seekbar.
if (seekTime >= duration) {
seekTime = wasPlaying ? duration - .001 : duration;
}
player.currentTime(seekTime);
if (wasPlaying) {
silencePromise(player.play());
}
break;
// Toggle Fullscreen with the F key
case cFullscreen:
if (enableFull) {
if (player.isFullscreen()) {
player.exitFullscreen();
} else {
player.requestFullscreen();
}
}
break;
// Volume control with the up/down arrow keys
case cVolumeDown:
ePreventDefault();
if (!enableJogStyle) {
player.volume(player.volume() - volumeStep);
} else {
seekTime = player.currentTime() - 1;
if (player.currentTime() <= 1) {
seekTime = 0;
}
player.currentTime(seekTime);
}
break;
case cVolumeUp:
ePreventDefault();
if (!enableJogStyle) {
player.volume(player.volume() + volumeStep);
} else {
seekTime = player.currentTime() + 1;
if (seekTime >= duration) {
seekTime = duration;
}
player.currentTime(seekTime);
}
break;
default:
// Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%
if ((ewhich > 47 && ewhich < 59) || (ewhich > 95 && ewhich < 106)) {
// Do not handle if enableModifiersForNumbers set to false and keys are Ctrl, Cmd or Alt
if (enableModifiersForNumbers || !(event.metaKey || event.ctrlKey || event.altKey)) {
if (enableNumbers) {
var sub = 48;
if (ewhich > 95) {
sub = 96;
}
var number = ewhich - sub;
ePreventDefault();
player.currentTime(player.duration() * number * 0.1);
}
}
}
// Toggle Mute with the M key
case cMute:
if (enableMute) {
player.muted(!player.muted());
}
break;
// Handle any custom hotkeys
for (var customKey in options.customKeys) {
var customHotkey = options.customKeys[customKey];
// Check for well formed custom keys
if (customHotkey && customHotkey.key && customHotkey.handler) {
// Check if the custom key's condition matches
if (customHotkey.key(event)) {
ePreventDefault();
customHotkey.handler(player, options, event);
}
}
}
}
}
}
};
// Toggle Fullscreen with the F key
case cFullscreen:
if (enableFull) {
if (player.isFullscreen()) {
player.exitFullscreen();
} else {
player.requestFullscreen();
}
}
break;
var doubleClick = function doubleClick(event) {
// Video.js added double-click fullscreen in 7.1.0
if (videojsVer != null && videojsVer <= "7.1.0") {
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
// Don't catch clicks if any control buttons are focused
var activeEl = event.relatedTarget || event.toElement || doc.activeElement;
if (activeEl == pEl || activeEl == pEl.querySelector(".vjs-tech") || activeEl == pEl.querySelector(".iframeblocker")) {
if (enableFull) {
if (player.isFullscreen()) {
player.exitFullscreen();
} else {
player.requestFullscreen();
}
}
}
}
}
};
default:
// Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%
if ((ewhich > 47 && ewhich < 59) || (ewhich > 95 && ewhich < 106)) {
// Do not handle if enableModifiersForNumbers set to false and keys are Ctrl, Cmd or Alt
if (enableModifiersForNumbers || !(event.metaKey || event.ctrlKey || event.altKey)) {
if (enableNumbers) {
var sub = 48;
if (ewhich > 95) {
sub = 96;
}
var number = ewhich - sub;
ePreventDefault();
player.currentTime(player.duration() * number * 0.1);
}
}
}
var volumeHover = false;
var volumeSelector = pEl.querySelector(".vjs-volume-menu-button") || pEl.querySelector(".vjs-volume-panel");
if (volumeSelector != null) {
volumeSelector.onmouseover = function () {
volumeHover = true;
};
volumeSelector.onmouseout = function () {
volumeHover = false;
};
}
// Handle any custom hotkeys
for (var customKey in options.customKeys) {
var customHotkey = options.customKeys[customKey];
// Check for well formed custom keys
if (customHotkey && customHotkey.key && customHotkey.handler) {
// Check if the custom key's condition matches
if (customHotkey.key(event)) {
ePreventDefault();
customHotkey.handler(player, options, event);
}
}
}
}
}
}
};
var mouseScroll = function mouseScroll(event) {
if (enableHoverScroll) {
// If we leave this undefined then it can match non-existent elements below
var activeEl = 0;
} else {
var activeEl = doc.activeElement;
}
var doubleClick = function doubleClick(event) {
// Video.js added double-click fullscreen in 7.1.0
if (videojsVer != null && videojsVer <= "7.1.0") {
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
if (
alwaysCaptureHotkeys ||
activeEl == pEl ||
activeEl == pEl.querySelector(".vjs-tech") ||
activeEl == pEl.querySelector(".iframeblocker") ||
activeEl == pEl.querySelector(".vjs-control-bar") ||
volumeHover
) {
if (enableVolumeScroll) {
event = window.event || event;
var delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail));
event.preventDefault();
// Don't catch clicks if any control buttons are focused
var activeEl = event.relatedTarget || event.toElement || doc.activeElement;
if (activeEl == pEl ||
activeEl == pEl.querySelector('.vjs-tech') ||
activeEl == pEl.querySelector('.iframeblocker')) {
if (delta == 1) {
player.volume(player.volume() + volumeStep);
} else if (delta == -1) {
player.volume(player.volume() - volumeStep);
}
}
}
}
};
if (enableFull) {
if (player.isFullscreen()) {
player.exitFullscreen();
} else {
player.requestFullscreen();
}
}
}
}
}
};
var checkKeys = function checkKeys(e, player) {
// Allow some modularity in defining custom hotkeys
var volumeHover = false;
var volumeSelector = pEl.querySelector('.vjs-volume-menu-button') || pEl.querySelector('.vjs-volume-panel');
if (volumeSelector != null) {
volumeSelector.onmouseover = function() { volumeHover = true; };
volumeSelector.onmouseout = function() { volumeHover = false; };
}
// Play/Pause check
if (options.playPauseKey(e, player)) {
return cPlay;
}
var mouseScroll = function mouseScroll(event) {
if (enableHoverScroll) {
// If we leave this undefined then it can match non-existent elements below
var activeEl = 0;
} else {
var activeEl = doc.activeElement;
}
// Seek Backward check
if (options.rewindKey(e, player)) {
return cRewind;
}
// When controls are disabled, hotkeys will be disabled as well
if (player.controls()) {
if (alwaysCaptureHotkeys ||
activeEl == pEl ||
activeEl == pEl.querySelector('.vjs-tech') ||
activeEl == pEl.querySelector('.iframeblocker') ||
activeEl == pEl.querySelector('.vjs-control-bar') ||
volumeHover) {
// Seek Forward check
if (options.forwardKey(e, player)) {
return cForward;
}
if (enableVolumeScroll) {
event = window.event || event;
var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
event.preventDefault();
// Volume Up check
if (options.volumeUpKey(e, player)) {
return cVolumeUp;
}
if (delta == 1) {
player.volume(player.volume() + volumeStep);
} else if (delta == -1) {
player.volume(player.volume() - volumeStep);
}
}
}
}
};
// Volume Down check
if (options.volumeDownKey(e, player)) {
return cVolumeDown;
}
var checkKeys = function checkKeys(e, player) {
// Allow some modularity in defining custom hotkeys
// Mute check
if (options.muteKey(e, player)) {
return cMute;
}
// Play/Pause check
if (options.playPauseKey(e, player)) {
return cPlay;
}
// Fullscreen check
if (options.fullscreenKey(e, player)) {
return cFullscreen;
}
};
// Seek Backward check
if (options.rewindKey(e, player)) {
return cRewind;
}
function playPauseKey(e) {
// Space bar or MediaPlayPause
return e.which === 32 || e.which === 179;
}
// Seek Forward check
if (options.forwardKey(e, player)) {
return cForward;
}
function rewindKey(e) {
// Left Arrow or MediaRewind
return e.which === 37 || e.which === 177;
}
// Volume Up check
if (options.volumeUpKey(e, player)) {
return cVolumeUp;
}
function forwardKey(e) {
// Right Arrow or MediaForward
return e.which === 39 || e.which === 176;
}
// Volume Down check
if (options.volumeDownKey(e, player)) {
return cVolumeDown;
}
function volumeUpKey(e) {
// Up Arrow
return e.which === 38;
}
// Mute check
if (options.muteKey(e, player)) {
return cMute;
}
function volumeDownKey(e) {
// Down Arrow
return e.which === 40;
}
// Fullscreen check
if (options.fullscreenKey(e, player)) {
return cFullscreen;
}
};
function muteKey(e) {
// M key
return e.which === 77;
}
function playPauseKey(e) {
// Space bar or MediaPlayPause
return (e.which === 32 || e.which === 179);
}
function fullscreenKey(e) {
// F key
return e.which === 70;
}
function rewindKey(e) {
// Left Arrow or MediaRewind
return (e.which === 37 || e.which === 177);
}
function seekStepD(e) {
// SeekStep caller, returns an int, or a function returning an int
return typeof seekStep === "function" ? seekStep(e) : seekStep;
}
function forwardKey(e) {
// Right Arrow or MediaForward
return (e.which === 39 || e.which === 176);
}
function silencePromise(value) {
if (value != null && typeof value.then === "function") {
value.then(null, function (e) {});
}
}
function volumeUpKey(e) {
// Up Arrow
return (e.which === 38);
}
if (captureDocumentHotkeys) {
var capDocHK = function (event) {
keyDown(event);
};
document.addEventListener("keydown", capDocHK);
function volumeDownKey(e) {
// Down Arrow
return (e.which === 40);
}
this.dispose = function () {
document.removeEventListener("keydown", capDocHK);
};
} else {
player.on("keydown", keyDown);
}
function muteKey(e) {
// M key
return (e.which === 77);
}
player.on("dblclick", doubleClick);
player.on("mousewheel", mouseScroll);
player.on("DOMMouseScroll", mouseScroll);
function fullscreenKey(e) {
// F key
return (e.which === 70);
}
return this;
};
function seekStepD(e) {
// SeekStep caller, returns an int, or a function returning an int
return (typeof seekStep === "function" ? seekStep(e) : seekStep);
}
function silencePromise(value) {
if (value != null && typeof value.then === 'function') {
value.then(null, function(e) {});
}
}
if (captureDocumentHotkeys) {
var capDocHK = function (event) { keyDown(event) };
document.addEventListener('keydown', capDocHK);
this.dispose = function () {
document.removeEventListener('keydown', capDocHK);
}
} else {
player.on('keydown', keyDown);
}
player.on('dblclick', doubleClick);
player.on('mousewheel', mouseScroll);
player.on("DOMMouseScroll", mouseScroll);
return this;
};
var registerPlugin = videojs.registerPlugin || videojs.plugin;
registerPlugin('hotkeys', hotkeys);
}));
var registerPlugin = videojs.registerPlugin || videojs.plugin;
registerPlugin("hotkeys", hotkeys);
});

@@ -1,2 +0,2 @@

/* videojs-hotkeys v0.2.28 - https://github.com/ctd1500/videojs-hotkeys */
!function(e,t){if("undefined"!=typeof window&&window.videojs)t(window.videojs);else if("function"==typeof define&&define.amd)define("videojs-hotkeys",["video.js"],function(e){return t(e.default||e)});else if("undefined"!=typeof module&&module.exports){var n=require("video.js");module.exports=t(n.default||n)}}(0,function(x){"use strict";"undefined"!=typeof window&&(window.videojs_hotkeys={version:"0.2.28"});(x.registerPlugin||x.plugin)("hotkeys",function(m){var f=this,y=f.el(),v=document,e={volumeStep:.1,seekStep:5,enableMute:!0,enableVolumeScroll:!0,enableHoverScroll:!1,enableFullscreen:!0,enableNumbers:!0,enableJogStyle:!1,alwaysCaptureHotkeys:!1,captureDocumentHotkeys:!1,documentHotkeysFocusElementFilter:function(){return!1},enableModifiersForNumbers:!0,enableInactiveFocus:!0,skipInitialFocus:!1,playPauseKey:function(e){return 32===e.which||179===e.which},rewindKey:function(e){return 37===e.which||177===e.which},forwardKey:function(e){return 39===e.which||176===e.which},volumeUpKey:function(e){return 38===e.which},volumeDownKey:function(e){return 40===e.which},muteKey:function(e){return 77===e.which},fullscreenKey:function(e){return 70===e.which},customKeys:{}},t=x.mergeOptions||x.util.mergeOptions,d=(m=t(e,m||{})).volumeStep,n=m.seekStep,p=m.enableMute,o=m.enableVolumeScroll,r=m.enableHoverScroll,b=m.enableFullscreen,h=m.enableNumbers,w=m.enableJogStyle,k=m.alwaysCaptureHotkeys,S=m.captureDocumentHotkeys,K=m.documentHotkeysFocusElementFilter,F=m.enableModifiersForNumbers,u=m.enableInactiveFocus,l=m.skipInitialFocus,i=x.VERSION;y.hasAttribute("tabIndex")||y.setAttribute("tabIndex","-1"),y.style.outline="none",!k&&f.autoplay()||l||f.one("play",function(){y.focus()}),u&&f.on("userinactive",function(){var n=function(){clearTimeout(e)},e=setTimeout(function(){f.off("useractive",n);var e=v.activeElement,t=y.querySelector(".vjs-control-bar");e&&e.parentElement==t&&y.focus()},10);f.one("useractive",n)}),f.on("play",function(){var e=y.querySelector(".iframeblocker");e&&""===e.style.display&&(e.style.display="block",e.style.bottom="39px")});var c=function(e){var t,n,o=e.which,r=e.preventDefault.bind(e),u=f.duration();if(f.controls()){var l=v.activeElement;if(k||S&&K(l)||l==y||l==y.querySelector(".vjs-tech")||l==y.querySelector(".vjs-control-bar")||l==y.querySelector(".iframeblocker"))switch(j(e,f)){case 1:r(),(k||S)&&e.stopPropagation(),f.paused()?E(f.play()):f.pause();break;case 2:t=!f.paused(),r(),t&&f.pause(),(n=f.currentTime()-T(e))<=0&&(n=0),f.currentTime(n),t&&E(f.play());break;case 3:t=!f.paused(),r(),t&&f.pause(),u<=(n=f.currentTime()+T(e))&&(n=t?u-.001:u),f.currentTime(n),t&&E(f.play());break;case 5:r(),w?(n=f.currentTime()-1,f.currentTime()<=1&&(n=0),f.currentTime(n)):f.volume(f.volume()-d);break;case 4:r(),w?(u<=(n=f.currentTime()+1)&&(n=u),f.currentTime(n)):f.volume(f.volume()+d);break;case 6:p&&f.muted(!f.muted());break;case 7:b&&(f.isFullscreen()?f.exitFullscreen():f.requestFullscreen());break;default:if((47<o&&o<59||95<o&&o<106)&&(F||!(e.metaKey||e.ctrlKey||e.altKey))&&h){var i=48;95<o&&(i=96);var c=o-i;r(),f.currentTime(f.duration()*c*.1)}for(var a in m.customKeys){var s=m.customKeys[a];s&&s.key&&s.handler&&s.key(e)&&(r(),s.handler(f,m,e))}}}},a=!1,s=y.querySelector(".vjs-volume-menu-button")||y.querySelector(".vjs-volume-panel");null!=s&&(s.onmouseover=function(){a=!0},s.onmouseout=function(){a=!1});var q=function(e){if(r)var t=0;else t=v.activeElement;if(f.controls()&&(k||t==y||t==y.querySelector(".vjs-tech")||t==y.querySelector(".iframeblocker")||t==y.querySelector(".vjs-control-bar")||a)&&o){e=window.event||e;var n=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail));e.preventDefault(),1==n?f.volume(f.volume()+d):-1==n&&f.volume(f.volume()-d)}},j=function(e,t){return m.playPauseKey(e,t)?1:m.rewindKey(e,t)?2:m.forwardKey(e,t)?3:m.volumeUpKey(e,t)?4:m.volumeDownKey(e,t)?5:m.muteKey(e,t)?6:m.fullscreenKey(e,t)?7:void 0};function T(e){return"function"==typeof n?n(e):n}function E(e){null!=e&&"function"==typeof e.then&&e.then(null,function(e){})}if(S){var g=function(e){c(e)};document.addEventListener("keydown",g),this.dispose=function(){document.removeEventListener("keydown",g)}}else f.on("keydown",c);return f.on("dblclick",function(e){if(null!=i&&i<="7.1.0"&&f.controls()){var t=e.relatedTarget||e.toElement||v.activeElement;t!=y&&t!=y.querySelector(".vjs-tech")&&t!=y.querySelector(".iframeblocker")||b&&(f.isFullscreen()?f.exitFullscreen():f.requestFullscreen())}}),f.on("mousewheel",q),f.on("DOMMouseScroll",q),this})});
/* videojs-hotkeys v0.2.29 - https://github.com/ctd1500/videojs-hotkeys */
(n=>{var e;"undefined"!=typeof window&&window.videojs?n(window.videojs):"function"==typeof define&&define.amd?define("videojs-hotkeys",["video.js"],function(e){return n(e.default||e)}):"undefined"!=typeof module&&module.exports&&(e=require("video.js"),module.exports=n(e.default||e))})(function(I){"undefined"!=typeof window&&(window.videojs_hotkeys={version:"0.2.29"});(I.registerPlugin||I.plugin)("hotkeys",function(a){function e(e){var n;n=u?0:y.activeElement,s.controls()&&(q||n==m||n==m.querySelector(".vjs-tech")||n==m.querySelector(".iframeblocker")||n==m.querySelector(".vjs-control-bar")||x)&&r&&(e=window.event||e,n=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault(),1==n?s.volume(s.volume()+k):-1==n&&s.volume(s.volume()-k))}var n,s=this,m=s.el(),y=document,f=1,d=2,v=3,p=4,b=5,h=6,w=7,t=I.obj.merge||I.mergeOptions||I.util.mergeOptions,k=(a=t({volumeStep:.1,seekStep:5,enableMute:!0,enableVolumeScroll:!0,enableHoverScroll:!1,enableFullscreen:!0,enableNumbers:!0,enableJogStyle:!1,alwaysCaptureHotkeys:!1,captureDocumentHotkeys:!1,documentHotkeysFocusElementFilter:function(){return!1},enableModifiersForNumbers:!0,enableInactiveFocus:!0,skipInitialFocus:!1,playPauseKey:function(e){return 32===e.which||179===e.which},rewindKey:function(e){return 37===e.which||177===e.which},forwardKey:function(e){return 39===e.which||176===e.which},volumeUpKey:function(e){return 38===e.which},volumeDownKey:function(e){return 40===e.which},muteKey:function(e){return 77===e.which},fullscreenKey:function(e){return 70===e.which},customKeys:{}},a||{})).volumeStep,o=a.seekStep,S=a.enableMute,r=a.enableVolumeScroll,u=a.enableHoverScroll,K=a.enableFullscreen,F=a.enableNumbers,j=a.enableJogStyle,q=a.alwaysCaptureHotkeys,T=a.captureDocumentHotkeys,E=a.documentHotkeysFocusElementFilter,g=a.enableModifiersForNumbers,t=a.enableInactiveFocus,l=a.skipInitialFocus,i=I.VERSION,c=(m.hasAttribute("tabIndex")||m.setAttribute("tabIndex","-1"),m.style.outline="none",!q&&s.autoplay()||l||s.one("play",function(){m.focus()}),t&&s.on("userinactive",function(){function t(){clearTimeout(e)}var e=setTimeout(function(){s.off("useractive",t);var e=y.activeElement,n=m.querySelector(".vjs-control-bar");e&&e.parentElement==n&&m.focus()},10);s.one("useractive",t)}),s.on("play",function(){var e=m.querySelector(".iframeblocker");e&&""===e.style.display&&(e.style.display="block",e.style.bottom="39px")}),function(e){var n=e.which,t=e.preventDefault.bind(e),o=s.duration();if(s.controls()){var r,u,l,i=y.activeElement;if(q||T&&E(i)||i==m||i==m.querySelector(".vjs-tech")||i==m.querySelector(".vjs-control-bar")||i==m.querySelector(".iframeblocker"))switch(D(e,s)){case f:t(),(q||T)&&e.stopPropagation(),s.paused()?M(s.play()):s.pause();break;case d:r=!s.paused(),t(),r&&s.pause(),u=s.currentTime()-H(e),s.currentTime(u=u<=0?0:u),r&&M(s.play());break;case v:r=!s.paused(),t(),r&&s.pause(),u=s.currentTime()+H(e),s.currentTime(u=o<=u?r?o-.001:o:u),r&&M(s.play());break;case b:t(),j?(u=s.currentTime()-1,s.currentTime()<=1&&(u=0),s.currentTime(u)):s.volume(s.volume()-k);break;case p:t(),j?(u=s.currentTime()+1,s.currentTime(u=o<=u?o:u)):s.volume(s.volume()+k);break;case h:S&&s.muted(!s.muted());break;case w:K&&(s.isFullscreen()?s.exitFullscreen():s.requestFullscreen());break;default:for(l in!(47<n&&n<59||95<n&&n<106)||!g&&(e.metaKey||e.ctrlKey||e.altKey)||F&&(r=48,u=n-(r=95<n?96:r),t(),s.currentTime(s.duration()*u*.1)),a.customKeys){var c=a.customKeys[l];c&&c.key&&c.handler&&c.key(e)&&(t(),c.handler(s,a,e))}}}}),x=!1,l=m.querySelector(".vjs-volume-menu-button")||m.querySelector(".vjs-volume-panel"),D=(null!=l&&(l.onmouseover=function(){x=!0},l.onmouseout=function(){x=!1}),function(e,n){return a.playPauseKey(e,n)?f:a.rewindKey(e,n)?d:a.forwardKey(e,n)?v:a.volumeUpKey(e,n)?p:a.volumeDownKey(e,n)?b:a.muteKey(e,n)?h:a.fullscreenKey(e,n)?w:void 0});function H(e){return"function"==typeof o?o(e):o}function M(e){null!=e&&"function"==typeof e.then&&e.then(null,function(e){})}return T?(n=function(e){c(e)},document.addEventListener("keydown",n),this.dispose=function(){document.removeEventListener("keydown",n)}):s.on("keydown",c),s.on("dblclick",function(e){null!=i&&i<="7.1.0"&&(!s.controls()||(e=e.relatedTarget||e.toElement||y.activeElement)!=m&&e!=m.querySelector(".vjs-tech")&&e!=m.querySelector(".iframeblocker")||K&&(s.isFullscreen()?s.exitFullscreen():s.requestFullscreen()))}),s.on("mousewheel",e),s.on("DOMMouseScroll",e),this})});

Sorry, the diff of this file is not supported yet

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