Socket
Socket
Sign inDemoInstall

js-circle-progress

Package Overview
Dependencies
0
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0-alpha.0 to 1.0.0-alpha.1

59

dist/circle-progress.d.ts

@@ -110,2 +110,14 @@ export default CircleProgress;

/**
* Get property value
* Flushes pending updates.
*/
_get(key: any): any;
/**
* Set an attribute to a value
* @param {string} key Attribute name
* @param {*} val Attribute value
* @return {false|void} false if the value is the same as the current one, void otherwise
*/
_set(key: string, val: any): false | void;
/**
* A promise that resolves when the element has finished updating

@@ -115,2 +127,41 @@ */

/**
* Schedule an update of a property on microtask level
* @param {string} key Property name
* @param {*} val Property value
*/
_scheduleUpdate(key: string, val: any): void;
_flushBatch(): void;
/**
* Format attribute value according to its type
* @param {string} key Attribute name
* @param {*} val Attribute value
* @return {*} Formatted attribute value
*/
_formatValue(key: string, val: any): any;
/**
* Convert current value to angle
* The caller is responsible to check if the state is not indeterminate.
* This is done for optimization purposes as this method is called from within an animation.
* @return {number} Angle in degrees
*/
_valueToAngle(value?: number): number;
/**
* Check wether the progressbar is in indeterminate state
* @return {boolean} True if the state is indeterminate, false if it is determinate
*/
_isIndeterminate(): boolean;
/**
* Position the value text on the circle
* @param {number} angle Angle at which to position the text
* @param {number} r Circle radius measured to the middle of the stroke
* as returned by {@link CircleProgress.getRadius}, where text should be.
* The radius is passed rather than calculated inside the function
* for optimization purposes as this method is called from within an animation.
*/
_positionValueText(angle: number, r: number): void;
/**
* Generate text representation of the values based on {@link CircleProgress#textFormat}
*/
_initText(): void;
/**
* Update graphics

@@ -120,2 +171,6 @@ */

/**
* Update texts
*/
_updateText(value: any, angle: any, r: any): void;
/**
* Get circles' radius based on the calculated stroke widths of the value path and circle

@@ -125,4 +180,8 @@ * @return {number} The radius

getRadius(): number;
/**
* Get SVG element's stroke-width
*/
_getStrokeWidth(el: any): number;
#private;
}
import CustomElement from './custom-element.js';

81

dist/circle-progress.js
/*!
* Circle Progress - v1.0.0-alpha.0 - 2023-07-17
* Circle Progress - v1.0.0-alpha.1 - 2023-07-17
* https://tigrr.github.io/circle-progress/

@@ -59,3 +59,3 @@ * Copyright (c) Tigran Sargsyan

*/
#attrNameToProp(name) {
_attrNameToProp(name) {
return this.#attrToPropDict[name] ?? name

@@ -69,3 +69,3 @@ }

*/
#propToAttrName(name) {
_propToAttrName(name) {
return this.#propToAttrDict[name] ?? name

@@ -80,3 +80,3 @@ }

*/
#attrValToProp(name, value) {
_attrValToProp(name, value) {
if (this.#boolProps.has(name)) {

@@ -95,3 +95,3 @@ return value !== null

}
this.attributeUpdated?.(this.#attrNameToProp(name), this.#attrValToProp(name, newValue));
this.attributeUpdated?.(this._attrNameToProp(name), this._attrValToProp(name, newValue));
}

@@ -102,3 +102,3 @@

this.#bailOutAttrUpdate = true;
const attr = this.#propToAttrName(prop);
const attr = this._propToAttrName(prop);
if (this.#boolProps.has(prop)) {

@@ -450,6 +450,2 @@ if (value) {

}
:host(:not([text-format="vertical"])) .text {
dominant-baseline: middle;
}
`;

@@ -576,3 +572,3 @@

get() {
return this.#get(prop);
return this._get(prop);
},

@@ -622,5 +618,5 @@ set(val) {

});
this.#initText();
this._initText();
Object.keys(CircleProgress.props)
.forEach(key => key in opts && this.#set(key, opts[key]));
.forEach(key => key in opts && this._set(key, opts[key]));
}

@@ -630,3 +626,3 @@

attributeUpdated(name, newValue) {
this.#set(name, newValue);
this._set(name, newValue);
}

@@ -649,3 +645,3 @@

if(arguments.length === 1) {
return this.#get(attrs);
return this._get(attrs);
}

@@ -659,3 +655,3 @@ attrs = [[attrs, arguments[1]]];

attrs.forEach(([key, value]) => this.#set(key, value));
attrs.forEach(([key, value]) => this._set(key, value));
return this;

@@ -668,4 +664,4 @@ }

*/
#get(key) {
this.#flushBatch();
_get(key) {
this._flushBatch();
return this.#attrs[key];

@@ -681,6 +677,6 @@ }

*/
#set(key, val) {
val = this.#formatValue(key, val);
_set(key, val) {
val = this._formatValue(key, val);
if(val === undefined) throw new TypeError(`Failed to set the ${key} property on CircleProgress: The provided value is non-finite.`);
this.#scheduleUpdate(key, val);
this._scheduleUpdate(key, val);
}

@@ -703,6 +699,6 @@

*/
#scheduleUpdate(key, val) {
_scheduleUpdate(key, val) {
if(!this.#batch) {
this.#batch = {};
this.updateComplete = Promise.resolve().then(() => this.#flushBatch());
this.updateComplete = Promise.resolve().then(() => this._flushBatch());
}

@@ -712,3 +708,3 @@ this.#batch[key] = val;

#flushBatch() {
_flushBatch() {
if (!this.#batch) {

@@ -747,3 +743,3 @@ return;

if(key === 'textFormat') {
this.#initText();
this._initText();
const circleThickness = val === 'valueOnCircle' ? 16 : 8;

@@ -765,3 +761,3 @@ this.graph.sector.attr('stroke-width', circleThickness);

*/
#formatValue(key, val) {
_formatValue(key, val) {
switch(key) {

@@ -810,3 +806,3 @@ case 'value':

*/
#valueToAngle(value = this.value) {
_valueToAngle(value = this.value) {
return Math.min(

@@ -826,3 +822,3 @@ 360,

*/
#isIndeterminate() {
_isIndeterminate() {
return ['value', 'max', 'min'].some(key => typeof this[key] !== 'number');

@@ -840,3 +836,3 @@ }

*/
#positionValueText(angle, r) {
_positionValueText(angle, r) {
const coords = polarToCartesian(r, angle);

@@ -850,3 +846,3 @@ this.graph.textVal.attr({x: 50 + coords.x, y: 50 + coords.y});

*/
#initText() {
_initText() {
const format = this.textFormat;

@@ -881,2 +877,3 @@ this.graph.text.content('');

y: 0,
dy: '0.4em',
});

@@ -886,2 +883,3 @@ this.graph.textMax.attr({

y: 50,
dy: '0.4em',
});

@@ -900,2 +898,3 @@ break;

}
this.graph.text.attr('dy', format === 'vertical' ? '' : '0.4em');
}

@@ -917,19 +916,19 @@

this.#animator?.cancel();
if(!this.#isIndeterminate()) {
if(!this._isIndeterminate()) {
const clockwise = !this.anticlockwise;
let angle = this.#valueToAngle();
let angle = this._valueToAngle();
this.graph.circle.attr('r', r);
if(this.animation !== 'none' && this.value !== this.graph.value) {
this.#animator = animator(this.animation, this.graph.value, this.value - this.graph.value, this.animationDuration, value => {
angle = this.#valueToAngle(value);
angle = this._valueToAngle(value);
this.graph.sector.attr('d', makeSectorPath(50, 50, r, startAngle, angle, clockwise));
this.#updateText(value === this.value ? value : Math.round(value), (2 * startAngle + angle) / 2, r);
this._updateText(value === this.value ? value : Math.round(value), (2 * startAngle + angle) / 2, r);
});
} else {
this.graph.sector.attr('d', makeSectorPath(50, 50, r, startAngle, angle, clockwise));
this.#updateText(this.value, (2 * startAngle + angle) / 2, r);
this._updateText(this.value, (2 * startAngle + angle) / 2, r);
}
this.graph.value = this.value;
} else {
this.#updateText(this.value, startAngle, r);
this._updateText(this.value, startAngle, r);
}

@@ -941,3 +940,3 @@ }

*/
#updateText(value, angle, r) {
_updateText(value, angle, r) {
if(typeof this.textFormat === 'function') {

@@ -962,3 +961,3 @@ this.graph.text.content(this.textFormat(value, this.max));

if(this.textFormat === 'valueOnCircle') {
this.#positionValueText(angle, r);
this._positionValueText(angle, r);
}

@@ -975,4 +974,4 @@ }

return 50 - Math.max(
this.#getStrokeWidth(this.graph.circle.el),
this.#getStrokeWidth(this.graph.sector.el),
this._getStrokeWidth(this.graph.circle.el),
this._getStrokeWidth(this.graph.sector.el),
) / 2;

@@ -984,3 +983,3 @@ }

*/
#getStrokeWidth(el) {
_getStrokeWidth(el) {
return Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(el)['stroke-width'] || 0);

@@ -987,0 +986,0 @@ }

/*!
* Circle Progress - v1.0.0-alpha.0 - 2023-07-17
* Circle Progress - v1.0.0-alpha.1 - 2023-07-17
* https://tigrr.github.io/circle-progress/

@@ -7,3 +7,3 @@ * Copyright (c) Tigran Sargsyan

*/
class t extends HTMLElement{static styles="";static props={};#t={};#e={};#a=new Set;constructor(){super();const t=this.attachShadow({mode:"open"}),{styles:e}=this.constructor;if(e){const a=document.createElement("style");a.textContent=e,t.append(a)}const{props:a}=this.constructor;if(a)for(const[t,e]of Object.entries(a))e.attribute&&(this.#t[t]=e.attribute,this.#e[e.attribute]=t),e.type===Boolean&&this.#a.add(t)}attributeUpdated(t,e){}#i(t){return this.#e[t]??t}#r(t){return this.#t[t]??t}#n(t,e){return this.#a.has(t)?null!==e:e}#s=!1;attributeChangedCallback(t,e,a){this.#s?this.#s=!1:this.attributeUpdated?.(this.#i(t),this.#n(t,a))}reflectPropToAttribute(t){const e=this[t];this.#s=!0;const a=this.#r(t);this.#a.has(t)?e?this.setAttribute(a,""):this.removeAttribute(a):"function"==typeof e?this.removeAttribute(a):this.setAttribute(a,String(e))}}const e=function(t,e,i,r){r=r||document;const n=Object.create(a);if("string"==typeof t&&(t=r.querySelector(t)),!t)return;const s=r.createElementNS("http://www.w3.org/2000/svg","svg");return s.setAttribute("version","1.1"),e&&s.setAttribute("width",String(e)),i&&s.setAttribute("height",String(i)),e&&i&&s.setAttribute("viewBox","0 0 "+e+" "+i),t.appendChild(s),n.svg=s,n},a={element:function(t,e,a,r){const n=i(this,t,e,r);return a&&(n.el.innerHTML=a),n}},i=function(t,e,a,i,n){n=n||document;const s=Object.create(r);return s.el=n.createElementNS("http://www.w3.org/2000/svg",e),s.attr(a),(i?"el"in i?i.el:i:t.svg).appendChild(s.el),s},r={attr:function(t,e){if(void 0===t)return this;if("object"==typeof t){for(let e in t)this.attr(e,t[e]);return this}return void 0===e?this.el.getAttributeNS(null,t):(this.el.setAttribute(t,e),this)},content:function(t){return this.el.innerHTML=t,this}},n={linear:function(t,e,a,i){return a*t/i+e},easeInQuad:function(t,e,a,i){return a*(t/=i)*t+e},easeOutQuad:function(t,e,a,i){return-a*(t/=i)*(t-2)+e},easeInOutQuad:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t+e:-a/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,a,i){return a*(t/=i)*t*t+e},easeOutCubic:function(t,e,a,i){return t/=i,a*(--t*t*t+1)+e},easeInOutCubic:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t+e:a/2*((t-=2)*t*t+2)+e},easeInQuart:function(t,e,a,i){return a*(t/=i)*t*t*t+e},easeOutQuart:function(t,e,a,i){return t/=i,-a*(--t*t*t*t-1)+e},easeInOutQuart:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t*t+e:-a/2*((t-=2)*t*t*t-2)+e},easeInQuint:function(t,e,a,i){return a*(t/=i)*t*t*t*t+e},easeOutQuint:function(t,e,a,i){return t/=i,a*(--t*t*t*t*t+1)+e},easeInOutQuint:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t*t*t+e:a/2*((t-=2)*t*t*t*t+2)+e},easeInSine:function(t,e,a,i){return-a*Math.cos(t/i*(Math.PI/2))+a+e},easeOutSine:function(t,e,a,i){return a*Math.sin(t/i*(Math.PI/2))+e},easeInOutSine:function(t,e,a,i){return-a/2*(Math.cos(Math.PI*t/i)-1)+e},easeInExpo:function(t,e,a,i){return a*Math.pow(2,10*(t/i-1))+e},easeOutExpo:function(t,e,a,i){return a*(1-Math.pow(2,-10*t/i))+e},easeInOutExpo:function(t,e,a,i){return(t/=i/2)<1?a/2*Math.pow(2,10*(t-1))+e:(t--,a/2*(2-Math.pow(2,-10*t))+e)},easeInCirc:function(t,e,a,i){return t/=i,-a*(Math.sqrt(1-t*t)-1)+e},easeOutCirc:function(t,e,a,i){return t/=i,t--,a*Math.sqrt(1-t*t)+e},easeInOutCirc:function(t,e,a,i){return(t/=i/2)<1?-a/2*(Math.sqrt(1-t*t)-1)+e:(t-=2,a/2*(Math.sqrt(1-t*t)+1)+e)}},s=(t,e)=>({x:t*Math.cos(e*Math.PI/180),y:t*Math.sin(e*Math.PI/180)}),o=(t,e,a,i,r,n=!1)=>{r>0&&r<.3?r=0:r>359.999&&(r=359.999);const o=i+r*(2*+n-1),h=s(a,i),u=s(a,o),l=t+h.x,c=t+u.x;return["M",l,e+h.y,"A",a,a,0,+(r>180),+n,c,e+u.y].join(" ")};const h={value:"aria-valuenow",min:"aria-valuemin",max:"aria-valuemax"};class u extends t{static styles='\n\t:host(:not([hidden])) {\n\t\tdisplay: inline-block;\n\t}\n\n\t.circle {\n\t\tfill: none;\n\t\tstroke: #ddd;\n\t}\n\n\t.value {\n\t\tfill: none;\n\t\tstroke: #00E699;\n\t}\n\n\t.text {\n\t\tfont: 16px Arial, sans-serif;\n\t\ttext-anchor: middle;\n\t\tfill: #999;\n\t}\n\n\t:host([text-format="valueOnCircle"]) .text-value {\n\t\tfont-size: 12px;\n\t\tfill: #fff;\n\t}\n\n\t:host([text-format="valueOnCircle"]) .text-max {\n\t\tfont-size: 22px;\n\t\tfont-weight: bold;\n\t\tfill: #ddd;\n\t}\n\n\t:host([text-format="vertical"]) .text-separator {\n\t\tfont-family: Arial, sans-serif !important;\n\t}\n\n\t:host(:not([text-format="vertical"])) .text {\n\t\tdominant-baseline: middle;\n\t}\n';value;min;max;startAngle;anticlockwise;unconstrained;indeterminateText;textFormat;animation;animationDuration;static props={value:!0,min:!0,max:!0,startAngle:{attribute:"start-angle"},anticlockwise:{type:Boolean},unconstrained:{type:Boolean},indeterminateText:{attribute:"indeterminate-text"},textFormat:{attribute:"text-format"},animation:!0,animationDuration:{attribute:"animation-duration"}};static get observedAttributes(){return Object.entries(this.props).map((([t,e])=>e&&"object"==typeof e&&e.attribute||t))}static defaults={startAngle:0,min:0,max:1,unconstrained:!1,indeterminateText:"?",anticlockwise:!1,textFormat:"horizontal",animation:"easeInOutCubic",animationDuration:600};constructor(t={}){let a;super(),Object.defineProperties(this,Object.keys(u.props).reduce(((t,e)=>(t[e]={get(){return this.#o(e)},set(t){this.attr(e,t)}},t)),{})),a="valueOnCircle"===(t={...u.defaults,...t}).textFormat?16:8,this.graph={paper:e(this.shadowRoot,100,100),value:0},this.graph.paper.svg.setAttribute("class","base"),this.graph.paper.svg.setAttribute("part","base"),this.graph.paper.svg.setAttribute("role","progressbar"),this.graph.circle=this.graph.paper.element("circle").attr({class:"circle",part:"circle",cx:50,cy:50,r:50-a/2,"stroke-width":a}),this.graph.sector=this.graph.paper.element("path").attr({d:o(50,50,50-a/2,0,0),class:"value",part:"value","stroke-width":a}),this.graph.text=this.graph.paper.element("text",{class:"text",part:"text",x:50,y:50}),this.#h(),Object.keys(u.props).forEach((e=>e in t&&this.#u(e,t[e])))}attributeUpdated(t,e){this.#u(t,e)}#l={};attr(t){if(!["string","object"].includes(typeof t))throw new TypeError(`Wrong argument passed to attr. Expected object, got "${typeof t}"`);if("string"==typeof t){if(1===arguments.length)return this.#o(t);t=[[t,arguments[1]]]}return Array.isArray(t)||(t=Object.keys(t).map((e=>[e,t[e]]))),t.forEach((([t,e])=>this.#u(t,e))),this}#o(t){return this.#c(),this.#l[t]}#u(t,e){if(void 0===(e=this.#p(t,e)))throw new TypeError(`Failed to set the ${t} property on CircleProgress: The provided value is non-finite.`);this.#m(t,e)}#d=null;updateComplete=null;#m(t,e){this.#d||(this.#d={},this.updateComplete=Promise.resolve().then((()=>this.#c()))),this.#d[t]=e}#c(){if(!this.#d)return;const t=this.#d;this.#d=null;let e=t.min??this.#l.min,a=t.max??this.#l.max;"min"in t&&t.min>=a&&(e=t.min=a),"max"in t&&t.max<=e&&(a=t.max=e),"value"in t&&!(t.unconstrained??this.#l.unconstrained)&&(null!=e&&t.value<e&&(t.value=e),null!=a&&t.value>a&&(t.value=a));for(const[e,a]of Object.entries(t))if(this.#l[e]!==a){if(this.#l[e]=a,e in h&&(void 0!==a?this.graph.paper.svg.setAttribute(h[e],a):this.graph.paper.svg.removeAttribute(h[e])),["min","max","unconstrained"].includes(e)&&(this.value>this.max||this.value<this.min)&&(this.value=Math.min(this.max,Math.max(this.min,this.value))),"textFormat"===e){this.#h();const t="valueOnCircle"===a?16:8;this.graph.sector.attr("stroke-width",t),this.graph.circle.attr("stroke-width",t)}this.reflectPropToAttribute(e)}this.updateGraph()}#p(t,e){switch(t){case"value":case"min":case"max":e=Number(e),Number.isFinite(e)||(e=void 0);break;case"startAngle":e=Number(e),e=Number.isFinite(e)?Math.max(0,Math.min(360,e)):void 0;break;case"anticlockwise":case"unconstrained":e=!!e;break;case"indeterminateText":e=String(e);break;case"textFormat":if("function"!=typeof e&&!["valueOnCircle","horizontal","vertical","percent","value","none"].includes(e))throw new Error(`Failed to set the "textFormat" property on CircleProgress: the provided value "${e}" is not a legal textFormat identifier.`);break;case"animation":if("string"!=typeof e&&"function"!=typeof e)throw new TypeError(`Failed to set "animation" property on CircleProgress: the value must be either string or function, ${typeof e} passed.`);if("string"==typeof e&&"none"!==e&&!n[e])throw new Error(`Failed to set "animation" on CircleProgress: the provided value ${e} is not a legal easing function name.`)}return e}#x(t=this.value){return Math.min(360,Math.max(0,(t-this.min)/(this.max-this.min)*360))}#f(){return["value","max","min"].some((t=>"number"!=typeof this[t]))}#g(t,e){const a=s(e,t);this.graph.textVal.attr({x:50+a.x,y:50+a.y})}#h(){const t=this.textFormat;switch(this.graph.text.content(""),"string"==typeof t&&["valueOnCircle","horizontal","vertical"].includes(t)&&(this.graph.textVal=this.graph.paper.element("tspan",{class:"text-value",part:"text-value"},"",this.graph.text),["horizontal","vertical"].includes(t)&&(this.graph.textSeparator=this.graph.paper.element("tspan",{class:"text-separator",part:"text-separator"},"",this.graph.text)),this.graph.textMax=this.graph.paper.element("tspan",{class:"text-max",part:"text-max"},"",this.graph.text)),t){case"valueOnCircle":this.graph.textVal.attr({x:0,y:0}),this.graph.textMax.attr({x:50,y:50});break;case"horizontal":this.graph.textSeparator.content("/");break;case"vertical":this.graph.textVal.attr({x:50,dy:"-0.25em"}),this.graph.textSeparator.attr({x:50,dy:"0.1em"}).content("___"),this.graph.textMax.attr({x:50,dy:"1.2em"})}}#v=null;updateGraph(){const t=this.startAngle-90,e=this.getRadius();if(this.#v?.cancel(),this.#f())this.#b(this.value,t,e);else{const a=!this.anticlockwise;let i=this.#x();this.graph.circle.attr("r",e),"none"!==this.animation&&this.value!==this.graph.value?this.#v=function(t,e,a,i,r){const s="string"==typeof t?n[t]:t;let o,h;const u=function(t){o||(o=t),t-=o,t=Math.min(t,i);const n=s(t,e,a,i);r(n),t<i?h=requestAnimationFrame(u):r(e+a)};return h=requestAnimationFrame(u),{cancel:()=>{cancelAnimationFrame(h)}}}(this.animation,this.graph.value,this.value-this.graph.value,this.animationDuration,(r=>{i=this.#x(r),this.graph.sector.attr("d",o(50,50,e,t,i,a)),this.#b(r===this.value?r:Math.round(r),(2*t+i)/2,e)})):(this.graph.sector.attr("d",o(50,50,e,t,i,a)),this.#b(this.value,(2*t+i)/2,e)),this.graph.value=this.value}}#b(t,e,a){if("function"!=typeof this.textFormat)switch(this.textFormat){case"value":this.graph.text.el.textContent=void 0!==t?t:this.indeterminateText;break;case"percent":this.graph.text.el.textContent=(void 0!==t&&null!=this.max?Math.round(t/this.max*100):this.indeterminateText)+"%";break;case"none":this.graph.text.el.textContent="";break;default:this.graph.textVal.el.textContent=void 0!==t?t:this.indeterminateText,this.graph.textMax.el.textContent=void 0!==this.max?this.max:this.indeterminateText,"valueOnCircle"===this.textFormat&&this.#g(e,a)}else this.graph.text.content(this.textFormat(t,this.max))}getRadius(){return 50-Math.max(this.#y(this.graph.circle.el),this.#y(this.graph.sector.el))/2}#y(t){return Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(t)["stroke-width"]||0)}}customElements.define("circle-progress",u);export{u as default};
class t extends HTMLElement{static styles="";static props={};#t={};#e={};#a=new Set;constructor(){super();const t=this.attachShadow({mode:"open"}),{styles:e}=this.constructor;if(e){const a=document.createElement("style");a.textContent=e,t.append(a)}const{props:a}=this.constructor;if(a)for(const[t,e]of Object.entries(a))e.attribute&&(this.#t[t]=e.attribute,this.#e[e.attribute]=t),e.type===Boolean&&this.#a.add(t)}attributeUpdated(t,e){}_attrNameToProp(t){return this.#e[t]??t}_propToAttrName(t){return this.#t[t]??t}_attrValToProp(t,e){return this.#a.has(t)?null!==e:e}#i=!1;attributeChangedCallback(t,e,a){this.#i?this.#i=!1:this.attributeUpdated?.(this._attrNameToProp(t),this._attrValToProp(t,a))}reflectPropToAttribute(t){const e=this[t];this.#i=!0;const a=this._propToAttrName(t);this.#a.has(t)?e?this.setAttribute(a,""):this.removeAttribute(a):"function"==typeof e?this.removeAttribute(a):this.setAttribute(a,String(e))}}const e=function(t,e,i,r){r=r||document;const n=Object.create(a);if("string"==typeof t&&(t=r.querySelector(t)),!t)return;const s=r.createElementNS("http://www.w3.org/2000/svg","svg");return s.setAttribute("version","1.1"),e&&s.setAttribute("width",String(e)),i&&s.setAttribute("height",String(i)),e&&i&&s.setAttribute("viewBox","0 0 "+e+" "+i),t.appendChild(s),n.svg=s,n},a={element:function(t,e,a,r){const n=i(this,t,e,r);return a&&(n.el.innerHTML=a),n}},i=function(t,e,a,i,n){n=n||document;const s=Object.create(r);return s.el=n.createElementNS("http://www.w3.org/2000/svg",e),s.attr(a),(i?"el"in i?i.el:i:t.svg).appendChild(s.el),s},r={attr:function(t,e){if(void 0===t)return this;if("object"==typeof t){for(let e in t)this.attr(e,t[e]);return this}return void 0===e?this.el.getAttributeNS(null,t):(this.el.setAttribute(t,e),this)},content:function(t){return this.el.innerHTML=t,this}},n={linear:function(t,e,a,i){return a*t/i+e},easeInQuad:function(t,e,a,i){return a*(t/=i)*t+e},easeOutQuad:function(t,e,a,i){return-a*(t/=i)*(t-2)+e},easeInOutQuad:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t+e:-a/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,a,i){return a*(t/=i)*t*t+e},easeOutCubic:function(t,e,a,i){return t/=i,a*(--t*t*t+1)+e},easeInOutCubic:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t+e:a/2*((t-=2)*t*t+2)+e},easeInQuart:function(t,e,a,i){return a*(t/=i)*t*t*t+e},easeOutQuart:function(t,e,a,i){return t/=i,-a*(--t*t*t*t-1)+e},easeInOutQuart:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t*t+e:-a/2*((t-=2)*t*t*t-2)+e},easeInQuint:function(t,e,a,i){return a*(t/=i)*t*t*t*t+e},easeOutQuint:function(t,e,a,i){return t/=i,a*(--t*t*t*t*t+1)+e},easeInOutQuint:function(t,e,a,i){return(t/=i/2)<1?a/2*t*t*t*t*t+e:a/2*((t-=2)*t*t*t*t+2)+e},easeInSine:function(t,e,a,i){return-a*Math.cos(t/i*(Math.PI/2))+a+e},easeOutSine:function(t,e,a,i){return a*Math.sin(t/i*(Math.PI/2))+e},easeInOutSine:function(t,e,a,i){return-a/2*(Math.cos(Math.PI*t/i)-1)+e},easeInExpo:function(t,e,a,i){return a*Math.pow(2,10*(t/i-1))+e},easeOutExpo:function(t,e,a,i){return a*(1-Math.pow(2,-10*t/i))+e},easeInOutExpo:function(t,e,a,i){return(t/=i/2)<1?a/2*Math.pow(2,10*(t-1))+e:(t--,a/2*(2-Math.pow(2,-10*t))+e)},easeInCirc:function(t,e,a,i){return t/=i,-a*(Math.sqrt(1-t*t)-1)+e},easeOutCirc:function(t,e,a,i){return t/=i,t--,a*Math.sqrt(1-t*t)+e},easeInOutCirc:function(t,e,a,i){return(t/=i/2)<1?-a/2*(Math.sqrt(1-t*t)-1)+e:(t-=2,a/2*(Math.sqrt(1-t*t)+1)+e)}},s=(t,e)=>({x:t*Math.cos(e*Math.PI/180),y:t*Math.sin(e*Math.PI/180)}),o=(t,e,a,i,r,n=!1)=>{r>0&&r<.3?r=0:r>359.999&&(r=359.999);const o=i+r*(2*+n-1),h=s(a,i),u=s(a,o),l=t+h.x,c=t+u.x;return["M",l,e+h.y,"A",a,a,0,+(r>180),+n,c,e+u.y].join(" ")};const h={value:"aria-valuenow",min:"aria-valuemin",max:"aria-valuemax"};class u extends t{static styles='\n\t:host(:not([hidden])) {\n\t\tdisplay: inline-block;\n\t}\n\n\t.circle {\n\t\tfill: none;\n\t\tstroke: #ddd;\n\t}\n\n\t.value {\n\t\tfill: none;\n\t\tstroke: #00E699;\n\t}\n\n\t.text {\n\t\tfont: 16px Arial, sans-serif;\n\t\ttext-anchor: middle;\n\t\tfill: #999;\n\t}\n\n\t:host([text-format="valueOnCircle"]) .text-value {\n\t\tfont-size: 12px;\n\t\tfill: #fff;\n\t}\n\n\t:host([text-format="valueOnCircle"]) .text-max {\n\t\tfont-size: 22px;\n\t\tfont-weight: bold;\n\t\tfill: #ddd;\n\t}\n\n\t:host([text-format="vertical"]) .text-separator {\n\t\tfont-family: Arial, sans-serif !important;\n\t}\n';value;min;max;startAngle;anticlockwise;unconstrained;indeterminateText;textFormat;animation;animationDuration;static props={value:!0,min:!0,max:!0,startAngle:{attribute:"start-angle"},anticlockwise:{type:Boolean},unconstrained:{type:Boolean},indeterminateText:{attribute:"indeterminate-text"},textFormat:{attribute:"text-format"},animation:!0,animationDuration:{attribute:"animation-duration"}};static get observedAttributes(){return Object.entries(this.props).map((([t,e])=>e&&"object"==typeof e&&e.attribute||t))}static defaults={startAngle:0,min:0,max:1,unconstrained:!1,indeterminateText:"?",anticlockwise:!1,textFormat:"horizontal",animation:"easeInOutCubic",animationDuration:600};constructor(t={}){let a;super(),Object.defineProperties(this,Object.keys(u.props).reduce(((t,e)=>(t[e]={get(){return this._get(e)},set(t){this.attr(e,t)}},t)),{})),a="valueOnCircle"===(t={...u.defaults,...t}).textFormat?16:8,this.graph={paper:e(this.shadowRoot,100,100),value:0},this.graph.paper.svg.setAttribute("class","base"),this.graph.paper.svg.setAttribute("part","base"),this.graph.paper.svg.setAttribute("role","progressbar"),this.graph.circle=this.graph.paper.element("circle").attr({class:"circle",part:"circle",cx:50,cy:50,r:50-a/2,"stroke-width":a}),this.graph.sector=this.graph.paper.element("path").attr({d:o(50,50,50-a/2,0,0),class:"value",part:"value","stroke-width":a}),this.graph.text=this.graph.paper.element("text",{class:"text",part:"text",x:50,y:50}),this._initText(),Object.keys(u.props).forEach((e=>e in t&&this._set(e,t[e])))}attributeUpdated(t,e){this._set(t,e)}#r={};attr(t){if(!["string","object"].includes(typeof t))throw new TypeError(`Wrong argument passed to attr. Expected object, got "${typeof t}"`);if("string"==typeof t){if(1===arguments.length)return this._get(t);t=[[t,arguments[1]]]}return Array.isArray(t)||(t=Object.keys(t).map((e=>[e,t[e]]))),t.forEach((([t,e])=>this._set(t,e))),this}_get(t){return this._flushBatch(),this.#r[t]}_set(t,e){if(void 0===(e=this._formatValue(t,e)))throw new TypeError(`Failed to set the ${t} property on CircleProgress: The provided value is non-finite.`);this._scheduleUpdate(t,e)}#n=null;updateComplete=null;_scheduleUpdate(t,e){this.#n||(this.#n={},this.updateComplete=Promise.resolve().then((()=>this._flushBatch()))),this.#n[t]=e}_flushBatch(){if(!this.#n)return;const t=this.#n;this.#n=null;let e=t.min??this.#r.min,a=t.max??this.#r.max;"min"in t&&t.min>=a&&(e=t.min=a),"max"in t&&t.max<=e&&(a=t.max=e),"value"in t&&!(t.unconstrained??this.#r.unconstrained)&&(null!=e&&t.value<e&&(t.value=e),null!=a&&t.value>a&&(t.value=a));for(const[e,a]of Object.entries(t))if(this.#r[e]!==a){if(this.#r[e]=a,e in h&&(void 0!==a?this.graph.paper.svg.setAttribute(h[e],a):this.graph.paper.svg.removeAttribute(h[e])),["min","max","unconstrained"].includes(e)&&(this.value>this.max||this.value<this.min)&&(this.value=Math.min(this.max,Math.max(this.min,this.value))),"textFormat"===e){this._initText();const t="valueOnCircle"===a?16:8;this.graph.sector.attr("stroke-width",t),this.graph.circle.attr("stroke-width",t)}this.reflectPropToAttribute(e)}this.updateGraph()}_formatValue(t,e){switch(t){case"value":case"min":case"max":e=Number(e),Number.isFinite(e)||(e=void 0);break;case"startAngle":e=Number(e),e=Number.isFinite(e)?Math.max(0,Math.min(360,e)):void 0;break;case"anticlockwise":case"unconstrained":e=!!e;break;case"indeterminateText":e=String(e);break;case"textFormat":if("function"!=typeof e&&!["valueOnCircle","horizontal","vertical","percent","value","none"].includes(e))throw new Error(`Failed to set the "textFormat" property on CircleProgress: the provided value "${e}" is not a legal textFormat identifier.`);break;case"animation":if("string"!=typeof e&&"function"!=typeof e)throw new TypeError(`Failed to set "animation" property on CircleProgress: the value must be either string or function, ${typeof e} passed.`);if("string"==typeof e&&"none"!==e&&!n[e])throw new Error(`Failed to set "animation" on CircleProgress: the provided value ${e} is not a legal easing function name.`)}return e}_valueToAngle(t=this.value){return Math.min(360,Math.max(0,(t-this.min)/(this.max-this.min)*360))}_isIndeterminate(){return["value","max","min"].some((t=>"number"!=typeof this[t]))}_positionValueText(t,e){const a=s(e,t);this.graph.textVal.attr({x:50+a.x,y:50+a.y})}_initText(){const t=this.textFormat;switch(this.graph.text.content(""),"string"==typeof t&&["valueOnCircle","horizontal","vertical"].includes(t)&&(this.graph.textVal=this.graph.paper.element("tspan",{class:"text-value",part:"text-value"},"",this.graph.text),["horizontal","vertical"].includes(t)&&(this.graph.textSeparator=this.graph.paper.element("tspan",{class:"text-separator",part:"text-separator"},"",this.graph.text)),this.graph.textMax=this.graph.paper.element("tspan",{class:"text-max",part:"text-max"},"",this.graph.text)),t){case"valueOnCircle":this.graph.textVal.attr({x:0,y:0,dy:"0.4em"}),this.graph.textMax.attr({x:50,y:50,dy:"0.4em"});break;case"horizontal":this.graph.textSeparator.content("/");break;case"vertical":this.graph.textVal.attr({x:50,dy:"-0.25em"}),this.graph.textSeparator.attr({x:50,dy:"0.1em"}).content("___"),this.graph.textMax.attr({x:50,dy:"1.2em"})}this.graph.text.attr("dy","vertical"===t?"":"0.4em")}#s=null;updateGraph(){const t=this.startAngle-90,e=this.getRadius();if(this.#s?.cancel(),this._isIndeterminate())this._updateText(this.value,t,e);else{const a=!this.anticlockwise;let i=this._valueToAngle();this.graph.circle.attr("r",e),"none"!==this.animation&&this.value!==this.graph.value?this.#s=function(t,e,a,i,r){const s="string"==typeof t?n[t]:t;let o,h;const u=function(t){o||(o=t),t-=o,t=Math.min(t,i);const n=s(t,e,a,i);r(n),t<i?h=requestAnimationFrame(u):r(e+a)};return h=requestAnimationFrame(u),{cancel:()=>{cancelAnimationFrame(h)}}}(this.animation,this.graph.value,this.value-this.graph.value,this.animationDuration,(r=>{i=this._valueToAngle(r),this.graph.sector.attr("d",o(50,50,e,t,i,a)),this._updateText(r===this.value?r:Math.round(r),(2*t+i)/2,e)})):(this.graph.sector.attr("d",o(50,50,e,t,i,a)),this._updateText(this.value,(2*t+i)/2,e)),this.graph.value=this.value}}_updateText(t,e,a){if("function"!=typeof this.textFormat)switch(this.textFormat){case"value":this.graph.text.el.textContent=void 0!==t?t:this.indeterminateText;break;case"percent":this.graph.text.el.textContent=(void 0!==t&&null!=this.max?Math.round(t/this.max*100):this.indeterminateText)+"%";break;case"none":this.graph.text.el.textContent="";break;default:this.graph.textVal.el.textContent=void 0!==t?t:this.indeterminateText,this.graph.textMax.el.textContent=void 0!==this.max?this.max:this.indeterminateText,"valueOnCircle"===this.textFormat&&this._positionValueText(e,a)}else this.graph.text.content(this.textFormat(t,this.max))}getRadius(){return 50-Math.max(this._getStrokeWidth(this.graph.circle.el),this._getStrokeWidth(this.graph.sector.el))/2}_getStrokeWidth(t){return Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(t)["stroke-width"]||0)}}customElements.define("circle-progress",u);export{u as default};
//# sourceMappingURL=circle-progress.min.js.map

@@ -11,2 +11,21 @@ export default class CustomElement extends HTMLElement {

attributeUpdated(prop: string, value: any): void;
/**
* Convert attribute name to property name
* @param {string} name Attribute name
* @return {string} Property name
*/
_attrNameToProp(name: string): string;
/**
* Convert property name to attribute name
* @param {string} name Property name
* @return {string} Attribute name
*/
_propToAttrName(name: string): string;
/**
* Convert attribute value to property value
* @param {string} name Attribute name
* @param {(string|null)} value Attribute value
* @return Property value
*/
_attrValToProp(name: string, value: (string | null)): string | boolean;
attributeChangedCallback(name: any, _: any, newValue: any): void;

@@ -13,0 +32,0 @@ reflectPropToAttribute(prop: any): void;

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

declare const _default: "\n\t:host(:not([hidden])) {\n\t\tdisplay: inline-block;\n\t}\n\n\t.circle {\n\t\tfill: none;\n\t\tstroke: #ddd;\n\t}\n\n\t.value {\n\t\tfill: none;\n\t\tstroke: #00E699;\n\t}\n\n\t.text {\n\t\tfont: 16px Arial, sans-serif;\n\t\ttext-anchor: middle;\n\t\tfill: #999;\n\t}\n\n\t:host([text-format=\"valueOnCircle\"]) .text-value {\n\t\tfont-size: 12px;\n\t\tfill: #fff;\n\t}\n\n\t:host([text-format=\"valueOnCircle\"]) .text-max {\n\t\tfont-size: 22px;\n\t\tfont-weight: bold;\n\t\tfill: #ddd;\n\t}\n\n\t:host([text-format=\"vertical\"]) .text-separator {\n\t\tfont-family: Arial, sans-serif !important;\n\t}\n\n\t:host(:not([text-format=\"vertical\"])) .text {\n\t\tdominant-baseline: middle;\n\t}\n";
declare const _default: "\n\t:host(:not([hidden])) {\n\t\tdisplay: inline-block;\n\t}\n\n\t.circle {\n\t\tfill: none;\n\t\tstroke: #ddd;\n\t}\n\n\t.value {\n\t\tfill: none;\n\t\tstroke: #00E699;\n\t}\n\n\t.text {\n\t\tfont: 16px Arial, sans-serif;\n\t\ttext-anchor: middle;\n\t\tfill: #999;\n\t}\n\n\t:host([text-format=\"valueOnCircle\"]) .text-value {\n\t\tfont-size: 12px;\n\t\tfill: #fff;\n\t}\n\n\t:host([text-format=\"valueOnCircle\"]) .text-max {\n\t\tfont-size: 22px;\n\t\tfont-weight: bold;\n\t\tfill: #ddd;\n\t}\n\n\t:host([text-format=\"vertical\"]) .text-separator {\n\t\tfont-family: Arial, sans-serif !important;\n\t}\n";
export default _default;
{
"name": "js-circle-progress",
"version": "1.0.0-alpha.0",
"version": "1.0.0-alpha.1",
"description": "Responsive, accessible, animated, stylable with CSS circular progress bar available as plain (vanilla) JS and jQuery plugin.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -19,3 +19,3 @@ # Circle Progress

### Breaking changes since v0
- Internet Explorer is no longer supported.
- Internet Explorer and Safari below version 14 are no longer supported.
- The jQuery variant of the library is no longer provided.

@@ -41,3 +41,3 @@ - The library is only shipped as an ES module.

```shell
$ npm install --save js-circle-progress@latest
$ npm install --save js-circle-progress
```

@@ -90,3 +90,3 @@

```html
<script src="https://unpkg.com/js-circle-progress@latest/dist/circle-progress.min.js" type="module"></script>
<script src="https://unpkg.com/js-circle-progress/dist/circle-progress.min.js" type="module"></script>

@@ -217,3 +217,3 @@ <circle-progress value="50" max="100"></circle-progress>

Chrome, Firefox, Safari (starting with 13.0), Edge are supported.
Chrome, Firefox, Safari (starting with version 15), Edge are supported.

@@ -238,5 +238,5 @@ ## Contributing

[vanilla-min]: https://unpkg.com/js-circle-progress@latest/dist/circle-progress.min.js
[vanilla-min]: https://unpkg.com/js-circle-progress/dist/circle-progress.min.js
[site]: https://tigrr.github.io/circle-progress/
[examples]: https://tigrr.github.io/circle-progress/examples.html
[license]: https://github.com/tigrr/circle-progress/blob/master/LICENSE

@@ -127,3 +127,3 @@ /**

get() {
return this.#get(prop);
return this._get(prop);
},

@@ -173,5 +173,5 @@ set(val) {

});
this.#initText();
this._initText();
Object.keys(CircleProgress.props)
.forEach(key => key in opts && this.#set(key, opts[key]));
.forEach(key => key in opts && this._set(key, opts[key]));
}

@@ -181,3 +181,3 @@

attributeUpdated(name, newValue) {
this.#set(name, newValue)
this._set(name, newValue)
}

@@ -200,3 +200,3 @@

if(arguments.length === 1) {
return this.#get(attrs);
return this._get(attrs);
}

@@ -210,3 +210,3 @@ attrs = [[attrs, arguments[1]]];

attrs.forEach(([key, value]) => this.#set(key, value));
attrs.forEach(([key, value]) => this._set(key, value));
return this;

@@ -219,4 +219,4 @@ }

*/
#get(key) {
this.#flushBatch();
_get(key) {
this._flushBatch();
return this.#attrs[key];

@@ -232,6 +232,6 @@ }

*/
#set(key, val) {
val = this.#formatValue(key, val);
_set(key, val) {
val = this._formatValue(key, val);
if(val === undefined) throw new TypeError(`Failed to set the ${key} property on CircleProgress: The provided value is non-finite.`);
this.#scheduleUpdate(key, val);
this._scheduleUpdate(key, val);
}

@@ -254,6 +254,6 @@

*/
#scheduleUpdate(key, val) {
_scheduleUpdate(key, val) {
if(!this.#batch) {
this.#batch = {};
this.updateComplete = Promise.resolve().then(() => this.#flushBatch());
this.updateComplete = Promise.resolve().then(() => this._flushBatch());
}

@@ -263,3 +263,3 @@ this.#batch[key] = val;

#flushBatch() {
_flushBatch() {
if (!this.#batch) {

@@ -298,3 +298,3 @@ return;

if(key === 'textFormat') {
this.#initText();
this._initText();
const circleThickness = val === 'valueOnCircle' ? 16 : 8;

@@ -316,3 +316,3 @@ this.graph.sector.attr('stroke-width', circleThickness);

*/
#formatValue(key, val) {
_formatValue(key, val) {
switch(key) {

@@ -361,3 +361,3 @@ case 'value':

*/
#valueToAngle(value = this.value) {
_valueToAngle(value = this.value) {
return Math.min(

@@ -377,3 +377,3 @@ 360,

*/
#isIndeterminate() {
_isIndeterminate() {
return ['value', 'max', 'min'].some(key => typeof this[key] !== 'number');

@@ -391,3 +391,3 @@ }

*/
#positionValueText(angle, r) {
_positionValueText(angle, r) {
const coords = polarToCartesian(r, angle);

@@ -401,3 +401,3 @@ this.graph.textVal.attr({x: 50 + coords.x, y: 50 + coords.y});

*/
#initText() {
_initText() {
const format = this.textFormat;

@@ -432,2 +432,3 @@ this.graph.text.content('');

y: 0,
dy: '0.4em',
});

@@ -437,2 +438,3 @@ this.graph.textMax.attr({

y: 50,
dy: '0.4em',
});

@@ -451,2 +453,3 @@ break;

}
this.graph.text.attr('dy', format === 'vertical' ? '' : '0.4em');
}

@@ -468,19 +471,19 @@

this.#animator?.cancel()
if(!this.#isIndeterminate()) {
if(!this._isIndeterminate()) {
const clockwise = !this.anticlockwise;
let angle = this.#valueToAngle();
let angle = this._valueToAngle();
this.graph.circle.attr('r', r);
if(this.animation !== 'none' && this.value !== this.graph.value) {
this.#animator = animator(this.animation, this.graph.value, this.value - this.graph.value, this.animationDuration, value => {
angle = this.#valueToAngle(value);
angle = this._valueToAngle(value);
this.graph.sector.attr('d', makeSectorPath(50, 50, r, startAngle, angle, clockwise));
this.#updateText(value === this.value ? value : Math.round(value), (2 * startAngle + angle) / 2, r);
this._updateText(value === this.value ? value : Math.round(value), (2 * startAngle + angle) / 2, r);
});
} else {
this.graph.sector.attr('d', makeSectorPath(50, 50, r, startAngle, angle, clockwise));
this.#updateText(this.value, (2 * startAngle + angle) / 2, r);
this._updateText(this.value, (2 * startAngle + angle) / 2, r);
}
this.graph.value = this.value;
} else {
this.#updateText(this.value, startAngle, r);
this._updateText(this.value, startAngle, r);
}

@@ -492,3 +495,3 @@ }

*/
#updateText(value, angle, r) {
_updateText(value, angle, r) {
if(typeof this.textFormat === 'function') {

@@ -513,3 +516,3 @@ this.graph.text.content(this.textFormat(value, this.max));

if(this.textFormat === 'valueOnCircle') {
this.#positionValueText(angle, r);
this._positionValueText(angle, r);
}

@@ -526,4 +529,4 @@ }

return 50 - Math.max(
this.#getStrokeWidth(this.graph.circle.el),
this.#getStrokeWidth(this.graph.sector.el),
this._getStrokeWidth(this.graph.circle.el),
this._getStrokeWidth(this.graph.sector.el),
) / 2;

@@ -535,3 +538,3 @@ }

*/
#getStrokeWidth(el) {
_getStrokeWidth(el) {
return Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(el)['stroke-width'] || 0);

@@ -538,0 +541,0 @@ }

@@ -53,3 +53,3 @@ export default class CustomElement extends HTMLElement {

*/
#attrNameToProp(name) {
_attrNameToProp(name) {
return this.#attrToPropDict[name] ?? name

@@ -63,3 +63,3 @@ }

*/
#propToAttrName(name) {
_propToAttrName(name) {
return this.#propToAttrDict[name] ?? name

@@ -74,3 +74,3 @@ }

*/
#attrValToProp(name, value) {
_attrValToProp(name, value) {
if (this.#boolProps.has(name)) {

@@ -89,3 +89,3 @@ return value !== null

}
this.attributeUpdated?.(this.#attrNameToProp(name), this.#attrValToProp(name, newValue))
this.attributeUpdated?.(this._attrNameToProp(name), this._attrValToProp(name, newValue))
}

@@ -96,3 +96,3 @@

this.#bailOutAttrUpdate = true
const attr = this.#propToAttrName(prop)
const attr = this._propToAttrName(prop)
if (this.#boolProps.has(prop)) {

@@ -99,0 +99,0 @@ if (value) {

@@ -36,6 +36,2 @@ export default /* css */`

}
:host(:not([text-format="vertical"])) .text {
dominant-baseline: middle;
}
`

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc