@ruvector/ruvllm 2.7.0 → 4.0.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 (151) hide show
  1. package/GPU-LOOP.md +229 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +9 -0
  4. package/README.md +157 -263
  5. package/examples/gpu-loop.example.json +26 -0
  6. package/package.json +50 -120
  7. package/src/adapters-cli.mjs +23 -0
  8. package/src/adapters.mjs +91 -0
  9. package/src/cli.mjs +30 -0
  10. package/src/engine.mjs +238 -0
  11. package/src/fixture.mjs +38 -0
  12. package/src/gpu-host.mjs +47 -0
  13. package/src/gpu-loop-cli.mjs +67 -0
  14. package/src/gpu-loop.mjs +184 -0
  15. package/src/gpu-spool-adapter.mjs +80 -0
  16. package/src/vast-host-adapter.mjs +274 -0
  17. package/bin/cli.js +0 -1020
  18. package/dist/cjs/benchmarks/embedding-benchmark.d.ts +0 -102
  19. package/dist/cjs/benchmarks/embedding-benchmark.d.ts.map +0 -1
  20. package/dist/cjs/benchmarks/embedding-benchmark.js +0 -436
  21. package/dist/cjs/benchmarks/index.d.ts +0 -34
  22. package/dist/cjs/benchmarks/index.d.ts.map +0 -1
  23. package/dist/cjs/benchmarks/index.js +0 -132
  24. package/dist/cjs/benchmarks/model-comparison.d.ts +0 -71
  25. package/dist/cjs/benchmarks/model-comparison.d.ts.map +0 -1
  26. package/dist/cjs/benchmarks/model-comparison.js +0 -476
  27. package/dist/cjs/benchmarks/routing-benchmark.d.ts +0 -70
  28. package/dist/cjs/benchmarks/routing-benchmark.d.ts.map +0 -1
  29. package/dist/cjs/benchmarks/routing-benchmark.js +0 -289
  30. package/dist/cjs/contrastive.d.ts +0 -229
  31. package/dist/cjs/contrastive.d.ts.map +0 -1
  32. package/dist/cjs/contrastive.js +0 -589
  33. package/dist/cjs/engine.d.ts +0 -95
  34. package/dist/cjs/engine.d.ts.map +0 -1
  35. package/dist/cjs/engine.js +0 -372
  36. package/dist/cjs/export.d.ts +0 -182
  37. package/dist/cjs/export.d.ts.map +0 -1
  38. package/dist/cjs/export.js +0 -422
  39. package/dist/cjs/federated.d.ts +0 -233
  40. package/dist/cjs/federated.d.ts.map +0 -1
  41. package/dist/cjs/federated.js +0 -525
  42. package/dist/cjs/index.d.ts +0 -68
  43. package/dist/cjs/index.d.ts.map +0 -1
  44. package/dist/cjs/index.js +0 -104
  45. package/dist/cjs/intelligence.d.ts +0 -136
  46. package/dist/cjs/intelligence.d.ts.map +0 -1
  47. package/dist/cjs/intelligence.js +0 -226
  48. package/dist/cjs/lora.d.ts +0 -251
  49. package/dist/cjs/lora.d.ts.map +0 -1
  50. package/dist/cjs/lora.js +0 -509
  51. package/dist/cjs/models.d.ts +0 -129
  52. package/dist/cjs/models.d.ts.map +0 -1
  53. package/dist/cjs/models.js +0 -323
  54. package/dist/cjs/native.d.ts +0 -92
  55. package/dist/cjs/native.d.ts.map +0 -1
  56. package/dist/cjs/native.js +0 -77
  57. package/dist/cjs/session.d.ts +0 -80
  58. package/dist/cjs/session.d.ts.map +0 -1
  59. package/dist/cjs/session.js +0 -203
  60. package/dist/cjs/simd.d.ts +0 -90
  61. package/dist/cjs/simd.d.ts.map +0 -1
  62. package/dist/cjs/simd.js +0 -209
  63. package/dist/cjs/sona.d.ts +0 -223
  64. package/dist/cjs/sona.d.ts.map +0 -1
  65. package/dist/cjs/sona.js +0 -562
  66. package/dist/cjs/streaming.d.ts +0 -55
  67. package/dist/cjs/streaming.d.ts.map +0 -1
  68. package/dist/cjs/streaming.js +0 -131
  69. package/dist/cjs/training.d.ts +0 -312
  70. package/dist/cjs/training.d.ts.map +0 -1
  71. package/dist/cjs/training.js +0 -610
  72. package/dist/cjs/types.d.ts +0 -615
  73. package/dist/cjs/types.d.ts.map +0 -1
  74. package/dist/cjs/types.js +0 -6
  75. package/dist/esm/benchmarks/embedding-benchmark.d.ts +0 -102
  76. package/dist/esm/benchmarks/embedding-benchmark.d.ts.map +0 -1
  77. package/dist/esm/benchmarks/embedding-benchmark.js +0 -427
  78. package/dist/esm/benchmarks/index.d.ts +0 -34
  79. package/dist/esm/benchmarks/index.d.ts.map +0 -1
  80. package/dist/esm/benchmarks/index.js +0 -110
  81. package/dist/esm/benchmarks/model-comparison.d.ts +0 -71
  82. package/dist/esm/benchmarks/model-comparison.d.ts.map +0 -1
  83. package/dist/esm/benchmarks/model-comparison.js +0 -434
  84. package/dist/esm/benchmarks/routing-benchmark.d.ts +0 -70
  85. package/dist/esm/benchmarks/routing-benchmark.d.ts.map +0 -1
  86. package/dist/esm/benchmarks/routing-benchmark.js +0 -283
  87. package/dist/esm/contrastive.d.ts +0 -229
  88. package/dist/esm/contrastive.d.ts.map +0 -1
  89. package/dist/esm/contrastive.js +0 -578
  90. package/dist/esm/engine.d.ts +0 -95
  91. package/dist/esm/engine.d.ts.map +0 -1
  92. package/dist/esm/engine.js +0 -368
  93. package/dist/esm/export.d.ts +0 -182
  94. package/dist/esm/export.d.ts.map +0 -1
  95. package/dist/esm/export.js +0 -414
  96. package/dist/esm/federated.d.ts +0 -233
  97. package/dist/esm/federated.d.ts.map +0 -1
  98. package/dist/esm/federated.js +0 -520
  99. package/dist/esm/index.d.ts +0 -68
  100. package/dist/esm/index.d.ts.map +0 -1
  101. package/dist/esm/index.js +0 -84
  102. package/dist/esm/intelligence.d.ts +0 -136
  103. package/dist/esm/intelligence.d.ts.map +0 -1
  104. package/dist/esm/intelligence.js +0 -188
  105. package/dist/esm/lora.d.ts +0 -251
  106. package/dist/esm/lora.d.ts.map +0 -1
  107. package/dist/esm/lora.js +0 -504
  108. package/dist/esm/models.d.ts +0 -129
  109. package/dist/esm/models.d.ts.map +0 -1
  110. package/dist/esm/models.js +0 -282
  111. package/dist/esm/native.d.ts +0 -92
  112. package/dist/esm/native.d.ts.map +0 -1
  113. package/dist/esm/native.js +0 -72
  114. package/dist/esm/session.d.ts +0 -80
  115. package/dist/esm/session.d.ts.map +0 -1
  116. package/dist/esm/session.js +0 -199
  117. package/dist/esm/simd.d.ts +0 -90
  118. package/dist/esm/simd.d.ts.map +0 -1
  119. package/dist/esm/simd.js +0 -205
  120. package/dist/esm/sona.d.ts +0 -223
  121. package/dist/esm/sona.d.ts.map +0 -1
  122. package/dist/esm/sona.js +0 -556
  123. package/dist/esm/streaming.d.ts +0 -55
  124. package/dist/esm/streaming.d.ts.map +0 -1
  125. package/dist/esm/streaming.js +0 -126
  126. package/dist/esm/training.d.ts +0 -312
  127. package/dist/esm/training.d.ts.map +0 -1
  128. package/dist/esm/training.js +0 -603
  129. package/dist/esm/types.d.ts +0 -615
  130. package/dist/esm/types.d.ts.map +0 -1
  131. package/dist/esm/types.js +0 -5
  132. package/scripts/ensemble-model-compare.js +0 -287
  133. package/scripts/fix-esm-extensions.mjs +0 -181
  134. package/scripts/huggingface/README.md +0 -537
  135. package/scripts/huggingface/publish.sh +0 -112
  136. package/scripts/hybrid-model-compare.js +0 -373
  137. package/scripts/improved-model-compare.js +0 -288
  138. package/scripts/optimized-model-compare.js +0 -364
  139. package/scripts/real-model-compare.js +0 -280
  140. package/scripts/smoke-esm.mjs +0 -82
  141. package/scripts/training/agentic-flow-capabilities.json +0 -329
  142. package/scripts/training/claude-code-synth.js +0 -505
  143. package/scripts/training/claude-flow-capabilities.json +0 -1322
  144. package/scripts/training/claude-hard-negatives.js +0 -222
  145. package/scripts/training/contrastive-finetune.js +0 -517
  146. package/scripts/training/ecosystem-triplets.jsonl +0 -1467
  147. package/scripts/training/generate-ecosystem-triplets.js +0 -1324
  148. package/scripts/training/routing-dataset.js +0 -634
  149. package/scripts/training/ruvector-capabilities.json +0 -798
  150. package/scripts/training/validate-ecosystem.js +0 -381
  151. package/scripts/training/validation-results.json +0 -23
@@ -1,80 +0,0 @@
1
- /**
2
- * Session Management for multi-turn conversations
3
- */
4
- import { ConversationSession, ConversationMessage, QueryResponse, GenerationConfig } from './types.js';
5
- /**
6
- * Session Manager for multi-turn conversations
7
- *
8
- * @example
9
- * ```typescript
10
- * import { RuvLLM, SessionManager } from '@ruvector/ruvllm';
11
- *
12
- * const llm = new RuvLLM();
13
- * const sessions = new SessionManager(llm);
14
- *
15
- * // Create a new session
16
- * const session = sessions.create();
17
- *
18
- * // Chat with context
19
- * const response1 = sessions.chat(session.id, 'What is Python?');
20
- * const response2 = sessions.chat(session.id, 'How do I install it?');
21
- * // Second query automatically has context from first
22
- * ```
23
- */
24
- export declare class SessionManager {
25
- private sessions;
26
- private llm;
27
- constructor(llm: {
28
- query: (text: string, config?: GenerationConfig) => QueryResponse;
29
- addMemory: (content: string, metadata?: Record<string, unknown>) => number;
30
- });
31
- /**
32
- * Create a new conversation session
33
- */
34
- create(metadata?: Record<string, unknown>): ConversationSession;
35
- /**
36
- * Get session by ID
37
- */
38
- get(sessionId: string): ConversationSession | undefined;
39
- /**
40
- * Chat within a session (maintains context)
41
- */
42
- chat(sessionId: string, message: string, config?: GenerationConfig): QueryResponse;
43
- /**
44
- * Add system message to session
45
- */
46
- addSystemMessage(sessionId: string, content: string): void;
47
- /**
48
- * Add context to session (persisted to memory)
49
- */
50
- addContext(sessionId: string, context: string): number;
51
- /**
52
- * Get conversation history
53
- */
54
- getHistory(sessionId: string, limit?: number): ConversationMessage[];
55
- /**
56
- * Clear session history (keep session active)
57
- */
58
- clearHistory(sessionId: string): void;
59
- /**
60
- * End and delete session
61
- */
62
- end(sessionId: string): boolean;
63
- /**
64
- * List all active sessions
65
- */
66
- list(): ConversationSession[];
67
- /**
68
- * Export session as JSON
69
- */
70
- export(sessionId: string): string | null;
71
- /**
72
- * Import session from JSON
73
- */
74
- import(json: string): ConversationSession;
75
- /**
76
- * Build context string from recent messages
77
- */
78
- private buildContext;
79
- }
80
- //# sourceMappingURL=session.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,GAAG,CAAoJ;gBAEnJ,GAAG,EAAE;QAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,KAAK,aAAa,CAAC;QAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;KAAE;IAIlK;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB;IAe/D;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIvD;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,aAAa;IAiClF;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAc1D;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAmBtD;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAUpE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IASrC;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B;;OAEG;IACH,IAAI,IAAI,mBAAmB,EAAE;IAI7B;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASxC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB;IAezC;;OAEG;IACH,OAAO,CAAC,YAAY;CA2BrB"}
@@ -1,199 +0,0 @@
1
- /**
2
- * Session Management for multi-turn conversations
3
- */
4
- /**
5
- * Session Manager for multi-turn conversations
6
- *
7
- * @example
8
- * ```typescript
9
- * import { RuvLLM, SessionManager } from '@ruvector/ruvllm';
10
- *
11
- * const llm = new RuvLLM();
12
- * const sessions = new SessionManager(llm);
13
- *
14
- * // Create a new session
15
- * const session = sessions.create();
16
- *
17
- * // Chat with context
18
- * const response1 = sessions.chat(session.id, 'What is Python?');
19
- * const response2 = sessions.chat(session.id, 'How do I install it?');
20
- * // Second query automatically has context from first
21
- * ```
22
- */
23
- export class SessionManager {
24
- constructor(llm) {
25
- this.sessions = new Map();
26
- this.llm = llm;
27
- }
28
- /**
29
- * Create a new conversation session
30
- */
31
- create(metadata) {
32
- const id = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
33
- const session = {
34
- id,
35
- createdAt: new Date(),
36
- messageCount: 0,
37
- messages: [],
38
- context: [],
39
- activeMemoryIds: [],
40
- metadata: metadata ?? {},
41
- };
42
- this.sessions.set(id, session);
43
- return session;
44
- }
45
- /**
46
- * Get session by ID
47
- */
48
- get(sessionId) {
49
- return this.sessions.get(sessionId);
50
- }
51
- /**
52
- * Chat within a session (maintains context)
53
- */
54
- chat(sessionId, message, config) {
55
- const session = this.sessions.get(sessionId);
56
- if (!session) {
57
- throw new Error(`Session not found: ${sessionId}`);
58
- }
59
- // Add user message
60
- session.messages.push({
61
- role: 'user',
62
- content: message,
63
- timestamp: new Date(),
64
- });
65
- // Build context from recent messages
66
- const contextWindow = this.buildContext(session);
67
- // Query with context
68
- const prompt = contextWindow ? `${contextWindow}\n\nUser: ${message}` : message;
69
- const response = this.llm.query(prompt, config);
70
- // Add assistant response
71
- session.messages.push({
72
- role: 'assistant',
73
- content: response.text,
74
- timestamp: new Date(),
75
- requestId: response.requestId,
76
- });
77
- session.messageCount = session.messages.length;
78
- return response;
79
- }
80
- /**
81
- * Add system message to session
82
- */
83
- addSystemMessage(sessionId, content) {
84
- const session = this.sessions.get(sessionId);
85
- if (!session) {
86
- throw new Error(`Session not found: ${sessionId}`);
87
- }
88
- session.messages.push({
89
- role: 'system',
90
- content,
91
- timestamp: new Date(),
92
- });
93
- session.messageCount = session.messages.length;
94
- }
95
- /**
96
- * Add context to session (persisted to memory)
97
- */
98
- addContext(sessionId, context) {
99
- const session = this.sessions.get(sessionId);
100
- if (!session) {
101
- throw new Error(`Session not found: ${sessionId}`);
102
- }
103
- session.context.push(context);
104
- // Also store in memory for retrieval
105
- const memoryId = this.llm.addMemory(context, {
106
- sessionId,
107
- type: 'context',
108
- timestamp: new Date().toISOString(),
109
- });
110
- session.activeMemoryIds.push(memoryId);
111
- return memoryId;
112
- }
113
- /**
114
- * Get conversation history
115
- */
116
- getHistory(sessionId, limit) {
117
- const session = this.sessions.get(sessionId);
118
- if (!session) {
119
- return [];
120
- }
121
- const messages = session.messages;
122
- return limit ? messages.slice(-limit) : messages;
123
- }
124
- /**
125
- * Clear session history (keep session active)
126
- */
127
- clearHistory(sessionId) {
128
- const session = this.sessions.get(sessionId);
129
- if (session) {
130
- session.messages = [];
131
- session.context = [];
132
- session.messageCount = 0;
133
- }
134
- }
135
- /**
136
- * End and delete session
137
- */
138
- end(sessionId) {
139
- return this.sessions.delete(sessionId);
140
- }
141
- /**
142
- * List all active sessions
143
- */
144
- list() {
145
- return Array.from(this.sessions.values());
146
- }
147
- /**
148
- * Export session as JSON
149
- */
150
- export(sessionId) {
151
- const session = this.sessions.get(sessionId);
152
- if (!session) {
153
- return null;
154
- }
155
- return JSON.stringify(session, null, 2);
156
- }
157
- /**
158
- * Import session from JSON
159
- */
160
- import(json) {
161
- const data = JSON.parse(json);
162
- const session = {
163
- ...data,
164
- createdAt: new Date(data.createdAt),
165
- messages: data.messages.map((m) => ({
166
- ...m,
167
- timestamp: new Date(m.timestamp),
168
- })),
169
- };
170
- this.sessions.set(session.id, session);
171
- return session;
172
- }
173
- /**
174
- * Build context string from recent messages
175
- */
176
- buildContext(session, maxMessages = 10) {
177
- const recent = session.messages.slice(-maxMessages);
178
- if (recent.length === 0) {
179
- return '';
180
- }
181
- const contextParts = [];
182
- // Add persistent context
183
- if (session.context.length > 0) {
184
- contextParts.push('Context:\n' + session.context.join('\n'));
185
- }
186
- // Add conversation history
187
- const history = recent
188
- .map(m => {
189
- const role = m.role === 'user' ? 'User' : m.role === 'assistant' ? 'Assistant' : 'System';
190
- return `${role}: ${m.content}`;
191
- })
192
- .join('\n');
193
- if (history) {
194
- contextParts.push('Conversation:\n' + history);
195
- }
196
- return contextParts.join('\n\n');
197
- }
198
- }
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXNzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBU0g7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBSXpCLFlBQVksR0FBc0o7UUFIMUosYUFBUSxHQUFxQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSTdELElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxRQUFrQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxXQUFXLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM3RSxNQUFNLE9BQU8sR0FBd0I7WUFDbkMsRUFBRTtZQUNGLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTtZQUNyQixZQUFZLEVBQUUsQ0FBQztZQUNmLFFBQVEsRUFBRSxFQUFFO1lBQ1osT0FBTyxFQUFFLEVBQUU7WUFDWCxlQUFlLEVBQUUsRUFBRTtZQUNuQixRQUFRLEVBQUUsUUFBUSxJQUFJLEVBQUU7U0FDekIsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvQixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxHQUFHLENBQUMsU0FBaUI7UUFDbkIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLENBQUMsU0FBaUIsRUFBRSxPQUFlLEVBQUUsTUFBeUI7UUFDaEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFD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QUFDLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzFGLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVkLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTZXNzaW9uIE1hbmFnZW1lbnQgZm9yIG11bHRpLXR1cm4gY29udmVyc2F0aW9uc1xuICovXG5cbmltcG9ydCB7XG4gIENvbnZlcnNhdGlvblNlc3Npb24sXG4gIENvbnZlcnNhdGlvbk1lc3NhZ2UsXG4gIFF1ZXJ5UmVzcG9uc2UsXG4gIEdlbmVyYXRpb25Db25maWcsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIFNlc3Npb24gTWFuYWdlciBmb3IgbXVsdGktdHVybiBjb252ZXJzYXRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFJ1dkxMTSwgU2Vzc2lvbk1hbmFnZXIgfSBmcm9tICdAcnV2ZWN0b3IvcnV2bGxtJztcbiAqXG4gKiBjb25zdCBsbG0gPSBuZXcgUnV2TExNKCk7XG4gKiBjb25zdCBzZXNzaW9ucyA9IG5ldyBTZXNzaW9uTWFuYWdlcihsbG0pO1xuICpcbiAqIC8vIENyZWF0ZSBhIG5ldyBzZXNzaW9uXG4gKiBjb25zdCBzZXNzaW9uID0gc2Vzc2lvbnMuY3JlYXRlKCk7XG4gKlxuICogLy8gQ2hhdCB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IHJlc3BvbnNlMSA9IHNlc3Npb25zLmNoYXQoc2Vzc2lvbi5pZCwgJ1doYXQgaXMgUHl0aG9uPycpO1xuICogY29uc3QgcmVzcG9uc2UyID0gc2Vzc2lvbnMuY2hhdChzZXNzaW9uLmlkLCAnSG93IGRvIEkgaW5zdGFsbCBpdD8nKTtcbiAqIC8vIFNlY29uZCBxdWVyeSBhdXRvbWF0aWNhbGx5IGhhcyBjb250ZXh0IGZyb20gZmlyc3RcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbk1hbmFnZXIge1xuICBwcml2YXRlIHNlc3Npb25zOiBNYXA8c3RyaW5nLCBDb252ZXJzYXRpb25TZXNzaW9uPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBsbG06IHsgcXVlcnk6ICh0ZXh0OiBzdHJpbmcsIGNvbmZpZz86IEdlbmVyYXRpb25Db25maWcpID0+IFF1ZXJ5UmVzcG9uc2U7IGFkZE1lbW9yeTogKGNvbnRlbnQ6IHN0cmluZywgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gbnVtYmVyIH07XG5cbiAgY29uc3RydWN0b3IobGxtOiB7IHF1ZXJ5OiAodGV4dDogc3RyaW5nLCBjb25maWc/OiBHZW5lcmF0aW9uQ29uZmlnKSA9PiBRdWVyeVJlc3BvbnNlOyBhZGRNZW1vcnk6IChjb250ZW50OiBzdHJpbmcsIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IG51bWJlciB9KSB7XG4gICAgdGhpcy5sbG0gPSBsbG07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGNvbnZlcnNhdGlvbiBzZXNzaW9uXG4gICAqL1xuICBjcmVhdGUobWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IENvbnZlcnNhdGlvblNlc3Npb24ge1xuICAgIGNvbnN0IGlkID0gYHNlc3Npb24tJHtEYXRlLm5vdygpfS0ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIsIDgpfWA7XG4gICAgY29uc3Qgc2Vzc2lvbjogQ29udmVyc2F0aW9uU2Vzc2lvbiA9IHtcbiAgICAgIGlkLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgbWVzc2FnZUNvdW50OiAwLFxuICAgICAgbWVzc2FnZXM6IFtdLFxuICAgICAgY29udGV4dDogW10sXG4gICAgICBhY3RpdmVNZW1vcnlJZHM6IFtdLFxuICAgICAgbWV0YWRhdGE6IG1ldGFkYXRhID8/IHt9LFxuICAgIH07XG4gICAgdGhpcy5zZXNzaW9ucy5zZXQoaWQsIHNlc3Npb24pO1xuICAgIHJldHVybiBzZXNzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzZXNzaW9uIGJ5IElEXG4gICAqL1xuICBnZXQoc2Vzc2lvbklkOiBzdHJpbmcpOiBDb252ZXJzYXRpb25TZXNzaW9uIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGF0IHdpdGhpbiBhIHNlc3Npb24gKG1haW50YWlucyBjb250ZXh0KVxuICAgKi9cbiAgY2hhdChzZXNzaW9uSWQ6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBjb25maWc/OiBHZW5lcmF0aW9uQ29uZmlnKTogUXVlcnlSZXNwb25zZSB7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlc3Npb24gbm90IGZvdW5kOiAke3Nlc3Npb25JZH1gKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgdXNlciBtZXNzYWdlXG4gICAgc2Vzc2lvbi5tZXNzYWdlcy5wdXNoKHtcbiAgICAgIHJvbGU6ICd1c2VyJyxcbiAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UsXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gICAgfSk7XG5cbiAgICAvLyBCdWlsZCBjb250ZXh0IGZyb20gcmVjZW50IG1lc3NhZ2VzXG4gICAgY29uc3QgY29udGV4dFdpbmRvdyA9IHRoaXMuYnVpbGRDb250ZXh0KHNlc3Npb24pO1xuXG4gICAgLy8gUXVlcnkgd2l0aCBjb250ZXh0XG4gICAgY29uc3QgcHJvbXB0ID0gY29udGV4dFdpbmRvdyA/IGAke2NvbnRleHRXaW5kb3d9XFxuXFxuVXNlcjogJHttZXNzYWdlfWAgOiBtZXNzYWdlO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5sbG0ucXVlcnkocHJvbXB0LCBjb25maWcpO1xuXG4gICAgLy8gQWRkIGFzc2lzdGFudCByZXNwb25zZVxuICAgIHNlc3Npb24ubWVzc2FnZXMucHVzaCh7XG4gICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgIGNvbnRlbnQ6IHJlc3BvbnNlLnRleHQsXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gICAgICByZXF1ZXN0SWQ6IHJlc3BvbnNlLnJlcXVlc3RJZCxcbiAgICB9KTtcblxuICAgIHNlc3Npb24ubWVzc2FnZUNvdW50ID0gc2Vzc2lvbi5tZXNzYWdlcy5sZW5ndGg7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHN5c3RlbSBtZXNzYWdlIHRvIHNlc3Npb25cbiAgICovXG4gIGFkZFN5c3RlbU1lc3NhZ2Uoc2Vzc2lvbklkOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXNzaW9uIG5vdCBmb3VuZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgfVxuXG4gICAgc2Vzc2lvbi5tZXNzYWdlcy5wdXNoKHtcbiAgICAgIHJvbGU6ICdzeXN0ZW0nLFxuICAgICAgY29udGVudCxcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcbiAgICB9KTtcbiAgICBzZXNzaW9uLm1lc3NhZ2VDb3VudCA9IHNlc3Npb24ubWVzc2FnZXMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBjb250ZXh0IHRvIHNlc3Npb24gKHBlcnNpc3RlZCB0byBtZW1vcnkpXG4gICAqL1xuICBhZGRDb250ZXh0KHNlc3Npb25JZDogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXNzaW9uIG5vdCBmb3VuZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgfVxuXG4gICAgc2Vzc2lvbi5jb250ZXh0LnB1c2goY29udGV4dCk7XG5cbiAgICAvLyBBbHNvIHN0b3JlIGluIG1lbW9yeSBmb3IgcmV0cmlldmFsXG4gICAgY29uc3QgbWVtb3J5SWQgPSB0aGlzLmxsbS5hZGRNZW1vcnkoY29udGV4dCwge1xuICAgICAgc2Vzc2lvbklkLFxuICAgICAgdHlwZTogJ2NvbnRleHQnLFxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgfSk7XG5cbiAgICBzZXNzaW9uLmFjdGl2ZU1lbW9yeUlkcy5wdXNoKG1lbW9yeUlkKTtcbiAgICByZXR1cm4gbWVtb3J5SWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNvbnZlcnNhdGlvbiBoaXN0b3J5XG4gICAqL1xuICBnZXRIaXN0b3J5KHNlc3Npb25JZDogc3RyaW5nLCBsaW1pdD86IG51bWJlcik6IENvbnZlcnNhdGlvbk1lc3NhZ2VbXSB7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZXMgPSBzZXNzaW9uLm1lc3NhZ2VzO1xuICAgIHJldHVybiBsaW1pdCA/IG1lc3NhZ2VzLnNsaWNlKC1saW1pdCkgOiBtZXNzYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBzZXNzaW9uIGhpc3RvcnkgKGtlZXAgc2Vzc2lvbiBhY3RpdmUpXG4gICAqL1xuICBjbGVhckhpc3Rvcnkoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoc2Vzc2lvbikge1xuICAgICAgc2Vzc2lvbi5tZXNzYWdlcyA9IFtdO1xuICAgICAgc2Vzc2lvbi5jb250ZXh0ID0gW107XG4gICAgICBzZXNzaW9uLm1lc3NhZ2VDb3VudCA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuZCBhbmQgZGVsZXRlIHNlc3Npb25cbiAgICovXG4gIGVuZChzZXNzaW9uSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNlc3Npb25zLmRlbGV0ZShzZXNzaW9uSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3QgYWxsIGFjdGl2ZSBzZXNzaW9uc1xuICAgKi9cbiAgbGlzdCgpOiBDb252ZXJzYXRpb25TZXNzaW9uW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuc2Vzc2lvbnMudmFsdWVzKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCBzZXNzaW9uIGFzIEpTT05cbiAgICovXG4gIGV4cG9ydChzZXNzaW9uSWQ6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNlc3Npb24sIG51bGwsIDIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBzZXNzaW9uIGZyb20gSlNPTlxuICAgKi9cbiAgaW1wb3J0KGpzb246IHN0cmluZyk6IENvbnZlcnNhdGlvblNlc3Npb24ge1xuICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKGpzb24pO1xuICAgIGNvbnN0IHNlc3Npb246IENvbnZlcnNhdGlvblNlc3Npb24gPSB7XG4gICAgICAuLi5kYXRhLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRBdCksXG4gICAgICBtZXNzYWdlczogZGF0YS5tZXNzYWdlcy5tYXAoKG06IENvbnZlcnNhdGlvbk1lc3NhZ2UpID0+ICh7XG4gICAgICAgIC4uLm0sXG4gICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUobS50aW1lc3RhbXApLFxuICAgICAgfSkpLFxuICAgIH07XG5cbiAgICB0aGlzLnNlc3Npb25zLnNldChzZXNzaW9uLmlkLCBzZXNzaW9uKTtcbiAgICByZXR1cm4gc2Vzc2lvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBjb250ZXh0IHN0cmluZyBmcm9tIHJlY2VudCBtZXNzYWdlc1xuICAgKi9cbiAgcHJpdmF0ZSBidWlsZENvbnRleHQoc2Vzc2lvbjogQ29udmVyc2F0aW9uU2Vzc2lvbiwgbWF4TWVzc2FnZXMgPSAxMCk6IHN0cmluZyB7XG4gICAgY29uc3QgcmVjZW50ID0gc2Vzc2lvbi5tZXNzYWdlcy5zbGljZSgtbWF4TWVzc2FnZXMpO1xuICAgIGlmIChyZWNlbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dFBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQWRkIHBlcnNpc3RlbnQgY29udGV4dFxuICAgIGlmIChzZXNzaW9uLmNvbnRleHQubGVuZ3RoID4gMCkge1xuICAgICAgY29udGV4dFBhcnRzLnB1c2goJ0NvbnRleHQ6XFxuJyArIHNlc3Npb24uY29udGV4dC5qb2luKCdcXG4nKSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGNvbnZlcnNhdGlvbiBoaXN0b3J5XG4gICAgY29uc3QgaGlzdG9yeSA9IHJlY2VudFxuICAgICAgLm1hcChtID0+IHtcbiAgICAgICAgY29uc3Qgcm9sZSA9IG0ucm9sZSA9PT0gJ3VzZXInID8gJ1VzZXInIDogbS5yb2xlID09PSAnYXNzaXN0YW50JyA/ICdBc3Npc3RhbnQnIDogJ1N5c3RlbSc7XG4gICAgICAgIHJldHVybiBgJHtyb2xlfTogJHttLmNvbnRlbnR9YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignXFxuJyk7XG5cbiAgICBpZiAoaGlzdG9yeSkge1xuICAgICAgY29udGV4dFBhcnRzLnB1c2goJ0NvbnZlcnNhdGlvbjpcXG4nICsgaGlzdG9yeSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHRQYXJ0cy5qb2luKCdcXG5cXG4nKTtcbiAgfVxufVxuIl19
@@ -1,90 +0,0 @@
1
- /**
2
- * SIMD Operations for vector computations
3
- *
4
- * Uses native SIMD instructions (AVX2/AVX512/SSE4.1/NEON) when available,
5
- * falls back to JavaScript implementations otherwise.
6
- */
7
- /**
8
- * SIMD Operations class
9
- *
10
- * Provides hardware-accelerated vector operations when native module is available.
11
- *
12
- * @example
13
- * ```typescript
14
- * import { SimdOps } from '@ruvector/ruvllm';
15
- *
16
- * const simd = new SimdOps();
17
- *
18
- * // Compute dot product
19
- * const result = simd.dotProduct([1, 2, 3], [4, 5, 6]);
20
- * console.log(result); // 32
21
- *
22
- * // Check capabilities
23
- * console.log(simd.capabilities()); // ['AVX2', 'FMA']
24
- * ```
25
- */
26
- export declare class SimdOps {
27
- private native;
28
- constructor();
29
- /**
30
- * Compute dot product of two vectors
31
- */
32
- dotProduct(a: number[], b: number[]): number;
33
- /**
34
- * Compute cosine similarity between two vectors
35
- */
36
- cosineSimilarity(a: number[], b: number[]): number;
37
- /**
38
- * Compute L2 (Euclidean) distance between two vectors
39
- */
40
- l2Distance(a: number[], b: number[]): number;
41
- /**
42
- * Matrix-vector multiplication
43
- */
44
- matvec(matrix: number[][], vector: number[]): number[];
45
- /**
46
- * Softmax activation function
47
- */
48
- softmax(input: number[]): number[];
49
- /**
50
- * Element-wise addition
51
- */
52
- add(a: number[], b: number[]): number[];
53
- /**
54
- * Element-wise multiplication
55
- */
56
- mul(a: number[], b: number[]): number[];
57
- /**
58
- * Scale vector by scalar
59
- */
60
- scale(a: number[], scalar: number): number[];
61
- /**
62
- * Normalize vector to unit length
63
- */
64
- normalize(a: number[]): number[];
65
- /**
66
- * ReLU activation
67
- */
68
- relu(input: number[]): number[];
69
- /**
70
- * GELU activation (approximate)
71
- */
72
- gelu(input: number[]): number[];
73
- /**
74
- * Sigmoid activation
75
- */
76
- sigmoid(input: number[]): number[];
77
- /**
78
- * Layer normalization
79
- */
80
- layerNorm(input: number[], eps?: number): number[];
81
- /**
82
- * Check if native SIMD is available
83
- */
84
- isNative(): boolean;
85
- /**
86
- * Get available SIMD capabilities
87
- */
88
- capabilities(): string[];
89
- }
90
- //# sourceMappingURL=simd.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"simd.d.ts","sourceRoot":"","sources":["../../src/simd.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAA8B;;IAa5C;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAc5C;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAqBlD;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAe5C;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAStD;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAYlC;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IASvC;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IASvC;;OAEG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAI5C;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAKhC;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAI/B;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAM/B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAIlC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,SAAO,GAAG,MAAM,EAAE;IAOhD;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;CAkBzB"}
package/dist/esm/simd.js DELETED
@@ -1,205 +0,0 @@
1
- /**
2
- * SIMD Operations for vector computations
3
- *
4
- * Uses native SIMD instructions (AVX2/AVX512/SSE4.1/NEON) when available,
5
- * falls back to JavaScript implementations otherwise.
6
- */
7
- import { getNativeModule } from './native.js';
8
- /**
9
- * SIMD Operations class
10
- *
11
- * Provides hardware-accelerated vector operations when native module is available.
12
- *
13
- * @example
14
- * ```typescript
15
- * import { SimdOps } from '@ruvector/ruvllm';
16
- *
17
- * const simd = new SimdOps();
18
- *
19
- * // Compute dot product
20
- * const result = simd.dotProduct([1, 2, 3], [4, 5, 6]);
21
- * console.log(result); // 32
22
- *
23
- * // Check capabilities
24
- * console.log(simd.capabilities()); // ['AVX2', 'FMA']
25
- * ```
26
- */
27
- export class SimdOps {
28
- constructor() {
29
- this.native = null;
30
- const mod = getNativeModule();
31
- if (mod) {
32
- try {
33
- this.native = new mod.SimdOperations();
34
- }
35
- catch {
36
- // Fall back to JS implementation
37
- }
38
- }
39
- }
40
- /**
41
- * Compute dot product of two vectors
42
- */
43
- dotProduct(a, b) {
44
- if (this.native) {
45
- return this.native.dotProduct(a, b);
46
- }
47
- // JavaScript fallback
48
- let sum = 0;
49
- const len = Math.min(a.length, b.length);
50
- for (let i = 0; i < len; i++) {
51
- sum += a[i] * b[i];
52
- }
53
- return sum;
54
- }
55
- /**
56
- * Compute cosine similarity between two vectors
57
- */
58
- cosineSimilarity(a, b) {
59
- if (this.native) {
60
- return this.native.cosineSimilarity(a, b);
61
- }
62
- // JavaScript fallback
63
- let dot = 0;
64
- let normA = 0;
65
- let normB = 0;
66
- const len = Math.min(a.length, b.length);
67
- for (let i = 0; i < len; i++) {
68
- dot += a[i] * b[i];
69
- normA += a[i] * a[i];
70
- normB += b[i] * b[i];
71
- }
72
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
73
- return denom > 0 ? dot / denom : 0;
74
- }
75
- /**
76
- * Compute L2 (Euclidean) distance between two vectors
77
- */
78
- l2Distance(a, b) {
79
- if (this.native) {
80
- return this.native.l2Distance(a, b);
81
- }
82
- // JavaScript fallback
83
- let sum = 0;
84
- const len = Math.min(a.length, b.length);
85
- for (let i = 0; i < len; i++) {
86
- const diff = a[i] - b[i];
87
- sum += diff * diff;
88
- }
89
- return Math.sqrt(sum);
90
- }
91
- /**
92
- * Matrix-vector multiplication
93
- */
94
- matvec(matrix, vector) {
95
- if (this.native) {
96
- return this.native.matvec(matrix, vector);
97
- }
98
- // JavaScript fallback
99
- return matrix.map(row => this.dotProduct(row, vector));
100
- }
101
- /**
102
- * Softmax activation function
103
- */
104
- softmax(input) {
105
- if (this.native) {
106
- return this.native.softmax(input);
107
- }
108
- // JavaScript fallback
109
- const max = Math.max(...input);
110
- const exps = input.map(x => Math.exp(x - max));
111
- const sum = exps.reduce((a, b) => a + b, 0);
112
- return exps.map(x => x / sum);
113
- }
114
- /**
115
- * Element-wise addition
116
- */
117
- add(a, b) {
118
- const len = Math.min(a.length, b.length);
119
- const result = new Array(len);
120
- for (let i = 0; i < len; i++) {
121
- result[i] = a[i] + b[i];
122
- }
123
- return result;
124
- }
125
- /**
126
- * Element-wise multiplication
127
- */
128
- mul(a, b) {
129
- const len = Math.min(a.length, b.length);
130
- const result = new Array(len);
131
- for (let i = 0; i < len; i++) {
132
- result[i] = a[i] * b[i];
133
- }
134
- return result;
135
- }
136
- /**
137
- * Scale vector by scalar
138
- */
139
- scale(a, scalar) {
140
- return a.map(x => x * scalar);
141
- }
142
- /**
143
- * Normalize vector to unit length
144
- */
145
- normalize(a) {
146
- const norm = Math.sqrt(a.reduce((sum, x) => sum + x * x, 0));
147
- return norm > 0 ? a.map(x => x / norm) : a;
148
- }
149
- /**
150
- * ReLU activation
151
- */
152
- relu(input) {
153
- return input.map(x => Math.max(0, x));
154
- }
155
- /**
156
- * GELU activation (approximate)
157
- */
158
- gelu(input) {
159
- return input.map(x => {
160
- return 0.5 * x * (1 + Math.tanh(Math.sqrt(2 / Math.PI) * (x + 0.044715 * x * x * x)));
161
- });
162
- }
163
- /**
164
- * Sigmoid activation
165
- */
166
- sigmoid(input) {
167
- return input.map(x => 1 / (1 + Math.exp(-x)));
168
- }
169
- /**
170
- * Layer normalization
171
- */
172
- layerNorm(input, eps = 1e-5) {
173
- const mean = input.reduce((a, b) => a + b, 0) / input.length;
174
- const variance = input.reduce((sum, x) => sum + (x - mean) ** 2, 0) / input.length;
175
- const std = Math.sqrt(variance + eps);
176
- return input.map(x => (x - mean) / std);
177
- }
178
- /**
179
- * Check if native SIMD is available
180
- */
181
- isNative() {
182
- return this.native !== null;
183
- }
184
- /**
185
- * Get available SIMD capabilities
186
- */
187
- capabilities() {
188
- if (!this.native) {
189
- return ['JavaScript (scalar)'];
190
- }
191
- // The native module will report actual capabilities
192
- const mod = getNativeModule();
193
- if (mod) {
194
- try {
195
- const engine = new mod.RuvLLMEngine();
196
- return engine.simdCapabilities();
197
- }
198
- catch {
199
- return ['Native (unknown)'];
200
- }
201
- }
202
- return ['JavaScript (scalar)'];
203
- }
204
- }
205
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaW1kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBaUIsTUFBTSxVQUFVLENBQUM7QUFFMUQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sT0FBTyxPQUFPO0lBR2xCO1FBRlEsV0FBTSxHQUF5QixJQUFJLENBQUM7UUFHMUMsTUFBTSxHQUFHLEdBQUcsZUFBZSxFQUFFLENBQUM7UUFDOUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNSLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3pDLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsaUNBQWlDO1lBQ25DLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVSxDQUFDLENBQVcsRUFBRSxDQUFXO1FBQ2pDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFFRCxzQkFBc0I7UUFDdEIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDN0IsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2Is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QUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsb0RBQW9EO1FBQ3BELE1BQU0sR0FBRyxHQUFHLGVBQWUsRUFBRSxDQUFDO1FBQzlCLElBQUksR0FBRyxFQUFFLENBQUM7WUFDUixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RDLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDbkMsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU0lNRCBPcGVyYXRpb25zIGZvciB2ZWN0b3IgY29tcHV0YXRpb25zXG4gKlxuICogVXNlcyBuYXRpdmUgU0lNRCBpbnN0cnVjdGlvbnMgKEFWWDIvQVZYNTEyL1NTRTQuMS9ORU9OKSB3aGVuIGF2YWlsYWJsZSxcbiAqIGZhbGxzIGJhY2sgdG8gSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbnMgb3RoZXJ3aXNlLlxuICovXG5cbmltcG9ydCB7IGdldE5hdGl2ZU1vZHVsZSwgTmF0aXZlU2ltZE9wcyB9IGZyb20gJy4vbmF0aXZlJztcblxuLyoqXG4gKiBTSU1EIE9wZXJhdGlvbnMgY2xhc3NcbiAqXG4gKiBQcm92aWRlcyBoYXJkd2FyZS1hY2NlbGVyYXRlZCB2ZWN0b3Igb3BlcmF0aW9ucyB3aGVuIG5hdGl2ZSBtb2R1bGUgaXMgYXZhaWxhYmxlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBTaW1kT3BzIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3Qgc2ltZCA9IG5ldyBTaW1kT3BzKCk7XG4gKlxuICogLy8gQ29tcHV0ZSBkb3QgcHJvZHVjdFxuICogY29uc3QgcmVzdWx0ID0gc2ltZC5kb3RQcm9kdWN0KFsxLCAyLCAzXSwgWzQsIDUsIDZdKTtcbiAqIGNvbnNvbGUubG9nKHJlc3VsdCk7IC8vIDMyXG4gKlxuICogLy8gQ2hlY2sgY2FwYWJpbGl0aWVzXG4gKiBjb25zb2xlLmxvZyhzaW1kLmNhcGFiaWxpdGllcygpKTsgLy8gWydBVlgyJywgJ0ZNQSddXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNpbWRPcHMge1xuICBwcml2YXRlIG5hdGl2ZTogTmF0aXZlU2ltZE9wcyB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IG1vZCA9IGdldE5hdGl2ZU1vZHVsZSgpO1xuICAgIGlmIChtb2QpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMubmF0aXZlID0gbmV3IG1vZC5TaW1kT3BlcmF0aW9ucygpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIEZhbGwgYmFjayB0byBKUyBpbXBsZW1lbnRhdGlvblxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGRvdCBwcm9kdWN0IG9mIHR3byB2ZWN0b3JzXG4gICAqL1xuICBkb3RQcm9kdWN0KGE6IG51bWJlcltdLCBiOiBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMubmF0aXZlKSB7XG4gICAgICByZXR1cm4gdGhpcy5uYXRpdmUuZG90UHJvZHVjdChhLCBiKTtcbiAgICB9XG5cbiAgICAvLyBKYXZhU2NyaXB0IGZhbGxiYWNrXG4gICAgbGV0IHN1bSA9IDA7XG4gICAgY29uc3QgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBzdW0gKz0gYVtpXSAqIGJbaV07XG4gICAgfVxuICAgIHJldHVybiBzdW07XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZSBjb3NpbmUgc2ltaWxhcml0eSBiZXR3ZWVuIHR3byB2ZWN0b3JzXG4gICAqL1xuICBjb3NpbmVTaW1pbGFyaXR5KGE6IG51bWJlcltdLCBiOiBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMubmF0aXZlKSB7XG4gICAgICByZXR1cm4gdGhpcy5uYXRpdmUuY29zaW5lU2ltaWxhcml0eShhLCBiKTtcbiAgICB9XG5cbiAgICAvLyBKYXZhU2NyaXB0IGZhbGxiYWNrXG4gICAgbGV0IGRvdCA9IDA7XG4gICAgbGV0IG5vcm1BID0gMDtcbiAgICBsZXQgbm9ybUIgPSAwO1xuXG4gICAgY29uc3QgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkb3QgKz0gYVtpXSAqIGJbaV07XG4gICAgICBub3JtQSArPSBhW2ldICogYVtpXTtcbiAgICAgIG5vcm1CICs9IGJbaV0gKiBiW2ldO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbm9tID0gTWF0aC5zcXJ0KG5vcm1BKSAqIE1hdGguc3FydChub3JtQik7XG4gICAgcmV0dXJuIGRlbm9tID4gMCA/IGRvdCAvIGRlbm9tIDogMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIEwyIChFdWNsaWRlYW4pIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlY3RvcnNcbiAgICovXG4gIGwyRGlzdGFuY2UoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5uYXRpdmUpIHtcbiAgICAgIHJldHVybiB0aGlzLm5hdGl2ZS5sMkRpc3RhbmNlKGEsIGIpO1xuICAgIH1cblxuICAgIC8vIEphdmFTY3JpcHQgZmFsbGJhY2tcbiAgICBsZXQgc3VtID0gMDtcbiAgICBjb25zdCBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpZmYgPSBhW2ldIC0gYltpXTtcbiAgICAgIHN1bSArPSBkaWZmICogZGlmZjtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGguc3FydChzdW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hdHJpeC12ZWN0b3IgbXVsdGlwbGljYXRpb25cbiAgICovXG4gIG1hdHZlYyhtYXRyaXg6IG51bWJlcltdW10sIHZlY3RvcjogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgaWYgKHRoaXMubmF0aXZlKSB7XG4gICAgICByZXR1cm4gdGhpcy5uYXRpdmUubWF0dmVjKG1hdHJpeCwgdmVjdG9yKTtcbiAgICB9XG5cbiAgICAvLyBKYXZhU2NyaXB0IGZhbGxiYWNrXG4gICAgcmV0dXJuIG1hdHJpeC5tYXAocm93ID0+IHRoaXMuZG90UHJvZHVjdChyb3csIHZlY3RvcikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvZnRtYXggYWN0aXZhdGlvbiBmdW5jdGlvblxuICAgKi9cbiAgc29mdG1heChpbnB1dDogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgaWYgKHRoaXMubmF0aXZlKSB7XG4gICAgICByZXR1cm4gdGhpcy5uYXRpdmUuc29mdG1heChpbnB1dCk7XG4gICAgfVxuXG4gICAgLy8gSmF2YVNjcmlwdCBmYWxsYmFja1xuICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KC4uLmlucHV0KTtcbiAgICBjb25zdCBleHBzID0gaW5wdXQubWFwKHggPT4gTWF0aC5leHAoeCAtIG1heCkpO1xuICAgIGNvbnN0IHN1bSA9IGV4cHMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG4gICAgcmV0dXJuIGV4cHMubWFwKHggPT4geCAvIHN1bSk7XG4gIH1cblxuICAvKipcbiAgICogRWxlbWVudC13aXNlIGFkZGl0aW9uXG4gICAqL1xuICBhZGQoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IGxlbiA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aCk7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5KGxlbik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgcmVzdWx0W2ldID0gYVtpXSArIGJbaV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogRWxlbWVudC13aXNlIG11bHRpcGxpY2F0aW9uXG4gICAqL1xuICBtdWwoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IGxlbiA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aCk7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5KGxlbik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgcmVzdWx0W2ldID0gYVtpXSAqIGJbaV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogU2NhbGUgdmVjdG9yIGJ5IHNjYWxhclxuICAgKi9cbiAgc2NhbGUoYTogbnVtYmVyW10sIHNjYWxhcjogbnVtYmVyKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBhLm1hcCh4ID0+IHggKiBzY2FsYXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZSB2ZWN0b3IgdG8gdW5pdCBsZW5ndGhcbiAgICovXG4gIG5vcm1hbGl6ZShhOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBub3JtID0gTWF0aC5zcXJ0KGEucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHggKiB4LCAwKSk7XG4gICAgcmV0dXJuIG5vcm0gPiAwID8gYS5tYXAoeCA9PiB4IC8gbm9ybSkgOiBhO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlTFUgYWN0aXZhdGlvblxuICAgKi9cbiAgcmVsdShpbnB1dDogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGlucHV0Lm1hcCh4ID0+IE1hdGgubWF4KDAsIHgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHRUxVIGFjdGl2YXRpb24gKGFwcHJveGltYXRlKVxuICAgKi9cbiAgZ2VsdShpbnB1dDogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGlucHV0Lm1hcCh4ID0+IHtcbiAgICAgIHJldHVybiAwLjUgKiB4ICogKDEgKyBNYXRoLnRhbmgoTWF0aC5zcXJ0KDIgLyBNYXRoLlBJKSAqICh4ICsgMC4wNDQ3MTUgKiB4ICogeCAqIHgpKSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU2lnbW9pZCBhY3RpdmF0aW9uXG4gICAqL1xuICBzaWdtb2lkKGlucHV0OiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gaW5wdXQubWFwKHggPT4gMSAvICgxICsgTWF0aC5leHAoLXgpKSk7XG4gIH1cblxuICAvKipcbiAgICogTGF5ZXIgbm9ybWFsaXphdGlvblxuICAgKi9cbiAgbGF5ZXJOb3JtKGlucHV0OiBudW1iZXJbXSwgZXBzID0gMWUtNSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBtZWFuID0gaW5wdXQucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgLyBpbnB1dC5sZW5ndGg7XG4gICAgY29uc3QgdmFyaWFuY2UgPSBpbnB1dC5yZWR1Y2UoKHN1bSwgeCkgPT4gc3VtICsgKHggLSBtZWFuKSAqKiAyLCAwKSAvIGlucHV0Lmxlbmd0aDtcbiAgICBjb25zdCBzdGQgPSBNYXRoLnNxcnQodmFyaWFuY2UgKyBlcHMpO1xuICAgIHJldHVybiBpbnB1dC5tYXAoeCA9PiAoeCAtIG1lYW4pIC8gc3RkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBuYXRpdmUgU0lNRCBpcyBhdmFpbGFibGVcbiAgICovXG4gIGlzTmF0aXZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5hdGl2ZSAhPT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXZhaWxhYmxlIFNJTUQgY2FwYWJpbGl0aWVzXG4gICAqL1xuICBjYXBhYmlsaXRpZXMoKTogc3RyaW5nW10ge1xuICAgIGlmICghdGhpcy5uYXRpdmUpIHtcbiAgICAgIHJldHVybiBbJ0phdmFTY3JpcHQgKHNjYWxhciknXTtcbiAgICB9XG5cbiAgICAvLyBUaGUgbmF0aXZlIG1vZHVsZSB3aWxsIHJlcG9ydCBhY3R1YWwgY2FwYWJpbGl0aWVzXG4gICAgY29uc3QgbW9kID0gZ2V0TmF0aXZlTW9kdWxlKCk7XG4gICAgaWYgKG1vZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZW5naW5lID0gbmV3IG1vZC5SdXZMTE1FbmdpbmUoKTtcbiAgICAgICAgcmV0dXJuIGVuZ2luZS5zaW1kQ2FwYWJpbGl0aWVzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFsnTmF0aXZlICh1bmtub3duKSddO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbJ0phdmFTY3JpcHQgKHNjYWxhciknXTtcbiAgfVxufVxuIl19