@privacyscrubber/sdk 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,21 +1,32 @@
1
1
  # @privacyscrubber/sdk
2
2
 
3
+ [![NPM Version](https://img.shields.io/npm/v/@privacyscrubber/sdk?color=10b981&label=version)](https://www.npmjs.com/package/@privacyscrubber/sdk)
4
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-success.svg)](https://www.npmjs.com/package/@privacyscrubber/sdk)
5
+ [![Latency](https://img.shields.io/badge/latency-%3C1ms-brightgreen.svg)](https://privacyscrubber.com/dlp-speed-test/)
6
+ [![Air-Gapped](https://img.shields.io/badge/network_calls-0-blueviolet.svg)](https://privacyscrubber.com)
7
+ [![TypeScript Typings](https://img.shields.io/badge/types-TypeScript-blue.svg)](https://www.npmjs.com/package/@privacyscrubber/sdk)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+
3
10
  > **Zero-Trust Data Sanitization (ZTDS) & PII Redaction Engine**
4
- > 100% Client-Side & In-Memory Execution. Zero Data Leakage. Zero Network Requests for Sanitization.
11
+ > 100% In-Memory Execution. Zero Remote Network Calls. Zero Disk Writes. Sub-millisecond Latency.
5
12
 
6
- The official Node.js / Browser SDK for [PrivacyScrubber.com](https://privacyscrubber.com). It provides enterprise-grade PII sanitization, cloud secrets redaction, cryptographic license enforcement, and deterministic token restoration for AI pipelines (OpenAI, Anthropic, LangChain, LlamaIndex).
13
+ The official Node.js / TypeScript programmatic SDK for [PrivacyScrubber.com](https://privacyscrubber.com). Provides enterprise-grade PII sanitization, cloud secrets detection, compliance audit receipts, and deterministic token restoration for AI pipelines (OpenAI, Anthropic, LangChain, LlamaIndex, RAG vector stores).
7
14
 
8
15
  ---
9
16
 
10
- ## ⚡ Highlights
17
+ ## ⚡ Why @privacyscrubber/sdk vs Cloud DLP / Presidio?
18
+
19
+ | Dimension | `@privacyscrubber/sdk` | MS Presidio | Google Cloud DLP | AWS Comprehend |
20
+ | :--- | :--- | :--- | :--- | :--- |
21
+ | **Execution Model** | **Local In-Memory (<1ms)** | Self-hosted Python (~35ms) | Cloud API Proxy (180–400ms) | Cloud API Proxy (200–500ms) |
22
+ | **Network Egress** | **0 Bytes (Air-gapped)** | 0 Bytes (Internal hop) | Full unencrypted payload | Full unencrypted payload |
23
+ | **Runtime Footprint** | **~150KB (0 dependencies)** | ~500MB (Python + spaCy) | Cloud SDK | Cloud SDK |
24
+ | **OpenAI 1-Line Drop-in** | **Yes (`wrapOpenAI`)** | Custom wrapper required | Custom pipeline | Custom pipeline |
25
+ | **Deterministic Reverse** | **Built-in (`restore`)** | Manual token map logic | Manual vault mapping | Manual token mapping |
26
+ | **DevOps Secrets Scanning** | **Built-in (AWS, JWT, DBs)** | Custom regex rules | Custom detectors | Custom classifiers |
27
+ | **Cost Predictability** | **Free Tier / Flat $299/mo** | DevOps server maintenance | Pay-per-GB cloud fees | Pay-per-unit API fees |
11
28
 
12
- - 🛡️ **Zero-Trust & In-Memory**: All sanitization executes locally in RAM. No PII or raw text is ever transmitted over the network.
13
- - 🤖 **Transparent AI Wrapper**: `wrapOpenAI(client)` automatically scrubs sensitive tokens before outbound API requests and deterministically restores them in responses.
14
- - ⚡ **High Throughput**: Under 2ms average execution time per 10k characters.
15
- - 📋 **23 Industry Compliance Profiles**: General, Dev/DevOps, Medical (HIPAA), Financial (PCI-DSS), Legal, HR, Executive, and more.
16
- - 🧾 **CISO Audit Receipts**: Automated generation of Markdown compliance receipts (GDPR Art. 4, HIPAA §164.514, SOC 2 Type II, ISO 27001, NIST SP 800-53).
17
- - 🔑 **Cryptographic License Engine**: Native RS256 JWT and cryptographic checksum verification.
18
- - 🏷️ **TypeScript Support**: Full `.d.ts` typings included out of the box.
29
+ > 📊 **Full Technical Benchmark**: Read the in-depth latency analysis, cold-start profiles, and architecture deep-dive in [docs/benchmarks/sdk-vs-presidio.md](https://github.com/moxno/PrivacyScrubber/blob/main/docs/benchmarks/sdk-vs-presidio.md).
19
30
 
20
31
  ---
21
32
 
@@ -29,230 +40,181 @@ npm install @privacyscrubber/sdk
29
40
 
30
41
  ## 🚀 Quickstart
31
42
 
32
- ### 1. Simple Sanitize & Restore
43
+ ### 1. Transparent OpenAI Client Wrapper (1 Line of Code)
44
+
45
+ Zero changes to your prompt logic. Wrapping your OpenAI client intercepts outbound prompts in memory, replaces PII with tokens like `[NAME_1]`, and rehydrates the original data into the assistant's response:
46
+
47
+ ```javascript
48
+ import OpenAI from 'openai';
49
+ import { wrapOpenAI } from '@privacyscrubber/sdk';
50
+
51
+ // Wrap your existing OpenAI client instance
52
+ const openai = wrapOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
53
+
54
+ // Outbound prompt is sanitized in local RAM before leaving your machine:
55
+ // "Contact [NAME_1] at [EMAIL_1] regarding invoice #99281."
56
+ const completion = await openai.chat.completions.create({
57
+ model: 'gpt-4o',
58
+ messages: [
59
+ { role: 'user', content: 'Contact Alice Smith at alice@acme.com regarding invoice #99281.' }
60
+ ]
61
+ });
62
+
63
+ // Incoming LLM answer is automatically rehydrated with "Alice Smith (alice@acme.com)":
64
+ console.log(completion.choices[0].message.content);
65
+ ```
66
+
67
+ ---
68
+
69
+ ### 2. Direct In-Memory Sanitization & Restoration
33
70
 
34
71
  ```javascript
35
72
  import { sanitize, restore } from '@privacyscrubber/sdk';
36
73
 
37
- const rawPrompt = "Hello, my name is Alice Smith and my email is alice@corp.com.";
74
+ const rawPrompt = "Hello, my name is John Doe and my phone is 555-0199.";
38
75
 
39
76
  // 1. Sanitize text before sending to LLM
40
77
  const { scrubbedText, tokenMap, telemetry, auditReceipt } = sanitize(rawPrompt);
41
78
 
42
79
  console.log(scrubbedText);
43
- // "Hello, my name is [NAME_1] and my email is [EMAIL_1]."
80
+ // "Hello, my name is [NAME_1] and my phone is [PHONE_1]."
44
81
 
45
82
  console.log(auditReceipt);
46
83
  // > 🛡️ **PrivacyScrubber Audit Receipt**
47
- // > * **Risk Level:** 🔴 CRITICAL (HIGH EXPOSURE)
84
+ // > * **Risk Level:** 🟡 MODERATE EXPOSURE
48
85
  // > * **Compliance Enforced:** ZTDS Standard, GDPR (Art. 4), CCPA/CPRA
49
- // > * **Tokens Masked:** 2 (1 NAME, 1 EMAIL)
86
+ // > * **Tokens Masked:** 2 (1 NAME, 1 PHONE)
50
87
 
51
- // 2. Restore response from LLM
52
- const aiResponse = "I have drafted a confirmation email to [NAME_1] ([EMAIL_1]).";
88
+ // 2. Deterministically restore LLM response
89
+ const aiResponse = "I have queued an SMS notification for [NAME_1] at [PHONE_1].";
53
90
  const { restoredText } = restore(aiResponse, tokenMap);
54
91
 
55
92
  console.log(restoredText);
56
- // "I have drafted a confirmation email to Alice Smith (alice@corp.com)."
93
+ // "I have queued an SMS notification for John Doe at 555-0199."
57
94
  ```
58
95
 
59
96
  ---
60
97
 
61
- ### 2. Transparent OpenAI Client Wrapper
98
+ ### 3. RAG & Vector Database Ingestion (Pinecone, Chroma, pgvector)
62
99
 
63
- Zero changes to your prompting architecture. Wrap your existing OpenAI SDK instance and PrivacyScrubber intercepts outbound prompts and restores incoming responses automatically:
100
+ Storing raw PII inside vector embeddings is irreversible and violates GDPR Article 17 (Right to be Forgotten). Sanitize document chunks prior to vectorization:
64
101
 
65
102
  ```javascript
66
- import OpenAI from 'openai';
67
- import { wrapOpenAI } from '@privacyscrubber/sdk';
68
-
69
- const openai = wrapOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
70
-
71
- // Prompts are scrubbed in RAM before leaving your server,
72
- // and the returned choice content is restored before reaching your application logic!
73
- const completion = await openai.chat.completions.create({
74
- model: 'gpt-4o',
75
- messages: [
76
- { role: 'user', content: 'Contact John Doe at john@acme.com regarding invoice #99281.' }
77
- ]
78
- });
103
+ import { sanitize } from '@privacyscrubber/sdk';
79
104
 
80
- console.log(completion.choices[0].message.content);
105
+ function prepareVectorChunk(rawDocumentChunk) {
106
+ const { scrubbedText, tokenMap, telemetry } = sanitize(rawDocumentChunk, {
107
+ profile: 'Healthcare', // Masks 18 HIPAA identifiers
108
+ detectSecrets: true // Masks API tokens, JWTs, DB credentials
109
+ });
110
+
111
+ // Embed only the sanitized text into your vector store
112
+ return {
113
+ anonymizedChunk: scrubbedText,
114
+ riskLevel: telemetry.riskLevel,
115
+ frameworks: telemetry.frameworksList
116
+ };
117
+ }
81
118
  ```
82
119
 
83
120
  ---
84
121
 
85
- ### 3. Stateful Conversational Engine (`PrivacyScrubberEngine`)
122
+ ### 4. Stateful Multi-Turn Agent Engine (`PrivacyScrubberEngine`)
86
123
 
87
- Maintain token map consistency across multi-turn chats or session threads:
124
+ Maintain token bindings across multi-step autonomous agent loops (LangChain, AutoGen, CrewAI):
88
125
 
89
126
  ```javascript
90
127
  import { PrivacyScrubberEngine } from '@privacyscrubber/sdk';
91
128
 
92
- const engine = new PrivacyScrubberEngine({ defaultProfile: 'General' });
129
+ const engine = new PrivacyScrubberEngine({ defaultProfile: 'Dev' });
93
130
 
94
- // Turn 1
95
- const turn1 = engine.sanitize("My name is John Doe and my phone is 555-0199.");
96
- // Tokens: [NAME_1], [PHONE_1]
131
+ // Turn 1: Assigns [NAME_1] to John Doe
132
+ const turn1 = engine.sanitize("John Doe initiated deployment on prod.");
97
133
 
98
- // Turn 2: Re-uses [NAME_1] for John Doe consistently
99
- const turn2 = engine.sanitize("John Doe needs an update on ticket #402.");
100
- // Tokens: [NAME_1]
134
+ // Turn 2: Engine remembers [NAME_1] is John Doe across the entire thread
135
+ const turn2 = engine.sanitize("Review logs for John Doe.");
136
+ // Result: "Review logs for [NAME_1]." (Token numbering is consistently preserved!)
101
137
 
102
138
  // Restore full thread context
103
- const restored = engine.restore("Notified [NAME_1] at [PHONE_1].");
104
- console.log(restored.restoredText);
105
- // "Notified John Doe at 555-0199."
139
+ const restored = engine.restore(agentOutputText);
106
140
  ```
107
141
 
108
142
  ---
109
143
 
110
- ### 4. Specialized Industry Profiles & DevOps Secrets
144
+ ## 🛡️ DevOps Secrets & Credentials Detection
111
145
 
112
- Sanitize AWS credentials, JWT tokens, Stripe API keys, database connection strings, and HIPAA records:
146
+ Auto-detect and strip infrastructure secrets alongside consumer PII:
113
147
 
114
148
  ```javascript
115
149
  import { sanitize } from '@privacyscrubber/sdk';
116
150
 
117
151
  const devLog = `
118
152
  AWS_KEY=AKIAIOSFODNN7EXAMPLE
153
+ JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M
119
154
  DB_URI=postgres://admin:secret123@db.internal:5432/prod
120
155
  `;
121
156
 
122
- const result = sanitize(devLog, { profile: 'Dev' });
157
+ const result = sanitize(devLog, { profile: 'Dev', detectSecrets: true });
123
158
  console.log(result.scrubbedText);
124
159
  // AWS_KEY=[AWS_KEY_1]
160
+ // JWT=[JWT_TOKEN_1]
125
161
  // DB_URI=[SECRET_1]
126
162
  ```
127
163
 
128
164
  ---
129
165
 
130
- ## 💼 Commercial Production Pipelines (Recipes)
131
-
132
- ### 1. AI Mortgage & Loan Underwriting Pipeline (W-2, Paystubs & DTI Calculation)
133
- *Enables Loan Officers and AI Underwriting bots (e.g. CalChat) to analyze borrower income without violating GLBA or transmitting SSNs to OpenAI/Anthropic.*
134
-
135
- ```javascript
136
- import OpenAI from 'openai';
137
- import { sanitize, restore } from '@privacyscrubber/sdk';
138
-
139
- const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
140
-
141
- async function underwriteLoanApplication(w2RawText) {
142
- // 1. Sanitize borrower W-2 in RAM (SSN, EIN, Employer, Address -> Masked; Wages/Rates -> Preserved)
143
- const { scrubbedText, tokenMap } = sanitize(w2RawText, { profile: 'Finance' });
144
-
145
- // 2. Transmit mathematical numbers to LLM for Debt-to-Income (DTI) & qualifying income calculation
146
- const aiResponse = await openai.chat.completions.create({
147
- model: 'gpt-4o',
148
- messages: [
149
- { role: 'system', content: 'You are an automated mortgage underwriting assistant. Calculate monthly qualifying income and front-end DTI.' },
150
- { role: 'user', content: scrubbedText }
151
- ]
152
- });
153
-
154
- // 3. Rehydrate borrower name and employer into the final formal credit memo
155
- const { restoredText } = restore(aiResponse.choices[0].message.content, tokenMap);
156
- return restoredText;
157
- }
158
- ```
159
-
160
- ### 2. Blind AI HR Screening Pipeline (EEOC & GDPR Compliant)
161
- *Strips names, photos, gender markers, contact details, and graduation years from candidate resumes to prevent algorithmic bias while retaining 100% skills, experience, and GPA.*
162
-
163
- ```javascript
164
- import { sanitize } from '@privacyscrubber/sdk';
165
-
166
- function prepareCandidateForAIScoring(resumeText) {
167
- const { scrubbedText, telemetry } = sanitize(resumeText, { profile: 'HR' });
168
-
169
- // Resume is now completely anonymous (Zero EEOC bias risk)
170
- // Skills (Python, Kubernetes, Leadership) and achievements are 100% intact.
171
- return { anonymousResume: scrubbedText, auditReceipt: telemetry };
172
- }
173
- ```
174
-
175
- ### 3. B2B Invoice & Expense Reconciliation Pipeline
176
- *Redacts corporate payment accounts (PCI-DSS), direct deposit info, and signatory names while preserving line items, tax rates (VAT/Sales Tax), quantities, and chart-of-accounts codes.*
177
-
178
- ```javascript
179
- import { sanitize, restore } from '@privacyscrubber/sdk';
180
-
181
- function processVendorInvoice(invoiceText) {
182
- const { scrubbedText, tokenMap } = sanitize(invoiceText, { profile: 'Accounting' });
183
- // Line items ($350.00, $1,200.00) and general ledger accounts remain fully intact for AI categorization.
184
- return { scrubbedText, tokenMap };
185
- }
186
- ```
187
-
188
- ---
189
-
190
- ## 🔑 License Activation & Commercial Tiers
166
+ ## 🔑 Licensing & Commercial Tiers
191
167
 
192
- PrivacyScrubber works free out-of-the-box with standard limits:
193
- - **Free Tier**: Up to 15,000 characters per request, General & standard profiles.
194
- - **PRO & TEAMS Tiers**: Unlimited throughput, all 23 specialized compliance profiles, custom regex rules, multi-user sync.
168
+ PrivacyScrubber works free out-of-the-box with standard developer limits:
169
+ - **Free Tier ($0)**: Up to 15,000 characters per request for General profile; 5,000 characters trial quota for specialized industry profiles. Ideal for prototyping and CI testing.
170
+ - **Developer SDK License ($299/mo or $2,990/yr)**: Unlimited character throughput, all 25 specialized compliance profiles, unrestricted RAG & microservice batch pipelines, zero quota errors.
195
171
 
196
- ### Activating Your License
172
+ ### Activating Your Commercial License
197
173
 
198
174
  Set the environment variable or pass your key explicitly:
199
175
 
200
176
  ```bash
201
- export PRIVACYSCRUBBER_KEY="your-license-key-here"
177
+ export PRIVACYSCRUBBER_KEY="PS-SDK-PRODXXXXKEY5-XXXX"
202
178
  ```
203
179
 
204
180
  ```javascript
205
181
  import { sanitize, validateLicense } from '@privacyscrubber/sdk';
206
182
 
207
- // Validate programmatically
183
+ // Check license status programmatically
208
184
  const license = validateLicense(process.env.PRIVACYSCRUBBER_KEY);
209
185
  console.log(`Active Tier: ${license.tier}, Valid: ${license.valid}`);
210
186
 
211
- // Or pass directly in options
212
- const result = sanitize(largeDocument, {
213
- licenseKey: 'PS-PRO-XXXX-XXXX',
214
- profile: 'Medical'
187
+ // Unlimited throughput is automatically enabled across all profiles
188
+ const result = sanitize(largeTextPayload, {
189
+ profile: 'Healthcare'
215
190
  });
216
191
  ```
217
192
 
218
- To purchase or upgrade a license, visit:
219
- 👉 **[PrivacyScrubber Pricing & Licensing](https://privacyscrubber.com/pricing?utm_source=npm_core&utm_medium=readme&utm_campaign=dev_upsell)**
220
-
221
- ---
222
-
223
- ## 🛡️ Supported Compliance Frameworks
224
-
225
- - **GDPR (Art. 4)**: Direct & indirect personal identifiers.
226
- - **HIPAA (§164.514 Safe Harbor)**: 18 protected health information identifiers (MRN, dates, clinical IDs).
227
- - **PCI-DSS v4.0**: Primary Account Numbers (PAN), CVVs, banking tokens.
228
- - **SOC 2 Type II / ISO 27001 (A.8.11)**: Data masking and access segregation.
229
- - **NIST SP 800-53**: Automated secrets and credential redaction.
193
+ To acquire a commercial Developer SDK license:
194
+ 👉 **[PrivacyScrubber Developer Licensing](https://privacyscrubber.com/pricing/?utm_source=npm_sdk&utm_medium=readme&utm_campaign=dev_upsell)**
230
195
 
231
196
  ---
232
197
 
233
- ## 📄 Legacy API Compatibility
198
+ ## 🏛️ Compliance Frameworks Enforced
234
199
 
235
- Full backward compatibility is retained for existing integrations using `scrubText` and `unscrubText`:
236
-
237
- ```javascript
238
- import { scrubText, unscrubText } from '@privacyscrubber/sdk';
239
-
240
- const result = scrubText("Raw text", [], {}, 'General', {}, true);
241
- const restored = unscrubText(result.scrubbedText, result.tokenMap);
242
- ```
200
+ - **GDPR (Art. 4 & Art. 17)**: Direct & indirect personal identifiers, Right to be Forgotten.
201
+ - **HIPAA (§164.514 Safe Harbor)**: 18 Protected Health Information (PHI) identifiers.
202
+ - **PCI-DSS v4.0**: Primary Account Numbers (PAN), CVVs, financial tokens.
203
+ - **SOC 2 Type II / ISO 27001 (A.8.11)**: Zero-trust data masking and credential segregation.
204
+ - **NIST SP 800-53**: Automated secrets and cryptographic key sanitization.
243
205
 
244
206
  ---
245
207
 
246
- ## 🔗 Ecosystem & Links
208
+ ## 🔗 PrivacyScrubber Ecosystem
247
209
 
248
210
  - 🌐 **Web App**: [https://privacyscrubber.com](https://privacyscrubber.com)
249
211
  - 🔌 **MCP Server**: [@privacyscrubber/mcp-server](https://www.npmjs.com/package/@privacyscrubber/mcp-server)
250
- - 🧩 **Chrome Extension**: [Chrome Web Store](https://chromewebstore.google.com/detail/privacyscrubber/gmmimjcmidhmbjcbgeojpajefebfepco)
251
- - 📖 **Documentation & Support**: [https://privacyscrubber.com/docs](https://privacyscrubber.com/docs)
252
- - 💬 **Feedback & Feature Requests**: [https://privacyscrubber.com/feedback](https://privacyscrubber.com/feedback)
212
+ - 🧩 **Chrome Extension**: [Chrome Web Store](https://chromewebstore.google.com/detail/privacyscrubber-%E2%80%94-zero-tr/pimoejgefeilajmmbpghifdmhdlkgjol)
213
+ - 📖 **Developer SDK Specs**: [https://privacyscrubber.com/features/developer-sdk/](https://privacyscrubber.com/features/developer-sdk/)
214
+ - 🧪 **DLP Latency Benchmark**: [https://privacyscrubber.com/dlp-speed-test/](https://privacyscrubber.com/dlp-speed-test/)
253
215
 
254
216
  ---
255
217
 
256
218
  ## ⚖️ License
257
219
 
258
- MIT License © 2026 PrivacyScrubber. Commercial features require an active PRO/TEAMS license.
220
+ MIT License © 2026 PrivacyScrubber. Commercial production usage without quota limits requires an active Developer SDK or Enterprise license.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@privacyscrubber/sdk",
3
- "version": "2.0.2",
4
- "description": "Zero-Trust Data Sanitization & PII Redaction Engine. 100% Client-Side / Server-Side in-memory execution. Zero external dependencies.",
3
+ "version": "2.0.3",
4
+ "description": "Zero-dependency, in-memory PII & secrets redaction SDK for Node.js, Next.js, OpenAI, and LangChain. 100% client-side & server-side zero-trust prompt anonymization under 1ms.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
7
  "type": "module",
@@ -14,29 +14,33 @@
14
14
  "polyfill.js",
15
15
  "ps-license-manager.js",
16
16
  "ps-pii-engine.cjs",
17
- "ps-pii-engine.js",
18
17
  "scrubber-core.cjs",
19
- "shared-ui.js",
20
- "ui-modals.js",
21
18
  "README.md"
22
19
  ],
23
20
  "scripts": {
24
- "test": "node test-sdk.js"
21
+ "build": "node ../scripts/build-sdk.js",
22
+ "test": "node test-sdk.js",
23
+ "prepublishOnly": "npm run build && npm test"
25
24
  },
26
25
  "keywords": [
27
- "privacy",
28
26
  "pii",
29
27
  "redaction",
30
28
  "sanitization",
31
- "security",
29
+ "data-masking",
32
30
  "zero-trust",
33
- "compliance",
31
+ "openai",
32
+ "langchain",
33
+ "prompt-anonymizer",
34
+ "llm-privacy",
35
+ "presidio",
36
+ "chatgpt-privacy",
37
+ "rag-sanitization",
38
+ "phi-redaction",
34
39
  "hipaa",
35
- "soc2",
36
40
  "gdpr",
37
- "llm-privacy",
38
- "openai",
39
- "langchain"
41
+ "soc2",
42
+ "secrets-detection",
43
+ "security"
40
44
  ],
41
45
  "author": "Ilya Sibiryakov (BrandMeWeb)",
42
46
  "license": "MIT",