Socket
Socket
Sign inDemoInstall

jsdom

Package Overview
Dependencies
95
Maintainers
6
Versions
258
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 15.1.0 to 15.1.1

lib/jsdom/living/nodes/HTMLOrSVGElement-impl.js

6

lib/jsdom/living/generated/CharacterData.js

@@ -9,4 +9,2 @@ "use strict";

const Node = require("./Node.js");
const ChildNode = require("./ChildNode.js");
const NonDocumentTypeChildNode = require("./NonDocumentTypeChildNode.js");

@@ -372,6 +370,2 @@ class CharacterData extends Node.interface {

ChildNode._mixedIntoPredicates.push(module.exports.is);
NonDocumentTypeChildNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/CharacterData-impl.js");

@@ -11,5 +11,2 @@ "use strict";

const Node = require("./Node.js");
const GlobalEventHandlers = require("./GlobalEventHandlers.js");
const NonElementParentNode = require("./NonElementParentNode.js");
const ParentNode = require("./ParentNode.js");

@@ -2436,8 +2433,2 @@ class Document extends Node.interface {

GlobalEventHandlers._mixedIntoPredicates.push(module.exports.is);
NonElementParentNode._mixedIntoPredicates.push(module.exports.is);
ParentNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/Document-impl.js");

@@ -9,4 +9,2 @@ "use strict";

const Node = require("./Node.js");
const NonElementParentNode = require("./NonElementParentNode.js");
const ParentNode = require("./ParentNode.js");

@@ -249,6 +247,2 @@ class DocumentFragment extends Node.interface {

NonElementParentNode._mixedIntoPredicates.push(module.exports.is);
ParentNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/DocumentFragment-impl.js");

3

lib/jsdom/living/generated/DocumentType.js

@@ -9,3 +9,2 @@ "use strict";

const Node = require("./Node.js");
const ChildNode = require("./ChildNode.js");

@@ -194,4 +193,2 @@ class DocumentType extends Node.interface {

ChildNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/DocumentType-impl.js");

@@ -11,6 +11,2 @@ "use strict";

const Node = require("./Node.js");
const ChildNode = require("./ChildNode.js");
const Slotable = require("./Slotable.js");
const NonDocumentTypeChildNode = require("./NonDocumentTypeChildNode.js");
const ParentNode = require("./ParentNode.js");

@@ -1100,10 +1096,2 @@ class Element extends Node.interface {

get assignedSlot() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["assignedSlot"]);
}
get previousElementSibling() {

@@ -1158,2 +1146,10 @@ if (!this || !module.exports.is(this)) {

}
get assignedSlot() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["assignedSlot"]);
}
}

@@ -1217,3 +1213,2 @@ Object.defineProperties(Element.prototype, {

clientHeight: { enumerable: true },
assignedSlot: { enumerable: true },
previousElementSibling: { enumerable: true },

@@ -1225,2 +1220,3 @@ nextElementSibling: { enumerable: true },

childElementCount: { enumerable: true },
assignedSlot: { enumerable: true },
[Symbol.toStringTag]: { value: "Element", configurable: true },

@@ -1309,10 +1305,2 @@ [Symbol.unscopables]: {

ChildNode._mixedIntoPredicates.push(module.exports.is);
Slotable._mixedIntoPredicates.push(module.exports.is);
NonDocumentTypeChildNode._mixedIntoPredicates.push(module.exports.is);
ParentNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/Element-impl.js");

@@ -95,3 +95,2 @@ "use strict";

let typedKey = key;
let typedValue = curArg[key];

@@ -102,2 +101,4 @@ typedKey = conversions["ByteString"](typedKey, {

let typedValue = curArg[key];
typedValue = conversions["ByteString"](typedValue, {

@@ -104,0 +105,0 @@ context: "Failed to construct 'Headers': parameter 1" + " record" + "'s value"

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const HTMLHyperlinkElementUtils = require("./HTMLHyperlinkElementUtils.js");

@@ -583,4 +582,2 @@ class HTMLAnchorElement extends HTMLElement.interface {

HTMLHyperlinkElementUtils._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLAnchorElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const HTMLHyperlinkElementUtils = require("./HTMLHyperlinkElementUtils.js");

@@ -477,4 +476,2 @@ class HTMLAreaElement extends HTMLElement.interface {

HTMLHyperlinkElementUtils._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLAreaElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const WindowEventHandlers = require("./WindowEventHandlers.js");

@@ -537,4 +536,2 @@ class HTMLBodyElement extends HTMLElement.interface {

WindowEventHandlers._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLBodyElement-impl.js");

@@ -8,5 +8,2 @@ "use strict";

const Element = require("./Element.js");
const ElementCSSInlineStyle = require("./ElementCSSInlineStyle.js");
const GlobalEventHandlers = require("./GlobalEventHandlers.js");
const ElementContentEditable = require("./ElementContentEditable.js");

@@ -124,12 +121,2 @@ class HTMLElement extends Element.interface {

get dataset() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.getSameObject(this, "dataset", () => {
return utils.tryWrapperForImpl(this[impl]["dataset"]);
});
}
get hidden() {

@@ -159,22 +146,2 @@ if (!this || !module.exports.is(this)) {

get tabIndex() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["tabIndex"];
}
set tabIndex(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["long"](V, {
context: "Failed to set the 'tabIndex' property on 'HTMLElement': The provided value"
});
this[impl]["tabIndex"] = V;
}
get accessKey() {

@@ -1378,2 +1345,53 @@ if (!this || !module.exports.is(this)) {

}
get dataset() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.getSameObject(this, "dataset", () => {
return utils.tryWrapperForImpl(this[impl]["dataset"]);
});
}
get nonce() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
const value = this.getAttributeNS(null, "nonce");
return value === null ? "" : value;
}
set nonce(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["DOMString"](V, {
context: "Failed to set the 'nonce' property on 'HTMLElement': The provided value"
});
this.setAttributeNS(null, "nonce", V);
}
get tabIndex() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["tabIndex"];
}
set tabIndex(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["long"](V, {
context: "Failed to set the 'tabIndex' property on 'HTMLElement': The provided value"
});
this[impl]["tabIndex"] = V;
}
}

@@ -1388,5 +1406,3 @@ Object.defineProperties(HTMLElement.prototype, {

dir: { enumerable: true },
dataset: { enumerable: true },
hidden: { enumerable: true },
tabIndex: { enumerable: true },
accessKey: { enumerable: true },

@@ -1462,2 +1478,5 @@ draggable: { enumerable: true },

onwaiting: { enumerable: true },
dataset: { enumerable: true },
nonce: { enumerable: true },
tabIndex: { enumerable: true },
[Symbol.toStringTag]: { value: "HTMLElement", configurable: true }

@@ -1542,8 +1561,2 @@ });

ElementCSSInlineStyle._mixedIntoPredicates.push(module.exports.is);
GlobalEventHandlers._mixedIntoPredicates.push(module.exports.is);
ElementContentEditable._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const WindowEventHandlers = require("./WindowEventHandlers.js");

@@ -444,4 +443,2 @@ class HTMLFrameSetElement extends HTMLElement.interface {

WindowEventHandlers._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLFrameSetElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const LinkStyle = require("./LinkStyle.js");

@@ -324,4 +323,2 @@ class HTMLLinkElement extends HTMLElement.interface {

LinkStyle._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLLinkElement-impl.js");

@@ -123,23 +123,2 @@ "use strict";

get nonce() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
const value = this.getAttributeNS(null, "nonce");
return value === null ? "" : value;
}
set nonce(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["DOMString"](V, {
context: "Failed to set the 'nonce' property on 'HTMLScriptElement': The provided value"
});
this.setAttributeNS(null, "nonce", V);
}
get charset() {

@@ -214,3 +193,2 @@ if (!this || !module.exports.is(this)) {

text: { enumerable: true },
nonce: { enumerable: true },
charset: { enumerable: true },

@@ -217,0 +195,0 @@ event: { enumerable: true },

@@ -8,3 +8,2 @@ "use strict";

const HTMLElement = require("./HTMLElement.js");
const LinkStyle = require("./LinkStyle.js");

@@ -37,23 +36,2 @@ class HTMLStyleElement extends HTMLElement.interface {

get nonce() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
const value = this.getAttributeNS(null, "nonce");
return value === null ? "" : value;
}
set nonce(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["DOMString"](V, {
context: "Failed to set the 'nonce' property on 'HTMLStyleElement': The provided value"
});
this.setAttributeNS(null, "nonce", V);
}
get type() {

@@ -90,3 +68,2 @@ if (!this || !module.exports.is(this)) {

media: { enumerable: true },
nonce: { enumerable: true },
type: { enumerable: true },

@@ -173,4 +150,2 @@ sheet: { enumerable: true },

LinkStyle._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/HTMLStyleElement-impl.js");

@@ -7,8 +7,2 @@ "use strict";

const impl = utils.implSymbol;
const NavigatorID = require("./NavigatorID.js");
const NavigatorLanguage = require("./NavigatorLanguage.js");
const NavigatorOnLine = require("./NavigatorOnLine.js");
const NavigatorCookies = require("./NavigatorCookies.js");
const NavigatorPlugins = require("./NavigatorPlugins.js");
const NavigatorConcurrentHardware = require("./NavigatorConcurrentHardware.js");

@@ -255,14 +249,2 @@ class Navigator {

NavigatorID._mixedIntoPredicates.push(module.exports.is);
NavigatorLanguage._mixedIntoPredicates.push(module.exports.is);
NavigatorOnLine._mixedIntoPredicates.push(module.exports.is);
NavigatorCookies._mixedIntoPredicates.push(module.exports.is);
NavigatorPlugins._mixedIntoPredicates.push(module.exports.is);
NavigatorConcurrentHardware._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../navigator/Navigator-impl.js");

@@ -8,4 +8,2 @@ "use strict";

const Element = require("./Element.js");
const ElementCSSInlineStyle = require("./ElementCSSInlineStyle.js");
const GlobalEventHandlers = require("./GlobalEventHandlers.js");

@@ -43,12 +41,2 @@ class SVGElement extends Element.interface {

get dataset() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.getSameObject(this, "dataset", () => {
return utils.tryWrapperForImpl(this[impl]["dataset"]);
});
}
get ownerSVGElement() {

@@ -70,22 +58,2 @@ if (!this || !module.exports.is(this)) {

get tabIndex() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["tabIndex"];
}
set tabIndex(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["long"](V, {
context: "Failed to set the 'tabIndex' property on 'SVGElement': The provided value"
});
this[impl]["tabIndex"] = V;
}
get style() {

@@ -1208,2 +1176,53 @@ if (!this || !module.exports.is(this)) {

}
get dataset() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.getSameObject(this, "dataset", () => {
return utils.tryWrapperForImpl(this[impl]["dataset"]);
});
}
get nonce() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
const value = this.getAttributeNS(null, "nonce");
return value === null ? "" : value;
}
set nonce(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["DOMString"](V, {
context: "Failed to set the 'nonce' property on 'SVGElement': The provided value"
});
this.setAttributeNS(null, "nonce", V);
}
get tabIndex() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["tabIndex"];
}
set tabIndex(V) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
V = conversions["long"](V, {
context: "Failed to set the 'tabIndex' property on 'SVGElement': The provided value"
});
this[impl]["tabIndex"] = V;
}
}

@@ -1214,6 +1233,4 @@ Object.defineProperties(SVGElement.prototype, {

className: { enumerable: true },
dataset: { enumerable: true },
ownerSVGElement: { enumerable: true },
viewportElement: { enumerable: true },
tabIndex: { enumerable: true },
style: { enumerable: true },

@@ -1282,2 +1299,5 @@ onabort: { enumerable: true },

onwaiting: { enumerable: true },
dataset: { enumerable: true },
nonce: { enumerable: true },
tabIndex: { enumerable: true },
[Symbol.toStringTag]: { value: "SVGElement", configurable: true }

@@ -1362,6 +1382,2 @@ });

ElementCSSInlineStyle._mixedIntoPredicates.push(module.exports.is);
GlobalEventHandlers._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/SVGElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const SVGGraphicsElement = require("./SVGGraphicsElement.js");
const WindowEventHandlers = require("./WindowEventHandlers.js");

@@ -499,4 +498,2 @@ class SVGSVGElement extends SVGGraphicsElement.interface {

WindowEventHandlers._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/SVGSVGElement-impl.js");

@@ -8,3 +8,2 @@ "use strict";

const CharacterData = require("./CharacterData.js");
const Slotable = require("./Slotable.js");

@@ -146,4 +145,2 @@ class Text extends CharacterData.interface {

Slotable._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/Text-impl.js");

@@ -11,2 +11,7 @@ "use strict";

// https://infra.spec.whatwg.org/#ascii-uppercase
exports.asciiUppercase = s => {
return s.replace(/[a-z]/g, l => l.toUpperCase());
};
// https://infra.spec.whatwg.org/#strip-newlines

@@ -13,0 +18,0 @@ exports.stripNewlines = s => {

@@ -20,3 +20,3 @@ "use strict";

const validateNames = require("../helpers/validate-names");
const { asciiLowercase } = require("../helpers/strings");
const { asciiLowercase, asciiUppercase } = require("../helpers/strings");
const { listOfElementsWithQualifiedName, listOfElementsWithNamespaceAndLocalName,

@@ -136,3 +136,3 @@ listOfElementsWithClassNames } = require("../node");

if (this.namespaceURI === HTML_NS && this._ownerDocument._parsingMode === "html") {
qualifiedName = qualifiedName.toUpperCase();
qualifiedName = asciiUppercase(qualifiedName);
}

@@ -139,0 +139,0 @@ return qualifiedName;

@@ -6,2 +6,3 @@ "use strict";

_initElementCSSInlineStyle() {
this._settingCssText = false;
this._style = new cssstyle.CSSStyleDeclaration(newCssText => {

@@ -8,0 +9,0 @@ if (!this._settingCssText) {

@@ -7,3 +7,3 @@ "use strict";

const GlobalEventHandlersImpl = require("./GlobalEventHandlers-impl").implementation;
const HTMLAndSVGElementSharedImpl = require("./HTMLAndSVGElementShared-impl").implementation;
const HTMLOrSVGElementImpl = require("./HTMLOrSVGElement-impl").implementation;
const { firstChildWithLocalName } = require("../helpers/traversal");

@@ -16,7 +16,6 @@ const { isDisabled } = require("../helpers/form-controls");

super(args, privateData);
this._initHTMLAndSVGElement();
this._initHTMLOrSVGElement();
this._initElementCSSInlineStyle();
this._initGlobalEvents();
this._settingCssText = false;
this._clickInProgress = false;

@@ -121,2 +120,3 @@

// Keep in sync with SVGElement. https://github.com/jsdom/jsdom/issues/2599
_attrModified(name, value, oldValue) {

@@ -157,3 +157,3 @@ if (name === "style" && value !== oldValue && !this._settingCssText) {

mixin(HTMLElementImpl.prototype, GlobalEventHandlersImpl.prototype);
mixin(HTMLElementImpl.prototype, HTMLAndSVGElementSharedImpl.prototype);
mixin(HTMLElementImpl.prototype, HTMLOrSVGElementImpl.prototype);

@@ -160,0 +160,0 @@ module.exports = {

@@ -10,3 +10,3 @@ "use strict";

const GlobalEventHandlersImpl = require("./GlobalEventHandlers-impl").implementation;
const HTMLAndSVGElementSharedImpl = require("./HTMLAndSVGElementShared-impl").implementation;
const HTMLOrSVGElementImpl = require("./HTMLOrSVGElement-impl").implementation;

@@ -16,3 +16,3 @@ class SVGElementImpl extends ElementImpl {

super(args, privateData);
this._initHTMLAndSVGElement();
this._initHTMLOrSVGElement();
this._initElementCSSInlineStyle();

@@ -22,2 +22,15 @@ this._initGlobalEvents();

// Keep in sync with HTMLElement. https://github.com/jsdom/jsdom/issues/2599
_attrModified(name, value, oldValue) {
if (name === "style" && value !== oldValue && !this._settingCssText) {
this._settingCssText = true;
this._style.cssText = value;
this._settingCssText = false;
} else if (name.startsWith("on")) {
this._globalEventChanged(name.substring(2));
}
super._attrModified.apply(this, arguments);
}
get className() {

@@ -52,4 +65,4 @@ return SVGAnimatedString.createImpl([], {

mixin(SVGElementImpl.prototype, GlobalEventHandlersImpl.prototype);
mixin(SVGElementImpl.prototype, HTMLAndSVGElementSharedImpl.prototype);
mixin(SVGElementImpl.prototype, HTMLOrSVGElementImpl.prototype);
exports.implementation = SVGElementImpl;

@@ -49,8 +49,2 @@ "use strict";

function mergeHeaders(lhs, rhs) {
const rhsParts = rhs.split(",");
const lhsParts = lhs.split(",");
return rhsParts.concat(lhsParts.filter(p => rhsParts.indexOf(p) < 0)).join(",");
}
function dispatchError(xhr) {

@@ -373,12 +367,3 @@ const errMessage = xhr[xhrSymbols.properties].error;

const realClient = doRequest();
realClient.on("response", res => {
for (const header in resp.headers) {
if (preflightHeaders.has(header)) {
res.headers[header] = Object.prototype.hasOwnProperty.call(res.headers, header) ?
mergeHeaders(res.headers[header], resp.headers[header]) :
resp.headers[header];
}
}
client.emit("response", res);
});
realClient.on("response", res => client.emit("response", res));
realClient.on("data", chunk => client.emit("data", chunk));

@@ -385,0 +370,0 @@ realClient.on("end", () => client.emit("end"));

@@ -579,4 +579,4 @@ "use strict";

parsed.parameters.set("charset", encoding);
xhrUtils.updateRequestHeader(flag.requestHeaders, "content-type", parsed.toString());
}
xhrUtils.updateRequestHeader(flag.requestHeaders, "content-type", parsed.toString());
}

@@ -583,0 +583,0 @@ }

{
"name": "jsdom",
"version": "15.1.0",
"version": "15.1.1",
"description": "A JavaScript implementation of many web standards",

@@ -23,19 +23,19 @@ "keywords": [

"abab": "^2.0.0",
"acorn": "^6.0.4",
"acorn-globals": "^4.3.0",
"acorn": "^6.1.1",
"acorn-globals": "^4.3.2",
"array-equal": "^1.0.0",
"cssom": "^0.3.4",
"cssstyle": "^1.1.1",
"cssom": "^0.3.6",
"cssstyle": "^1.2.2",
"data-urls": "^1.1.0",
"domexception": "^1.0.1",
"escodegen": "^1.11.0",
"escodegen": "^1.11.1",
"html-encoding-sniffer": "^1.0.2",
"nwsapi": "^2.1.3",
"nwsapi": "^2.1.4",
"parse5": "5.1.0",
"pn": "^1.1.0",
"request": "^2.88.0",
"request-promise-native": "^1.0.5",
"request-promise-native": "^1.0.7",
"saxes": "^3.1.9",
"symbol-tree": "^3.2.2",
"tough-cookie": "^2.5.0",
"tough-cookie": "^3.0.1",
"w3c-hr-time": "^1.0.1",

@@ -47,3 +47,3 @@ "w3c-xmlserializer": "^1.1.2",

"whatwg-url": "^7.0.0",
"ws": "^6.1.2",
"ws": "^7.0.0",
"xml-name-validator": "^3.0.0"

@@ -58,7 +58,7 @@ },

"chai": "^4.2.0",
"eslint": "^4.19.1",
"eslint": "^5.16.0",
"eslint-find-rules": "^3.3.1",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-html": "^5.0.5",
"eslint-plugin-jsdom-internal": "link:./scripts/eslint-plugin",
"js-yaml": "^3.12.0",
"js-yaml": "^3.13.1",
"karma": "^1.7.1",

@@ -76,8 +76,8 @@ "karma-browserify": "^5.3.0",

"q": "^1.5.1",
"rimraf": "^2.6.2",
"rimraf": "^2.6.3",
"server-destroy": "^1.0.1",
"st": "^1.2.2",
"watchify": "^3.11.0",
"wd": "^1.11.1",
"webidl2js": "^9.2.1"
"watchify": "^3.11.1",
"wd": "^1.11.2",
"webidl2js": "^9.2.2"
},

@@ -84,0 +84,0 @@ "browser": {

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc