gg-friggin-ez 0.1.0
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/LICENSE +21 -0
- package/README.md +337 -0
- package/dist/index.cjs +386 -0
- package/dist/index.d.cts +225 -0
- package/dist/index.d.ts +225 -0
- package/dist/index.js +352 -0
- package/package.json +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shikhar Srivastava
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img width="240" src="./docs/images/logo.svg" alt="gg-friggin-ez logo">
|
|
4
|
+
|
|
5
|
+
<h1>gg-friggin-ez</h1>
|
|
6
|
+
|
|
7
|
+
<p><strong>Fast, drop-in profanity and toxicity screener for Node.js, powered by <a href="https://typesafe.ai/blog/introducing-system-one-models-and-jev">TypeSafe AI Jev</a>.
|
|
8
|
+
</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p>
|
|
12
|
+
<strong>
|
|
13
|
+
Fast. Cheap. Catches the friggin crap.
|
|
14
|
+
</strong>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p>
|
|
18
|
+
<a href="#quick-start">Quick Start</a> |
|
|
19
|
+
<a href="#install">Install</a> |
|
|
20
|
+
<a href="#the-problem--the-solution">The Problem & The Solution</a> |
|
|
21
|
+
<a href="#interactive-browser-demos">Demos</a> |
|
|
22
|
+
<a href="#custom-schemas">Custom Schemas</a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
[](https://www.npmjs.com/package/gg-friggin-ez)
|
|
26
|
+
[](LICENSE)
|
|
27
|
+
|
|
28
|
+
⭐ _Help us reach more developers and grow the community. Star this repo!_
|
|
29
|
+
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<img src="./docs/images/banner.svg" alt="gg-friggin-ez banner" width="100%">
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
Works across languages and scripts, with zero training required.
|
|
37
|
+
|
|
38
|
+
Real-world chat isn't clean. Users switch scripts, write regional languages in Latin characters, add spaces between letters, and turn profanity into leetspeak. **gg-friggin-ez** is built for exactly these cases - detecting romanized profanity, code-mixed text, leetspeak, and character spacing across languages including Kannada, Telugu, Tamil, Hindi, and Bengali.
|
|
39
|
+
|
|
40
|
+
All at ~50-500ms latency, making it suitable for real-time chat and game moderation without reaching for a general-purpose LLM.
|
|
41
|
+
|
|
42
|
+
## The Problem
|
|
43
|
+
|
|
44
|
+
Static keyword denylists and generic moderation APIs fail on real-world user-generated content (social posts, comments, reviews, live chat, and in game text comms):
|
|
45
|
+
|
|
46
|
+
- **Evasion & Leetspeak**: Common obfuscation tricks bypass static keyword denylists.
|
|
47
|
+
|
|
48
|
+
| Technique | Examples |
|
|
49
|
+
| -------------------------- | ------------------------------------------------------------------------------------------- |
|
|
50
|
+
| **Symbol / number swaps** | `$hitt3r` · `p00da` · `b$dk` · `m1erda` · `c0nnard` · `傻x / c*m` · `死○ね / sh1ne` |
|
|
51
|
+
| **Spaced characters** | `p a i t h i y a m` · `b s d k` · `m i e r d a` |
|
|
52
|
+
| **Character stretching** | `looooosuuu` · `paaaagal` · `菜逼逼逼` · `死ねぇぇぇ` |
|
|
53
|
+
| **Mixed-script** | `chuतिya` · Latin + native-script characters |
|
|
54
|
+
| **ASCII / visual evasion** | Hostile gestures rendered with punctuation, e.g. ASCII middle fingers, that even LLMs miss. |
|
|
55
|
+
|
|
56
|
+
> Examples span English, Tamil, Hindi, Spanish, French, Chinese, Japanese, and other languages.
|
|
57
|
+
|
|
58
|
+
- **Romanized & Code-Mixed Languages**: Transliterated text has no standard spelling and freely blends multiple languages.
|
|
59
|
+
|
|
60
|
+
| Language | Example | Variations |
|
|
61
|
+
| ---------------------- | ------------------------------------------------------------ | --------------------------------------------- |
|
|
62
|
+
| **English** | `you are an absolute piece of <ins>sh1t</ins>, stop talking` | `shit` · `$hit` · `sh*t` |
|
|
63
|
+
| **Hindi / Hinglish** | `abe <ins>chutiya</ins> chup kar na` | `chootiya` · `chutya` · `chuतिya` · `c***iya` |
|
|
64
|
+
| **Tamil / Tanglish** | `nee oru <ins>pooda</ins> paithiyakaara da` | `p00da` · `puda` · `puuda` |
|
|
65
|
+
| **Kannada / Kanglish** | `nin <ins>huccha</ins> naye tara adtiya` | `huchcha` · `hu$ha` · `hucha` |
|
|
66
|
+
| **Japanese / Romaji** | `omae hontou ni <ins>shine</ins> yo gomi` | `shiИe` · `sh1ne` · `死ね` · `死○ね` |
|
|
67
|
+
|
|
68
|
+
- **Regional sparsity:** Non-Hindi regional languages suffer from limited training data and dialectal variation, challenging keyword lists and off-the-shelf classifiers ([DravidianCodeMix](https://doi.org/10.1007/s10579-022-09583-7)).
|
|
69
|
+
|
|
70
|
+
- **Identity-Based Hate Speech:** Regional caste, gender, and religious harassment can be difficult for English-centric moderation systems to detect, especially in transliterated or code-mixed text - e.g. _"kitchen me jaake khana bana ladki, games tere bas ka nahi"_.
|
|
71
|
+
|
|
72
|
+
- **False-Positive Traps**: Harmless friendly banter, cultural idioms, or casual slang get wrongly flagged as severe abuse by blunt keyword matchers.
|
|
73
|
+
- **LLMs are slow & expensive:** General-purpose LLMs can take 1-3s just to produce the first token, making real-time moderation slow and costly at scale.
|
|
74
|
+
|
|
75
|
+
## The Solution
|
|
76
|
+
|
|
77
|
+
`gg-friggin-ez` uses **TypeSafe AI Jev** as a reflex-speed System One decision (classifier) engine:
|
|
78
|
+
|
|
79
|
+
- **Reflex Speed**: ~50-500ms end-to-end response time.
|
|
80
|
+
- **Low Cost**: $0.042 / 1M input tokens, and no charge for output tokens.
|
|
81
|
+
- **Evasion-Aware**: Handles common obfuscation patterns including leetspeak, character spacing, romanization, and code-mixing.
|
|
82
|
+
- **Multilingual**: Supports English and Indic languages, including romanized/transliterated input.
|
|
83
|
+
- **Drop-In & Pluggable**: Simple Node.js API (`isProfane()`, `isToxic()`, `screen()`), with built-in screening rules, or bring your own custom schema.
|
|
84
|
+
- **Human Review Path**: Ambiguous/context-dependent cases can be routed for human review rather than forcing a binary decision.
|
|
85
|
+
|
|
86
|
+
## Install
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm install gg-friggin-ez
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
> Requires Node.js `18+` (or Bun). Ships as both ESM and CommonJS with bundled TypeScript types.
|
|
93
|
+
|
|
94
|
+
<details>
|
|
95
|
+
<summary>Other package managers</summary>
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
yarn add gg-friggin-ez
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pnpm add gg-friggin-ez
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
bun add gg-friggin-ez
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
</details>
|
|
110
|
+
|
|
111
|
+
## Quick Start
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { isProfane, isToxic } from "gg-friggin-ez";
|
|
115
|
+
|
|
116
|
+
process.env.OPENROUTER_API_KEY = "sk-or-..."; // or call configure({ apiKey }) instead
|
|
117
|
+
|
|
118
|
+
// Fast boolean convenience checks
|
|
119
|
+
const profane = await isProfane("you are absolute dog sh1t"); // true
|
|
120
|
+
const toxic = await isToxic("you are completely brainless and useless"); // true
|
|
121
|
+
|
|
122
|
+
// Works with transliterated, code-mixed, and obfuscated text
|
|
123
|
+
const indic = await isProfane("Nee oru p00da paithiyakaara da, 5colo nadatha"); // true
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Or `require()` it from plain CommonJS Node:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
const { isProfane, isToxic } = require("gg-friggin-ez");
|
|
130
|
+
|
|
131
|
+
const bad = await isProfane("you are absolute dog sh1t");
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> [!TIP]
|
|
135
|
+
> **Performance tip**: Performance tip: `isProfane()` and `isToxic()` each trigger an inference request. If you need multiple moderation signals, call `screen()` once.
|
|
136
|
+
|
|
137
|
+
### Full detail
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { screen } from "gg-friggin-ez";
|
|
141
|
+
|
|
142
|
+
// Multi-vector adversarial evasion: spacing, leetspeak, repeated chars, symbols, & mixed script
|
|
143
|
+
const result = await screen(
|
|
144
|
+
"Nee oru p 0 0 d a daaaa, b*dk chuतिya 5colo nadatha",
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
console.log(result);
|
|
148
|
+
// {
|
|
149
|
+
// isProfane: true,
|
|
150
|
+
// isToxic: true,
|
|
151
|
+
// severity: "SEVERE",
|
|
152
|
+
// severityScore: 1.95,
|
|
153
|
+
// language: "tamil",
|
|
154
|
+
// obfuscationType: "mixed_script",
|
|
155
|
+
// obfuscationTypes: [
|
|
156
|
+
// "mixed_script",
|
|
157
|
+
// "spaced_characters",
|
|
158
|
+
// "leetspeak",
|
|
159
|
+
// "repeated_characters",
|
|
160
|
+
// ],
|
|
161
|
+
// action: "AUTO_BAN",
|
|
162
|
+
// }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`screen()` returns the complete moderation result:
|
|
166
|
+
|
|
167
|
+
- `isProfane` - `true` / `false` - explicit profanity or slurs
|
|
168
|
+
- `isToxic` - `true` / `false` - hostility, harassment, or personal attacks
|
|
169
|
+
- `severity` - `"NONE"` / `"MILD"` / `"SEVERE"`
|
|
170
|
+
- `severityScore` - continuous `0.0-2.0` score, e.g. `1.95`
|
|
171
|
+
- `language` - detected language, e.g. `"tamil"`
|
|
172
|
+
- `obfuscationType` - primary evasion technique, e.g. `"mixed_script"`
|
|
173
|
+
- `obfuscationTypes` - all detected evasion techniques, e.g. `["mixed_script", "spaced_characters", "leetspeak", "repeated_characters", "symbol_substitutions"]`
|
|
174
|
+
- `action` - `"ALLOW"` / `"SUSPICIOUS_REVIEW"` / `"AUTO_CENSOR"` / `"AUTO_MUTE"` / `"AUTO_BAN"`
|
|
175
|
+
|
|
176
|
+
### Visual Evasion & ASCII Art Screening
|
|
177
|
+
|
|
178
|
+
Standard keyword denylists and traditional NLP models process text as 1D token streams, and may miss 2D ASCII drawings. `gg-friggin-ez` detects ASCII-art evasion as a distinct moderation signal.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
const asciiMiddleFinger = `
|
|
182
|
+
....................../´¯/)
|
|
183
|
+
....................,/¯../
|
|
184
|
+
.................../..../
|
|
185
|
+
............./´¯/'...'/´¯¯\`·¸
|
|
186
|
+
........../'/.../..../......./¨¯\\
|
|
187
|
+
........('(...´...´.... ¯~/'...')
|
|
188
|
+
.........\\.................'...../
|
|
189
|
+
..........''...\\.......... _.·´
|
|
190
|
+
............\\..............(
|
|
191
|
+
..............\\.............\\...
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
const res = await screen(asciiMiddleFinger);
|
|
195
|
+
|
|
196
|
+
console.log(res.obfuscationType); // "ascii_art"
|
|
197
|
+
console.log(res.obfuscationTypes); // ["ascii_art"]
|
|
198
|
+
console.log(res.severityScore); // 1.30
|
|
199
|
+
console.log(res.action); // "SUSPICIOUS_REVIEW"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Configurable policy thresholds
|
|
203
|
+
|
|
204
|
+
You can customize the decision action thresholds per-call or across the shared screener.
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
const result = await screen("some borderline text", {
|
|
208
|
+
thresholds: {
|
|
209
|
+
review: 0.3, // route to review at >= 30% confidence
|
|
210
|
+
censor: 0.55, // auto-censor at >= 55%
|
|
211
|
+
ban: 0.7, // auto-ban at >= 70%
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### API key configuration
|
|
217
|
+
|
|
218
|
+
`gg-friggin-ez` reads the API key from environment variables (in order): `OPENROUTER_API_KEY`, `TYPESAFE_API_KEY`, `JEV_KEY`. You can also configure it explicitly.
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { configure } from "gg-friggin-ez";
|
|
222
|
+
|
|
223
|
+
configure({ apiKey: "sk-or-..." });
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
If no key is configured, `gg-friggin-ez` falls back to a local heuristic evaluator so calls never throw - but for production-grade accuracy you'll want a real API key.
|
|
227
|
+
|
|
228
|
+
### Custom schemas
|
|
229
|
+
|
|
230
|
+
Create an independent screener with your own Jev question schema - useful for a different language family, domain, or moderation policy.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { createScreener } from "gg-friggin-ez";
|
|
234
|
+
|
|
235
|
+
const screener = createScreener({
|
|
236
|
+
apiKey: "sk-or-...",
|
|
237
|
+
questions: myCustomQuestions, // same shape as DEFAULT_TOXICITY_QUESTIONS
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const result = await screener.screen("some text");
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Interactive Browser Demos
|
|
244
|
+
|
|
245
|
+
The repository includes two interactive simulations - **Twitch live chat** and **Valorant text comms** - showcasing real-time code-mixed toxicity detection. Run locally with Bun or host on **GitHub Pages**. Add an OpenRouter or TypeSafe AI API key via the **API Keys** modal, or use the built-in offline heuristic evaluator without a key.
|
|
246
|
+
|
|
247
|
+
### Twitch Live Stream Chat UI
|
|
248
|
+
|
|
249
|
+
<p align="center">
|
|
250
|
+
<img src="./docs/images/demo-twitch.png" alt="Twitch Live Stream Chat Demo" width="100%">
|
|
251
|
+
<br>
|
|
252
|
+
<sub>Live Twitch chat moderation with AutoMod timeout, language detection, and moderator reveal.</sub>
|
|
253
|
+
</p>
|
|
254
|
+
|
|
255
|
+
### Valorant Realtime Comms
|
|
256
|
+
|
|
257
|
+
<p align="center">
|
|
258
|
+
<img src="./docs/images/demo-valorant.png" alt="Valorant Realtime Comms Demo" width="100%">
|
|
259
|
+
<br>
|
|
260
|
+
<sub>In-game tactical comms HUD with real-time censorship, 3-strike penalty system, and inline telemetry cards.</sub>
|
|
261
|
+
</p>
|
|
262
|
+
|
|
263
|
+
### Running the demo locally
|
|
264
|
+
|
|
265
|
+
Requires [Bun](https://bun.sh) (v1.1+).
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
git clone https://github.com/ItisShikhar/gg-friggin-ez.git
|
|
269
|
+
cd gg-friggin-ez
|
|
270
|
+
bun install
|
|
271
|
+
|
|
272
|
+
bun run demo
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Open [http://localhost:3000](http://localhost:3000) in your browser.
|
|
276
|
+
|
|
277
|
+
### Running Tests
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
bun test
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Building the npm package
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
npm run build
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Emits `dist/index.js` (ESM), `dist/index.cjs` (CJS), and `dist/index.d.ts` (types).
|
|
290
|
+
|
|
291
|
+
## How It Compares
|
|
292
|
+
|
|
293
|
+
How `gg-friggin-ez` compares on latency, multilingual coverage, and real-world evasion handling.
|
|
294
|
+
|
|
295
|
+
| Moderation Approach | Latency | Strengths | Trade-offs |
|
|
296
|
+
| :-------------------------------------------------------- | :------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------ |
|
|
297
|
+
| **`gg-friggin-ez`** (TypeSafe AI Jev) | **~50-500ms** | Multilingual, including romanized/transliterated Indic languages (Tamil, Telugu, Kannada, Bengali, Hindi, etc.), evasion tricks (leetspeak, spacing) | Limited conversational context (routes to human review) |
|
|
298
|
+
| **Perspective API** (Google Jigsaw) | ~80-120ms | Monolingual English, Spanish, standard Hindi (`hi`) | Unsupported on Dravidian & regional Indic languages. Scheduled to sunset end of 2026. |
|
|
299
|
+
| **OpenAI Moderation Endpoint** (`omni-moderation-latest`) | ~150-350ms | Multilingual standard text (40 languages supported with major gains in Telugu, Bengali, Marathi) | Fixed 13 harm categories rather than custom policy schemas; higher false-positive rate on casual colloquial banter. |
|
|
300
|
+
| **Custom BERT / FastText** | ~15-30ms | Extremely fast; performance depends on training data | Requires training data + maintenance. |
|
|
301
|
+
| **General LLMs (GPT-4o)** | 1,000-3,500ms | Has multilingual world knowledge | 10x to 30x latency, plus 100x inference cost. |
|
|
302
|
+
|
|
303
|
+
## Benchmark Results
|
|
304
|
+
|
|
305
|
+
Results from 42 curated test cases across 14 languages, covering multilingual, romanized, and obfuscated text.
|
|
306
|
+
|
|
307
|
+
| Metric | `gg-friggin-ez` (TypeSafe AI Jev) | OpenAI (`omni-moderation`) | Perspective API | Legacy Keyword Filter |
|
|
308
|
+
| :-------------------------------- | :-------------------------------- | :------------------------- | :--------------------------------- | :-------------------- |
|
|
309
|
+
| **Overall Accuracy** | **97.6%** (41 / 42) | 88.1% (37 / 42) | 38.1% (16 / 42) _(18 unsupported)_ | 61.9% (26 / 42) |
|
|
310
|
+
| **Romanized Indic Accuracy** | **94.4%** | 77.8% | 16.7% | 66.7% |
|
|
311
|
+
| **Global Languages Accuracy** | **100%** | 100% | 72.2% | 55.6% |
|
|
312
|
+
| **Obfuscated Evasion Catch Rate** | **100%** | 71.4% | 28.6% | 35.7% |
|
|
313
|
+
| **Average Measured Latency** | **~105ms** _(direct engine)_ | ~210ms | ~110ms | <1ms |
|
|
314
|
+
| **Inference Cost** | **~$0.000052 / msg** | Free | Free _(sunset 2026)_ | $0.00 |
|
|
315
|
+
|
|
316
|
+
> _Latency Note_: Direct `gg-friggin-ez` engine latency is ~105ms (reflecting raw OpenRouter proxy transit minus the ~265ms external network hop).
|
|
317
|
+
|
|
318
|
+
> _Note on API language coverage:_ According to Google's official [Perspective API documentation](https://github.com/conversationai/perspectiveapi), its `TOXICITY` model officially supports only 18 languages - with standard Hindi (`hi`) and experimental Hinglish (`hi-Latn`) being its only Indic coverage. Tamil, Telugu, Kannada, Bengali, Marathi, and Bhojpuri are unsupported.
|
|
319
|
+
|
|
320
|
+
> For complete itemized data across all 42 tests, individual scores, and latency logs, see [raw-benchmarks.md](./raw-benchmarks.md).
|
|
321
|
+
|
|
322
|
+
## Contributing
|
|
323
|
+
|
|
324
|
+
Contributions are welcome, whether they improve performance, fix bugs, add
|
|
325
|
+
presets, components or effects, expand examples and tests, or improve documentation.
|
|
326
|
+
See [Contributing](CONTRIBUTING.md) before opening a pull request.
|
|
327
|
+
|
|
328
|
+
## Author
|
|
329
|
+
|
|
330
|
+
Built by [Shikhar Srivastava](https://www.linkedin.com/in/itisshikhar/).
|
|
331
|
+
|
|
332
|
+
[GitHub](https://github.com/ItisShikhar) ·
|
|
333
|
+
[LinkedIn](https://www.linkedin.com/in/itisshikhar/)
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
gg-friggin-ez is released under the [MIT License](LICENSE).
|