@devanshhq/indica 0.1.0 → 0.2.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.
Files changed (52) hide show
  1. package/.pm/indica-research-report.md +390 -0
  2. package/ARCHITECTURE.md +470 -0
  3. package/Cargo.lock +1 -1
  4. package/Cargo.toml +2 -2
  5. package/README.md +98 -109
  6. package/package.json +2 -2
  7. package/src/batch/compute.rs +165 -0
  8. package/src/batch/mod.rs +2 -0
  9. package/src/batch/screen.rs +176 -0
  10. package/src/core/mod.rs +3 -0
  11. package/src/core/traits.rs +37 -0
  12. package/src/core/types.rs +22 -0
  13. package/src/core/utils.rs +43 -0
  14. package/src/indicators/india/circuit.rs +101 -0
  15. package/src/indicators/india/delivery.rs +116 -0
  16. package/src/indicators/india/mod.rs +2 -0
  17. package/src/indicators/mod.rs +6 -0
  18. package/src/indicators/momentum/macd.rs +123 -0
  19. package/src/indicators/momentum/mod.rs +3 -0
  20. package/src/indicators/momentum/rsi.rs +130 -0
  21. package/src/indicators/momentum/stochastic.rs +99 -0
  22. package/src/indicators/support_resistance/mod.rs +1 -0
  23. package/src/indicators/support_resistance/pivot.rs +40 -0
  24. package/src/indicators/trend/adx.rs +168 -0
  25. package/src/indicators/trend/ema.rs +110 -0
  26. package/src/indicators/trend/mod.rs +4 -0
  27. package/src/indicators/trend/sma.rs +75 -0
  28. package/src/indicators/trend/supertrend.rs +193 -0
  29. package/src/indicators/volatility/atr.rs +51 -0
  30. package/src/{bollinger.rs → indicators/volatility/bollinger.rs} +6 -22
  31. package/src/indicators/volatility/mod.rs +2 -0
  32. package/src/indicators/volume/mod.rs +3 -0
  33. package/src/indicators/volume/obv.rs +44 -0
  34. package/src/{volume.rs → indicators/volume/volume_trend.rs} +9 -27
  35. package/src/indicators/volume/vwap.rs +53 -0
  36. package/src/lib.rs +71 -21
  37. package/src/signals/engine.rs +139 -0
  38. package/src/signals/mod.rs +4 -0
  39. package/src/signals/presets.rs +109 -0
  40. package/src/signals/rules.rs +333 -0
  41. package/src/signals/types.rs +50 -0
  42. package/index.d.ts +0 -66
  43. package/indica.node +0 -0
  44. package/src/atr.rs +0 -66
  45. package/src/batch.rs +0 -139
  46. package/src/macd.rs +0 -132
  47. package/src/moving_avg.rs +0 -71
  48. package/src/napi_bindings.rs +0 -166
  49. package/src/pivot.rs +0 -58
  50. package/src/relative_strength.rs +0 -67
  51. package/src/rsi.rs +0 -74
  52. package/src/utils.rs +0 -17
@@ -0,0 +1,470 @@
1
+ # indica — Architecture Design Document
2
+
3
+ ## 1. Vision
4
+
5
+ indica is not "TA-Lib in Rust." It's a **trading intelligence library** built specifically for Indian stock markets. Three layers:
6
+
7
+ ```
8
+ ┌──────────────────────────────────────────────────────────┐
9
+ │ SIGNALS LAYER │
10
+ │ Composite buy/sell signals with confidence + reasons │
11
+ ├──────────────────────────────────────────────────────────┤
12
+ │ INDICATORS LAYER │
13
+ │ Standard TA (RSI, MACD, BB...) + India-specific │
14
+ │ (delivery %, circuit proximity, FII/DII momentum) │
15
+ ├──────────────────────────────────────────────────────────┤
16
+ │ CORE LAYER │
17
+ │ Streaming trait, batch processing, math utils │
18
+ └──────────────────────────────────────────────────────────┘
19
+ │ │ │
20
+ Rust NAPI WASM
21
+ (crate) (Node.js) (Browser)
22
+ ```
23
+
24
+ ## 2. Current State (v0.1)
25
+
26
+ ```
27
+ src/
28
+ ├── lib.rs ← flat re-exports
29
+ ├── moving_avg.rs ← SMA, EMA, ema_series
30
+ ├── rsi.rs ← RSI
31
+ ├── macd.rs ← MACD
32
+ ├── bollinger.rs ← Bollinger Bands
33
+ ├── atr.rs ← ATR
34
+ ├── pivot.rs ← Pivot Points
35
+ ├── volume.rs ← Volume Trend
36
+ ├── relative_strength.rs
37
+ ├── batch.rs ← Rayon parallel batch
38
+ ├── napi_bindings.rs ← Node.js FFI
39
+ └── utils.rs ← round, wilders_smooth
40
+ ```
41
+
42
+ Problems with current architecture:
43
+ - **Flat module structure** — everything in `src/`, will get messy at 20+ indicators
44
+ - **No shared trait** — each indicator is an independent function, no polymorphism
45
+ - **Batch is hardcoded** — `batch.rs` hardcodes which indicators to compute
46
+ - **NAPI bindings are manual** — every new indicator needs 20+ lines of boilerplate
47
+ - **No streaming** — must recompute from full array every time
48
+
49
+ ## 3. Target Architecture (v1.0)
50
+
51
+ ```
52
+ src/
53
+ ├── lib.rs ← public API surface
54
+
55
+ ├── core/ ← CORE LAYER
56
+ │ ├── mod.rs
57
+ │ ├── traits.rs ← Indicator trait (streaming + batch)
58
+ │ ├── types.rs ← Candle, Signal, shared types
59
+ │ └── utils.rs ← round, wilders_smooth, ema_step
60
+
61
+ ├── indicators/ ← INDICATORS LAYER
62
+ │ ├── mod.rs ← re-exports all indicators
63
+ │ ├── trend/ ← Trend indicators
64
+ │ │ ├── mod.rs
65
+ │ │ ├── sma.rs
66
+ │ │ ├── ema.rs
67
+ │ │ ├── supertrend.rs
68
+ │ │ ├── adx.rs
69
+ │ │ └── ichimoku.rs (future)
70
+ │ ├── momentum/ ← Momentum indicators
71
+ │ │ ├── mod.rs
72
+ │ │ ├── rsi.rs
73
+ │ │ ├── macd.rs
74
+ │ │ ├── stochastic.rs
75
+ │ │ └── cci.rs (future)
76
+ │ ├── volatility/ ← Volatility indicators
77
+ │ │ ├── mod.rs
78
+ │ │ ├── bollinger.rs
79
+ │ │ └── atr.rs
80
+ │ ├── volume/ ← Volume indicators
81
+ │ │ ├── mod.rs
82
+ │ │ ├── obv.rs
83
+ │ │ ├── vwap.rs
84
+ │ │ └── volume_trend.rs
85
+ │ ├── support_resistance/ ← Levels
86
+ │ │ ├── mod.rs
87
+ │ │ ├── pivot.rs
88
+ │ │ └── fibonacci.rs (future)
89
+ │ └── india/ ← INDIA-SPECIFIC (the moat)
90
+ │ ├── mod.rs
91
+ │ ├── delivery.rs ← delivery %, delivery trend
92
+ │ ├── circuit.rs ← circuit proximity, hit count
93
+ │ └── fii_dii.rs ← institutional flow momentum
94
+
95
+ ├── signals/ ← SIGNALS LAYER
96
+ │ ├── mod.rs
97
+ │ ├── types.rs ← Signal enum, Confidence, Reason
98
+ │ ├── engine.rs ← Composite signal generator
99
+ │ └── presets.rs ← Built-in strategies (swing, momentum, etc.)
100
+
101
+ ├── batch/ ← Batch processing
102
+ │ ├── mod.rs
103
+ │ ├── compute.rs ← configurable batch compute
104
+ │ └── screen.rs ← stock screening with filters
105
+
106
+ └── bindings/ ← Platform bindings
107
+ ├── mod.rs
108
+ ├── napi.rs ← Node.js (feature-gated)
109
+ └── wasm.rs ← Browser (feature-gated)
110
+ ```
111
+
112
+ ## 4. Key Architectural Decisions
113
+
114
+ ### ADR-001: Streaming Indicator Trait
115
+
116
+ **Context:** Current indicators are pure functions that recompute from full arrays. Real-time trading needs O(1) updates.
117
+
118
+ **Decision:** Define an `Indicator` trait with two modes:
119
+
120
+ ```rust
121
+ /// A candle of OHLCV data.
122
+ #[derive(Debug, Clone, Copy)]
123
+ pub struct Candle {
124
+ pub open: f64,
125
+ pub high: f64,
126
+ pub low: f64,
127
+ pub close: f64,
128
+ pub volume: f64,
129
+ }
130
+
131
+ /// Core trait for all indicators.
132
+ /// Supports both streaming (one candle at a time) and batch (full array).
133
+ pub trait Indicator: Send + Sync {
134
+ /// The output type (f64, MacdResult, BollingerBandsResult, etc.)
135
+ type Output: Clone;
136
+
137
+ /// Feed one new candle. Returns None while building up, Some once ready.
138
+ fn update(&mut self, candle: &Candle) -> Option<Self::Output>;
139
+
140
+ /// Reset internal state.
141
+ fn reset(&mut self);
142
+
143
+ /// Compute from a full array (convenience wrapper around update).
144
+ fn compute(&mut self, candles: &[Candle]) -> Vec<Option<Self::Output>> {
145
+ self.reset();
146
+ candles.iter().map(|c| self.update(c)).collect()
147
+ }
148
+
149
+ /// Compute the final value only (most common use case).
150
+ fn compute_last(&mut self, candles: &[Candle]) -> Option<Self::Output> {
151
+ self.reset();
152
+ let mut last = None;
153
+ for c in candles {
154
+ last = self.update(c);
155
+ }
156
+ last
157
+ }
158
+ }
159
+ ```
160
+
161
+ **Trade-offs:**
162
+ - (+) O(1) streaming updates for real-time use
163
+ - (+) Batch mode built on top of streaming (DRY)
164
+ - (+) All indicators share the same interface → configurable batch
165
+ - (-) Slightly more complex than pure functions for simple use cases
166
+ - (-) Indicators need internal state (mutable)
167
+
168
+ **Backward compatibility:** Keep the existing pure functions (`sma()`, `rsi()`, etc.) as convenience wrappers that create an indicator, call `compute_last`, and return. Zero breaking changes.
169
+
170
+ ```rust
171
+ // Convenience function (existing API, unchanged)
172
+ pub fn rsi(closes: &[f64], period: usize) -> Option<f64> {
173
+ let candles: Vec<Candle> = closes.iter()
174
+ .map(|&c| Candle { open: c, high: c, low: c, close: c, volume: 0.0 })
175
+ .collect();
176
+ let mut ind = Rsi::new(period);
177
+ ind.compute_last(&candles)
178
+ }
179
+
180
+ // Streaming API (new)
181
+ let mut rsi = Rsi::new(14);
182
+ for candle in live_feed {
183
+ if let Some(value) = rsi.update(&candle) {
184
+ println!("RSI: {}", value);
185
+ }
186
+ }
187
+ ```
188
+
189
+ ---
190
+
191
+ ### ADR-002: Candle as Universal Input
192
+
193
+ **Context:** Current functions take separate slices (`&[f64]` for closes, highs, lows, volumes). This leads to mismatched lengths and parameter explosion.
194
+
195
+ **Decision:** Introduce a `Candle` struct as the standard input type. Keep the `&[f64]` convenience functions for backward compatibility.
196
+
197
+ **Trade-offs:**
198
+ - (+) Type-safe: impossible to swap highs and lows
199
+ - (+) Simpler API: one `&[Candle]` instead of four `&[f64]` slices
200
+ - (+) Volume always available (needed for VWAP, OBV)
201
+ - (-) Slight overhead for indicators that only need close (e.g., SMA)
202
+ - (-) Users must construct Candle from their data format
203
+
204
+ ---
205
+
206
+ ### ADR-003: Feature-Gated Bindings
207
+
208
+ **Context:** NAPI-RS and WASM have heavy dependencies. Pure Rust users shouldn't need them.
209
+
210
+ **Decision:** Feature-gate bindings:
211
+
212
+ ```toml
213
+ [features]
214
+ default = []
215
+ napi = ["dep:napi", "dep:napi-derive"]
216
+ wasm = ["dep:wasm-bindgen"]
217
+
218
+ [dependencies]
219
+ napi = { version = "3", features = ["napi4"], optional = true }
220
+ napi-derive = { version = "3", optional = true }
221
+ wasm-bindgen = { version = "0.2", optional = true }
222
+ rayon = "1.11"
223
+
224
+ [lib]
225
+ crate-type = ["lib"] # default: pure Rust library
226
+
227
+ # NAPI users build with: cargo build --features napi
228
+ # WASM users build with: wasm-pack build --features wasm
229
+ ```
230
+
231
+ **Trade-offs:**
232
+ - (+) Smaller dependency tree for pure Rust users
233
+ - (+) Clean separation of concerns
234
+ - (-) CI must test with and without features
235
+
236
+ ---
237
+
238
+ ### ADR-004: India-Specific Module
239
+
240
+ **Context:** No other TA library has Indian market indicators. This is the differentiation.
241
+
242
+ **Decision:** Dedicated `indicators/india/` module for indicators that require India-specific data:
243
+
244
+ ```rust
245
+ /// Delivery volume analysis (unique to NSE/BSE).
246
+ pub struct DeliveryAnalysis {
247
+ period: usize,
248
+ }
249
+
250
+ impl DeliveryAnalysis {
251
+ /// Compute delivery percentage.
252
+ /// delivery_pct = delivery_volume / total_volume * 100
253
+ pub fn delivery_pct(delivery_vol: f64, total_vol: f64) -> f64;
254
+
255
+ /// Delivery trend: compare recent avg delivery % to longer-term avg.
256
+ /// High delivery % on up days = genuine buying.
257
+ pub fn delivery_trend(
258
+ delivery_pcts: &[f64],
259
+ closes: &[f64],
260
+ short_period: usize,
261
+ long_period: usize,
262
+ ) -> Option<DeliveryTrend>;
263
+ }
264
+
265
+ /// Circuit limit proximity detector.
266
+ pub fn circuit_proximity(
267
+ current_price: f64,
268
+ prev_close: f64,
269
+ circuit_limit: CircuitLimit, // Percent2, Percent5, Percent10, Percent20
270
+ ) -> CircuitStatus; // { upper_distance_pct, lower_distance_pct, near_upper, near_lower }
271
+
272
+ /// FII/DII flow momentum.
273
+ pub fn fii_dii_momentum(
274
+ fii_flows: &[f64], // Daily net FII values
275
+ dii_flows: &[f64], // Daily net DII values
276
+ period: usize,
277
+ ) -> Option<FlowMomentum>; // { fii_trend, dii_trend, divergence }
278
+ ```
279
+
280
+ **These indicators cannot exist in any US/global TA library** because the underlying data (delivery volume, circuit limits, FII/DII flows) is unique to Indian exchanges.
281
+
282
+ ---
283
+
284
+ ### ADR-005: Signal Generation Engine
285
+
286
+ **Context:** Raw indicator values require interpretation. Traders need actionable signals.
287
+
288
+ **Decision:** A composable signal engine:
289
+
290
+ ```rust
291
+ #[derive(Debug, Clone)]
292
+ pub enum SignalStrength {
293
+ StrongBuy,
294
+ Buy,
295
+ Neutral,
296
+ Sell,
297
+ StrongSell,
298
+ }
299
+
300
+ #[derive(Debug, Clone)]
301
+ pub struct Signal {
302
+ pub strength: SignalStrength,
303
+ pub confidence: f64, // 0.0 to 1.0
304
+ pub reasons: Vec<String>, // ["RSI oversold (28.5)", "MACD bullish crossover"]
305
+ }
306
+
307
+ /// Signal engine that combines multiple indicators.
308
+ pub struct SignalEngine {
309
+ rules: Vec<Box<dyn SignalRule>>,
310
+ }
311
+
312
+ pub trait SignalRule: Send + Sync {
313
+ fn evaluate(&self, snapshot: &IndicatorSnapshot) -> Option<SignalVote>;
314
+ }
315
+
316
+ // Built-in rules:
317
+ // - RsiRule: oversold < 30 = Buy, overbought > 70 = Sell
318
+ // - MacdCrossoverRule: bullish crossover = Buy, bearish = Sell
319
+ // - SupertrendRule: price above = Buy, below = Sell
320
+ // - VolumeConfirmationRule: surging volume confirms signal
321
+ // - DeliveryRule (India-specific): high delivery % confirms Buy
322
+ ```
323
+
324
+ The engine collects votes from all rules, weights them, and produces a composite signal. Users can add custom rules.
325
+
326
+ **Trade-offs:**
327
+ - (+) Actionable output (Buy/Sell, not 67.3)
328
+ - (+) Extensible via trait
329
+ - (+) Composable — users mix and match rules
330
+ - (-) Opinions baked in (what counts as "oversold"?)
331
+ - (-) More complex API surface
332
+
333
+ **Mitigation:** Built-in presets (conservative, aggressive, swing, momentum) plus full customization.
334
+
335
+ ---
336
+
337
+ ## 5. Implementation Phases
338
+
339
+ ### Phase 1: Core Refactor (Foundation)
340
+
341
+ Restructure into the module layout. Introduce `Candle` type and `Indicator` trait. Migrate existing indicators to implement the trait while keeping convenience functions.
342
+
343
+ **Files:** `core/traits.rs`, `core/types.rs`, `core/utils.rs`
344
+ **Breaking changes:** None (existing API preserved)
345
+
346
+ ### Phase 2: New Indicators
347
+
348
+ Add the 5 most-requested indicators:
349
+
350
+ | Indicator | Category | Depends on | Effort |
351
+ |-----------|----------|------------|--------|
352
+ | Supertrend | trend | ATR | 2 hrs |
353
+ | VWAP | volume | Volume data | 2 hrs |
354
+ | Stochastic | momentum | High/Low/Close | 2 hrs |
355
+ | ADX | trend | ATR | 3 hrs |
356
+ | OBV | volume | Close + Volume | 1 hr |
357
+
358
+ ### Phase 3: India-Specific Indicators
359
+
360
+ | Indicator | What it does | Data needed |
361
+ |-----------|-------------|-------------|
362
+ | `delivery_pct` | Delivery volume / total volume | Delivery + total vol |
363
+ | `delivery_trend` | Delivery % trend with price context | Delivery pcts + closes |
364
+ | `circuit_proximity` | Distance from circuit limits | Price + prev close |
365
+ | `fii_dii_momentum` | Institutional flow trend | Daily FII/DII values |
366
+
367
+ ### Phase 4: Signal Engine
368
+
369
+ Build the signal generation layer. Start with 5 built-in rules + 2 presets (swing trader, momentum trader).
370
+
371
+ ### Phase 5: Bindings
372
+
373
+ - Feature-gate NAPI behind `features = ["napi"]`
374
+ - Add WASM bindings behind `features = ["wasm"]`
375
+ - Auto-generate NAPI bindings for new indicators using a macro
376
+
377
+ ### Phase 6: Series Output
378
+
379
+ Add `_series()` variants to all indicators that return `Vec<f64>` (full history). Needed for charting and backtesting.
380
+
381
+ ---
382
+
383
+ ## 6. Cargo.toml (Target State)
384
+
385
+ ```toml
386
+ [package]
387
+ name = "indica"
388
+ version = "1.0.0"
389
+ edition = "2024"
390
+ description = "Fast technical analysis indicators for stock markets. Built for Indian markets."
391
+ license = "MIT"
392
+ repository = "https://github.com/Devansh-365/indica"
393
+ keywords = ["trading", "technical-analysis", "indicators", "nse", "stocks"]
394
+ categories = ["finance", "mathematics"]
395
+
396
+ [features]
397
+ default = []
398
+ napi = ["dep:napi", "dep:napi-derive"]
399
+ wasm = ["dep:wasm-bindgen"]
400
+ india = [] # India-specific indicators (delivery, circuit, FII/DII)
401
+ signals = [] # Signal generation engine
402
+
403
+ [dependencies]
404
+ rayon = "1.11"
405
+ napi = { version = "3", features = ["napi4"], optional = true }
406
+ napi-derive = { version = "3", optional = true }
407
+ wasm-bindgen = { version = "0.2", optional = true }
408
+
409
+ [lib]
410
+ crate-type = ["lib"]
411
+ ```
412
+
413
+ ## 7. Public API Surface (Target)
414
+
415
+ ```rust
416
+ // ── Convenience functions (existing, backward-compatible) ──
417
+ indica::sma(closes, period) -> Option<f64>
418
+ indica::ema(closes, period) -> Option<f64>
419
+ indica::rsi(closes, period) -> Option<f64>
420
+ indica::macd(closes, fast, slow, signal) -> Option<MacdResult>
421
+ indica::bollinger_bands(closes, period, mult) -> Option<BollingerBandsResult>
422
+ indica::atr(highs, lows, closes, period) -> Option<f64>
423
+ indica::pivot_points(high, low, close) -> PivotPointsResult
424
+ indica::volume_trend(volumes) -> &str
425
+ indica::relative_strength(stock, bench, period) -> Option<f64>
426
+ indica::supertrend(highs, lows, closes, period, mult) -> Option<SupertrendResult>
427
+ indica::vwap(candles) -> Option<f64>
428
+ indica::stochastic(highs, lows, closes, k_period, d_period) -> Option<StochasticResult>
429
+ indica::adx(highs, lows, closes, period) -> Option<f64>
430
+ indica::obv(closes, volumes) -> f64
431
+
432
+ // ── Streaming API (new) ──
433
+ let mut rsi = indica::Rsi::new(14);
434
+ rsi.update(&candle) -> Option<f64>
435
+
436
+ // ── Batch (existing, enhanced) ──
437
+ indica::batch::compute_parallel(stocks) -> Vec<IndicatorSnapshot>
438
+ indica::batch::screen(stocks, filter) -> Vec<ScreenResult>
439
+
440
+ // ── India-specific (new) ──
441
+ indica::india::delivery_pct(delivery_vol, total_vol) -> f64
442
+ indica::india::delivery_trend(pcts, closes, short, long) -> Option<DeliveryTrend>
443
+ indica::india::circuit_proximity(price, prev_close, limit) -> CircuitStatus
444
+ indica::india::fii_dii_momentum(fii, dii, period) -> Option<FlowMomentum>
445
+
446
+ // ── Signals (new) ──
447
+ let engine = indica::signals::Engine::preset_swing();
448
+ engine.evaluate(&snapshot) -> Signal { strength, confidence, reasons }
449
+ ```
450
+
451
+ ## 8. Non-Functional Requirements
452
+
453
+ | Requirement | Target | How |
454
+ |-------------|--------|-----|
455
+ | Performance | 2,000 stocks in <10ms | Rayon parallelism, zero allocations in hot path |
456
+ | Correctness | Bit-exact with TA-Lib for standard indicators | Cross-reference tests against known values |
457
+ | Safety | Zero panics on any input | All unwrap() replaced with ?, fuzzing tests |
458
+ | Binary size | <500KB for WASM | Feature-gate heavy deps, LTO |
459
+ | Compatibility | Rust 1.85+ (edition 2024) | CI tests on MSRV |
460
+ | Platforms | macOS, Linux, Windows, WASM | CI matrix |
461
+
462
+ ## 9. Risks
463
+
464
+ | Risk | Mitigation |
465
+ |------|------------|
466
+ | Streaming trait is too complex | Keep convenience functions as primary API |
467
+ | India indicators have no adoption | Ship them in Metis first, prove value |
468
+ | WASM + Rayon conflict | Rayon disabled in WASM, single-threaded batch |
469
+ | Signal engine is opinionated | Make rules configurable, presets optional |
470
+ | Breaking changes on refactor | Version bump to 0.2, deprecation warnings |
package/Cargo.lock CHANGED
@@ -175,7 +175,7 @@ dependencies = [
175
175
 
176
176
  [[package]]
177
177
  name = "indica"
178
- version = "0.1.0"
178
+ version = "0.2.0"
179
179
  dependencies = [
180
180
  "napi",
181
181
  "napi-build",
package/Cargo.toml CHANGED
@@ -1,8 +1,8 @@
1
1
  [package]
2
2
  name = "indica"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  edition = "2024"
5
- description = "Fast technical analysis indicators for stock markets — SMA, EMA, RSI, MACD, Bollinger Bands, ATR, and more"
5
+ description = "Fast technical analysis indicators for Indian stock markets — 16 indicators, signal engine, batch screening, streaming API"
6
6
  license = "MIT"
7
7
  repository = "https://github.com/Devansh-365/indica"
8
8
  homepage = "https://github.com/Devansh-365/indica"