swift-skills-mcp 0.0.1

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 (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/build/cli/auth.d.ts +3 -0
  4. package/build/cli/auth.d.ts.map +1 -0
  5. package/build/cli/auth.js +44 -0
  6. package/build/cli/auth.js.map +1 -0
  7. package/build/cli/setup.d.ts +2 -0
  8. package/build/cli/setup.d.ts.map +1 -0
  9. package/build/cli/setup.js +150 -0
  10. package/build/cli/setup.js.map +1 -0
  11. package/build/cli/source-manager.d.ts +3 -0
  12. package/build/cli/source-manager.d.ts.map +1 -0
  13. package/build/cli/source-manager.js +117 -0
  14. package/build/cli/source-manager.js.map +1 -0
  15. package/build/config/creators.d.ts +11 -0
  16. package/build/config/creators.d.ts.map +1 -0
  17. package/build/config/creators.js +32 -0
  18. package/build/config/creators.js.map +1 -0
  19. package/build/config/sources.d.ts +91 -0
  20. package/build/config/sources.d.ts.map +1 -0
  21. package/build/config/sources.js +231 -0
  22. package/build/config/sources.js.map +1 -0
  23. package/build/config/sources.test.d.ts +2 -0
  24. package/build/config/sources.test.d.ts.map +1 -0
  25. package/build/config/sources.test.js +199 -0
  26. package/build/config/sources.test.js.map +1 -0
  27. package/build/config/swift-keywords.d.ts +29 -0
  28. package/build/config/swift-keywords.d.ts.map +1 -0
  29. package/build/config/swift-keywords.js +77 -0
  30. package/build/config/swift-keywords.js.map +1 -0
  31. package/build/index.d.ts +3 -0
  32. package/build/index.d.ts.map +1 -0
  33. package/build/index.js +181 -0
  34. package/build/index.js.map +1 -0
  35. package/build/integration/cache-behavior.test.d.ts +2 -0
  36. package/build/integration/cache-behavior.test.d.ts.map +1 -0
  37. package/build/integration/cache-behavior.test.js +521 -0
  38. package/build/integration/cache-behavior.test.js.map +1 -0
  39. package/build/integration/mcp-client.test.d.ts +2 -0
  40. package/build/integration/mcp-client.test.d.ts.map +1 -0
  41. package/build/integration/mcp-client.test.js +82 -0
  42. package/build/integration/mcp-client.test.js.map +1 -0
  43. package/build/integration/response-quality.test.d.ts +2 -0
  44. package/build/integration/response-quality.test.d.ts.map +1 -0
  45. package/build/integration/response-quality.test.js +230 -0
  46. package/build/integration/response-quality.test.js.map +1 -0
  47. package/build/integration/test-client.d.ts +25 -0
  48. package/build/integration/test-client.d.ts.map +1 -0
  49. package/build/integration/test-client.js +93 -0
  50. package/build/integration/test-client.js.map +1 -0
  51. package/build/sources/free/nilcoalescing.d.ts +8 -0
  52. package/build/sources/free/nilcoalescing.d.ts.map +1 -0
  53. package/build/sources/free/nilcoalescing.js +26 -0
  54. package/build/sources/free/nilcoalescing.js.map +1 -0
  55. package/build/sources/free/nilcoalescing.test.d.ts +2 -0
  56. package/build/sources/free/nilcoalescing.test.d.ts.map +1 -0
  57. package/build/sources/free/nilcoalescing.test.js +63 -0
  58. package/build/sources/free/nilcoalescing.test.js.map +1 -0
  59. package/build/sources/free/pointfree.d.ts +15 -0
  60. package/build/sources/free/pointfree.d.ts.map +1 -0
  61. package/build/sources/free/pointfree.js +175 -0
  62. package/build/sources/free/pointfree.js.map +1 -0
  63. package/build/sources/free/pointfree.test.d.ts +2 -0
  64. package/build/sources/free/pointfree.test.d.ts.map +1 -0
  65. package/build/sources/free/pointfree.test.js +86 -0
  66. package/build/sources/free/pointfree.test.js.map +1 -0
  67. package/build/sources/free/rssPatternSource.d.ts +42 -0
  68. package/build/sources/free/rssPatternSource.d.ts.map +1 -0
  69. package/build/sources/free/rssPatternSource.js +109 -0
  70. package/build/sources/free/rssPatternSource.js.map +1 -0
  71. package/build/sources/free/rssPatternSource.test.d.ts +2 -0
  72. package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
  73. package/build/sources/free/rssPatternSource.test.js +89 -0
  74. package/build/sources/free/rssPatternSource.test.js.map +1 -0
  75. package/build/sources/free/sundell.d.ts +8 -0
  76. package/build/sources/free/sundell.d.ts.map +1 -0
  77. package/build/sources/free/sundell.js +17 -0
  78. package/build/sources/free/sundell.js.map +1 -0
  79. package/build/sources/free/sundell.test.d.ts +2 -0
  80. package/build/sources/free/sundell.test.d.ts.map +1 -0
  81. package/build/sources/free/sundell.test.js +63 -0
  82. package/build/sources/free/sundell.test.js.map +1 -0
  83. package/build/sources/free/vanderlee.d.ts +8 -0
  84. package/build/sources/free/vanderlee.d.ts.map +1 -0
  85. package/build/sources/free/vanderlee.js +63 -0
  86. package/build/sources/free/vanderlee.js.map +1 -0
  87. package/build/sources/free/vanderlee.test.d.ts +2 -0
  88. package/build/sources/free/vanderlee.test.d.ts.map +1 -0
  89. package/build/sources/free/vanderlee.test.js +77 -0
  90. package/build/sources/free/vanderlee.test.js.map +1 -0
  91. package/build/sources/premium/patreon-dl.d.ts +45 -0
  92. package/build/sources/premium/patreon-dl.d.ts.map +1 -0
  93. package/build/sources/premium/patreon-dl.js +189 -0
  94. package/build/sources/premium/patreon-dl.js.map +1 -0
  95. package/build/sources/premium/patreon-fetch.d.ts +3 -0
  96. package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
  97. package/build/sources/premium/patreon-fetch.js +18 -0
  98. package/build/sources/premium/patreon-fetch.js.map +1 -0
  99. package/build/sources/premium/patreon-oauth.d.ts +24 -0
  100. package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
  101. package/build/sources/premium/patreon-oauth.js +208 -0
  102. package/build/sources/premium/patreon-oauth.js.map +1 -0
  103. package/build/sources/premium/patreon-zip.d.ts +17 -0
  104. package/build/sources/premium/patreon-zip.d.ts.map +1 -0
  105. package/build/sources/premium/patreon-zip.js +127 -0
  106. package/build/sources/premium/patreon-zip.js.map +1 -0
  107. package/build/sources/premium/patreon.d.ts +48 -0
  108. package/build/sources/premium/patreon.d.ts.map +1 -0
  109. package/build/sources/premium/patreon.js +221 -0
  110. package/build/sources/premium/patreon.js.map +1 -0
  111. package/build/sources/premium/youtube.d.ts +14 -0
  112. package/build/sources/premium/youtube.d.ts.map +1 -0
  113. package/build/sources/premium/youtube.js +92 -0
  114. package/build/sources/premium/youtube.js.map +1 -0
  115. package/build/tools/extract-cookie.d.ts +2 -0
  116. package/build/tools/extract-cookie.d.ts.map +1 -0
  117. package/build/tools/extract-cookie.js +40 -0
  118. package/build/tools/extract-cookie.js.map +1 -0
  119. package/build/tools/handlers/enableSource.d.ts +3 -0
  120. package/build/tools/handlers/enableSource.d.ts.map +1 -0
  121. package/build/tools/handlers/enableSource.js +25 -0
  122. package/build/tools/handlers/enableSource.js.map +1 -0
  123. package/build/tools/handlers/getPatreonPatterns.d.ts +3 -0
  124. package/build/tools/handlers/getPatreonPatterns.d.ts.map +1 -0
  125. package/build/tools/handlers/getPatreonPatterns.js +43 -0
  126. package/build/tools/handlers/getPatreonPatterns.js.map +1 -0
  127. package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
  128. package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
  129. package/build/tools/handlers/getSwiftPattern.js +72 -0
  130. package/build/tools/handlers/getSwiftPattern.js.map +1 -0
  131. package/build/tools/handlers/handlers.test.d.ts +2 -0
  132. package/build/tools/handlers/handlers.test.d.ts.map +1 -0
  133. package/build/tools/handlers/handlers.test.js +359 -0
  134. package/build/tools/handlers/handlers.test.js.map +1 -0
  135. package/build/tools/handlers/listContentSources.d.ts +3 -0
  136. package/build/tools/handlers/listContentSources.d.ts.map +1 -0
  137. package/build/tools/handlers/listContentSources.js +34 -0
  138. package/build/tools/handlers/listContentSources.js.map +1 -0
  139. package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
  140. package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
  141. package/build/tools/handlers/searchSwiftContent.js +121 -0
  142. package/build/tools/handlers/searchSwiftContent.js.map +1 -0
  143. package/build/tools/handlers/setupPatreon.d.ts +3 -0
  144. package/build/tools/handlers/setupPatreon.d.ts.map +1 -0
  145. package/build/tools/handlers/setupPatreon.js +40 -0
  146. package/build/tools/handlers/setupPatreon.js.map +1 -0
  147. package/build/tools/index.d.ts +3 -0
  148. package/build/tools/index.d.ts.map +1 -0
  149. package/build/tools/index.js +18 -0
  150. package/build/tools/index.js.map +1 -0
  151. package/build/tools/registry.d.ts +14 -0
  152. package/build/tools/registry.d.ts.map +1 -0
  153. package/build/tools/registry.js +21 -0
  154. package/build/tools/registry.js.map +1 -0
  155. package/build/tools/registry.test.d.ts +2 -0
  156. package/build/tools/registry.test.d.ts.map +1 -0
  157. package/build/tools/registry.test.js +54 -0
  158. package/build/tools/registry.test.js.map +1 -0
  159. package/build/tools/types.d.ts +67 -0
  160. package/build/tools/types.d.ts.map +1 -0
  161. package/build/tools/types.js +3 -0
  162. package/build/tools/types.js.map +1 -0
  163. package/build/utils/cache.d.ts +20 -0
  164. package/build/utils/cache.d.ts.map +1 -0
  165. package/build/utils/cache.js +186 -0
  166. package/build/utils/cache.js.map +1 -0
  167. package/build/utils/concurrency.d.ts +13 -0
  168. package/build/utils/concurrency.d.ts.map +1 -0
  169. package/build/utils/concurrency.js +33 -0
  170. package/build/utils/concurrency.js.map +1 -0
  171. package/build/utils/errors.d.ts +19 -0
  172. package/build/utils/errors.d.ts.map +1 -0
  173. package/build/utils/errors.js +35 -0
  174. package/build/utils/errors.js.map +1 -0
  175. package/build/utils/fetch.d.ts +6 -0
  176. package/build/utils/fetch.d.ts.map +1 -0
  177. package/build/utils/fetch.js +6 -0
  178. package/build/utils/fetch.js.map +1 -0
  179. package/build/utils/http.d.ts +21 -0
  180. package/build/utils/http.d.ts.map +1 -0
  181. package/build/utils/http.js +53 -0
  182. package/build/utils/http.js.map +1 -0
  183. package/build/utils/intent-cache.d.ts +94 -0
  184. package/build/utils/intent-cache.d.ts.map +1 -0
  185. package/build/utils/intent-cache.js +164 -0
  186. package/build/utils/intent-cache.js.map +1 -0
  187. package/build/utils/intent-cache.test.d.ts +2 -0
  188. package/build/utils/intent-cache.test.d.ts.map +1 -0
  189. package/build/utils/intent-cache.test.js +290 -0
  190. package/build/utils/intent-cache.test.js.map +1 -0
  191. package/build/utils/logger.d.ts +4 -0
  192. package/build/utils/logger.d.ts.map +1 -0
  193. package/build/utils/logger.js +9 -0
  194. package/build/utils/logger.js.map +1 -0
  195. package/build/utils/paths.d.ts +27 -0
  196. package/build/utils/paths.d.ts.map +1 -0
  197. package/build/utils/paths.js +43 -0
  198. package/build/utils/paths.js.map +1 -0
  199. package/build/utils/pattern-formatter.d.ts +40 -0
  200. package/build/utils/pattern-formatter.d.ts.map +1 -0
  201. package/build/utils/pattern-formatter.js +124 -0
  202. package/build/utils/pattern-formatter.js.map +1 -0
  203. package/build/utils/response-helpers.d.ts +17 -0
  204. package/build/utils/response-helpers.d.ts.map +1 -0
  205. package/build/utils/response-helpers.js +34 -0
  206. package/build/utils/response-helpers.js.map +1 -0
  207. package/build/utils/search-terms.d.ts +17 -0
  208. package/build/utils/search-terms.d.ts.map +1 -0
  209. package/build/utils/search-terms.js +71 -0
  210. package/build/utils/search-terms.js.map +1 -0
  211. package/build/utils/search-terms.test.d.ts +2 -0
  212. package/build/utils/search-terms.test.d.ts.map +1 -0
  213. package/build/utils/search-terms.test.js +107 -0
  214. package/build/utils/search-terms.test.js.map +1 -0
  215. package/build/utils/search.d.ts +48 -0
  216. package/build/utils/search.d.ts.map +1 -0
  217. package/build/utils/search.js +158 -0
  218. package/build/utils/search.js.map +1 -0
  219. package/build/utils/search.test.d.ts +2 -0
  220. package/build/utils/search.test.d.ts.map +1 -0
  221. package/build/utils/search.test.js +199 -0
  222. package/build/utils/search.test.js.map +1 -0
  223. package/build/utils/semantic-recall.d.ts +38 -0
  224. package/build/utils/semantic-recall.d.ts.map +1 -0
  225. package/build/utils/semantic-recall.js +134 -0
  226. package/build/utils/semantic-recall.js.map +1 -0
  227. package/build/utils/semantic-recall.test.d.ts +2 -0
  228. package/build/utils/semantic-recall.test.d.ts.map +1 -0
  229. package/build/utils/semantic-recall.test.js +326 -0
  230. package/build/utils/semantic-recall.test.js.map +1 -0
  231. package/build/utils/source-registry.d.ts +45 -0
  232. package/build/utils/source-registry.d.ts.map +1 -0
  233. package/build/utils/source-registry.js +113 -0
  234. package/build/utils/source-registry.js.map +1 -0
  235. package/build/utils/source-registry.test.d.ts +2 -0
  236. package/build/utils/source-registry.test.d.ts.map +1 -0
  237. package/build/utils/source-registry.test.js +206 -0
  238. package/build/utils/source-registry.test.js.map +1 -0
  239. package/build/utils/swift-analysis.d.ts +61 -0
  240. package/build/utils/swift-analysis.d.ts.map +1 -0
  241. package/build/utils/swift-analysis.js +339 -0
  242. package/build/utils/swift-analysis.js.map +1 -0
  243. package/build/utils/swift-analysis.test.d.ts +2 -0
  244. package/build/utils/swift-analysis.test.d.ts.map +1 -0
  245. package/build/utils/swift-analysis.test.js +473 -0
  246. package/build/utils/swift-analysis.test.js.map +1 -0
  247. package/package.json +85 -0
@@ -0,0 +1,9 @@
1
+ import pino from 'pino';
2
+ const logger = pino.default({
3
+ level: process.env.LOG_LEVEL ?? 'info',
4
+ base: {
5
+ service: 'swift-patterns-mcp',
6
+ },
7
+ });
8
+ export default logger;
9
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,IAAI,EAAE;QACJ,OAAO,EAAE,oBAAoB;KAC9B;CACF,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Get the base directory for swift-patterns-mcp configuration and data
3
+ * @returns The absolute path to ~/.swift-patterns-mcp directory
4
+ */
5
+ export declare function getSwiftMcpDir(): string;
6
+ /**
7
+ * Get the configuration file path
8
+ * @returns The absolute path to the config.json file
9
+ */
10
+ export declare function getConfigPath(): string;
11
+ /**
12
+ * Get the cache directory path
13
+ * @param namespace Optional namespace for cache isolation
14
+ * @returns The absolute path to the cache directory
15
+ */
16
+ export declare function getCacheDir(namespace?: string): string;
17
+ /**
18
+ * Get the Patreon content download directory
19
+ * @returns The absolute path to the patreon-content directory
20
+ */
21
+ export declare function getPatreonContentDir(): string;
22
+ /**
23
+ * Get the Patreon creators configuration path
24
+ * @returns The absolute path to the patreon-creators.json file
25
+ */
26
+ export declare function getPatreonCreatorsPath(): string;
27
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
@@ -0,0 +1,43 @@
1
+ // src/utils/paths.ts
2
+ import path from 'path';
3
+ /**
4
+ * Get the base directory for swift-patterns-mcp configuration and data
5
+ * @returns The absolute path to ~/.swift-patterns-mcp directory
6
+ */
7
+ export function getSwiftMcpDir() {
8
+ const home = process.env.HOME || process.env.USERPROFILE || '';
9
+ return path.join(home, '.swift-patterns-mcp');
10
+ }
11
+ /**
12
+ * Get the configuration file path
13
+ * @returns The absolute path to the config.json file
14
+ */
15
+ export function getConfigPath() {
16
+ return path.join(getSwiftMcpDir(), 'config.json');
17
+ }
18
+ /**
19
+ * Get the cache directory path
20
+ * @param namespace Optional namespace for cache isolation
21
+ * @returns The absolute path to the cache directory
22
+ */
23
+ export function getCacheDir(namespace) {
24
+ if (namespace) {
25
+ return path.join(getSwiftMcpDir(), 'cache', namespace);
26
+ }
27
+ return path.join(getSwiftMcpDir(), 'cache');
28
+ }
29
+ /**
30
+ * Get the Patreon content download directory
31
+ * @returns The absolute path to the patreon-content directory
32
+ */
33
+ export function getPatreonContentDir() {
34
+ return path.join(getSwiftMcpDir(), 'patreon-content');
35
+ }
36
+ /**
37
+ * Get the Patreon creators configuration path
38
+ * @returns The absolute path to the patreon-creators.json file
39
+ */
40
+ export function getPatreonCreatorsPath() {
41
+ return path.join(getSwiftMcpDir(), 'patreon-creators.json');
42
+ }
43
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,qBAAqB;AAErB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,SAAkB;IAC5C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,uBAAuB,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Shared utilities for formatting patterns in responses
3
+ */
4
+ import type { BasePattern } from '../sources/free/rssPatternSource.js';
5
+ export interface FormatOptions {
6
+ maxResults?: number;
7
+ includeQuality?: boolean;
8
+ includeTopics?: boolean;
9
+ includeCode?: boolean;
10
+ excerptLength?: number;
11
+ includeSnippets?: boolean;
12
+ includeTechniques?: boolean;
13
+ includeComplexity?: boolean;
14
+ maxSnippets?: number;
15
+ }
16
+ /**
17
+ * Common format options used by tool handlers
18
+ */
19
+ export declare const COMMON_FORMAT_OPTIONS: FormatOptions;
20
+ /**
21
+ * Detect if the user wants to see code examples based on args or query content
22
+ */
23
+ export declare function detectCodeIntent(args: any, query: string): boolean;
24
+ /**
25
+ * Format a single pattern as markdown
26
+ */
27
+ export declare function formatPattern(pattern: BasePattern, options?: FormatOptions): string;
28
+ /**
29
+ * Format multiple patterns as a markdown document
30
+ */
31
+ export declare function formatPatterns(patterns: BasePattern[], title: string, options?: FormatOptions): string;
32
+ /**
33
+ * Format patterns for topic-based queries (with quality and topics)
34
+ */
35
+ export declare function formatTopicPatterns(patterns: BasePattern[], topic: string, options?: FormatOptions): string;
36
+ /**
37
+ * Format patterns for general search queries
38
+ */
39
+ export declare function formatSearchPatterns(patterns: BasePattern[], query: string, options?: FormatOptions): string;
40
+ //# sourceMappingURL=pattern-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/pattern-formatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AASvE,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAcD;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAMnC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAoDvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAQR"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Shared utilities for formatting patterns in responses
3
+ */
4
+ import { extractCodeSnippets, extractTechniques, detectComplexity, truncateAtSentence, extractDescriptiveTitle } from './swift-analysis.js';
5
+ const DEFAULT_OPTIONS = {
6
+ maxResults: 10,
7
+ includeQuality: false,
8
+ includeTopics: false,
9
+ includeCode: true,
10
+ excerptLength: 200,
11
+ includeSnippets: true,
12
+ includeTechniques: true,
13
+ includeComplexity: true,
14
+ maxSnippets: 1,
15
+ };
16
+ /**
17
+ * Common format options used by tool handlers
18
+ */
19
+ export const COMMON_FORMAT_OPTIONS = {
20
+ maxResults: 4,
21
+ includeSnippets: false,
22
+ includeTechniques: false,
23
+ includeComplexity: false,
24
+ excerptLength: 200,
25
+ };
26
+ /**
27
+ * Detect if the user wants to see code examples based on args or query content
28
+ */
29
+ export function detectCodeIntent(args, query) {
30
+ return Boolean(args?.includeCode) || /code|example|snippet/i.test(query);
31
+ }
32
+ /**
33
+ * Format a single pattern as markdown
34
+ */
35
+ export function formatPattern(pattern, options = {}) {
36
+ const opts = { ...DEFAULT_OPTIONS, ...options };
37
+ const sourceId = pattern.id.split('-')[0];
38
+ // Extract descriptive title from content
39
+ const title = extractDescriptiveTitle(pattern.content, pattern.title);
40
+ let formatted = `## ${title}\n`;
41
+ formatted += `**Source**: ${sourceId}\n`;
42
+ if (opts.includeQuality) {
43
+ formatted += `**Quality**: ${pattern.relevanceScore}/100\n`;
44
+ }
45
+ if (opts.includeComplexity) {
46
+ const complexity = detectComplexity(pattern.content, pattern.topics);
47
+ formatted += `**Complexity**: ${complexity}\n`;
48
+ }
49
+ if (opts.includeTopics && pattern.topics.length > 0) {
50
+ formatted += `**Topics**: ${pattern.topics.join(', ')}\n`;
51
+ }
52
+ if (opts.includeTechniques) {
53
+ const techniques = extractTechniques(pattern.content);
54
+ if (techniques.length > 0) {
55
+ formatted += `**Techniques**: ${techniques.join(', ')}\n`;
56
+ }
57
+ }
58
+ // Show code snippets if available and requested
59
+ if (opts.includeSnippets && pattern.hasCode) {
60
+ const snippets = extractCodeSnippets(pattern.content, opts.maxSnippets);
61
+ if (snippets.length > 0) {
62
+ formatted += `\n**Code Example**:\n`;
63
+ snippets.forEach(snippet => {
64
+ formatted += '```swift\n' + snippet + '\n```\n';
65
+ });
66
+ }
67
+ else if (opts.includeCode) {
68
+ // Fallback to checkmark if no snippets extracted
69
+ formatted += `**Code**: ✅\n`;
70
+ }
71
+ }
72
+ else if (opts.includeCode && pattern.hasCode) {
73
+ formatted += `**Code**: ✅\n`;
74
+ }
75
+ // Use smart truncation at sentence boundaries
76
+ const excerpt = truncateAtSentence(pattern.excerpt, opts.excerptLength);
77
+ formatted += `\n${excerpt}...\n\n`;
78
+ formatted += `[Read more](${pattern.url})`;
79
+ return formatted;
80
+ }
81
+ /**
82
+ * Format multiple patterns as a markdown document
83
+ */
84
+ export function formatPatterns(patterns, title, options = {}) {
85
+ const opts = { ...DEFAULT_OPTIONS, ...options };
86
+ const limited = patterns.slice(0, opts.maxResults);
87
+ const formatted = limited.map(p => formatPattern(p, opts)).join('\n\n---\n\n');
88
+ const count = patterns.length;
89
+ const shown = limited.length;
90
+ let result = `# ${title}\n\n`;
91
+ if (count > 0) {
92
+ result += `Found ${count} result${count === 1 ? '' : 's'}:\n\n`;
93
+ }
94
+ result += formatted;
95
+ if (count > shown) {
96
+ result += `\n\n*Showing top ${shown} of ${count} results*`;
97
+ }
98
+ return result;
99
+ }
100
+ /**
101
+ * Format patterns for topic-based queries (with quality and topics)
102
+ */
103
+ export function formatTopicPatterns(patterns, topic, options = {}) {
104
+ return formatPatterns(patterns, `Swift Patterns: ${topic}`, {
105
+ ...options,
106
+ includeQuality: true,
107
+ includeTopics: true,
108
+ includeCode: true,
109
+ excerptLength: 300,
110
+ });
111
+ }
112
+ /**
113
+ * Format patterns for general search queries
114
+ */
115
+ export function formatSearchPatterns(patterns, query, options = {}) {
116
+ return formatPatterns(patterns, `Search Results: "${query}"`, {
117
+ ...options,
118
+ includeQuality: false,
119
+ includeTopics: false,
120
+ includeCode: true,
121
+ excerptLength: 200,
122
+ });
123
+ }
124
+ //# sourceMappingURL=pattern-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-formatter.js","sourceRoot":"","sources":["../../src/utils/pattern-formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Response formatting helpers for consistent MCP tool responses
3
+ */
4
+ import type { ToolResponse } from '../tools/types.js';
5
+ /**
6
+ * Create a standard text response
7
+ */
8
+ export declare function createTextResponse(text: string): ToolResponse;
9
+ /**
10
+ * Create an error response
11
+ */
12
+ export declare function createErrorResponse(message: string): ToolResponse;
13
+ /**
14
+ * Create a response from an error (uses error utilities)
15
+ */
16
+ export declare function createErrorResponseFromError(error: unknown): ToolResponse;
17
+ //# sourceMappingURL=response-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/response-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAO7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAQjE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAEzE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Response formatting helpers for consistent MCP tool responses
3
+ */
4
+ import { toErrorMessage } from './errors.js';
5
+ /**
6
+ * Create a standard text response
7
+ */
8
+ export function createTextResponse(text) {
9
+ return {
10
+ content: [{
11
+ type: "text",
12
+ text,
13
+ }],
14
+ };
15
+ }
16
+ /**
17
+ * Create an error response
18
+ */
19
+ export function createErrorResponse(message) {
20
+ return {
21
+ content: [{
22
+ type: "text",
23
+ text: `Error: ${message}`,
24
+ }],
25
+ isError: true,
26
+ };
27
+ }
28
+ /**
29
+ * Create a response from an error (uses error utilities)
30
+ */
31
+ export function createErrorResponseFromError(error) {
32
+ return createErrorResponse(toErrorMessage(error));
33
+ }
34
+ //# sourceMappingURL=response-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-helpers.js","sourceRoot":"","sources":["../../src/utils/response-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI;aACL,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,UAAU,OAAO,EAAE;aAC1B,CAAC;QACF,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAAc;IACzD,OAAO,mBAAmB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare const STOPWORDS: Set<string>;
2
+ export declare const PRESERVE_TERMS: Set<string>;
3
+ /**
4
+ * Shared token normalization logic used by both search and intent caching.
5
+ *
6
+ * - Lowercase
7
+ * - Strip non-word characters (keeping hyphens)
8
+ * - Split on whitespace
9
+ * - Split hyphenated terms
10
+ * - Filter stopwords while preserving Swift-specific terms
11
+ *
12
+ * @param text - Text to normalize
13
+ * @param applyTransform - Optional transform function (e.g., stemmer) applied to non-preserved terms
14
+ * @returns Array of normalized tokens
15
+ */
16
+ export declare function normalizeTokens(text: string, applyTransform?: (token: string) => string): string[];
17
+ //# sourceMappingURL=search-terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-terms.d.ts","sourceRoot":"","sources":["../../src/utils/search-terms.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,aAUpB,CAAC;AAIH,eAAO,MAAM,cAAc,aAOzB,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACzC,MAAM,EAAE,CAmCV"}
@@ -0,0 +1,71 @@
1
+ // src/utils/search-terms.ts
2
+ // Shared search-related term lists
3
+ // Common stopwords to filter out
4
+ export const STOPWORDS = new Set([
5
+ 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
6
+ 'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been',
7
+ 'be', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
8
+ 'should', 'may', 'might', 'must', 'shall', 'can', 'this', 'that', 'these',
9
+ 'those', 'it', 'its', 'they', 'them', 'their', 'we', 'our', 'you', 'your',
10
+ 'i', 'my', 'me', 'he', 'she', 'him', 'her', 'his', 'who', 'what', 'which',
11
+ 'when', 'where', 'why', 'how', 'all', 'each', 'every', 'both', 'few',
12
+ 'more', 'most', 'other', 'some', 'such', 'no', 'not', 'only', 'same',
13
+ 'so', 'than', 'too', 'very', 'just', 'also', 'now', 'here', 'there'
14
+ ]);
15
+ // Swift-specific terms that shouldn't be stemmed (preserve technical accuracy)
16
+ // NOTE: If you add hyphenated terms here (e.g. "objective-c"), the tokenizer will now respect them.
17
+ export const PRESERVE_TERMS = new Set([
18
+ 'swift', 'swiftui', 'uikit', 'combine', 'async', 'await', 'actor',
19
+ 'struct', 'class', 'enum', 'protocol', 'extension', 'func', 'var', 'let',
20
+ 'mvvm', 'viper', 'mvc', 'tca', 'xctest', 'xcode', 'ios', 'macos',
21
+ 'watchos', 'tvos', 'ipados', 'appkit', 'foundation', 'coredata',
22
+ 'cloudkit', 'urlsession', 'codable', 'observable', 'published',
23
+ 'stateobject', 'observedobject', 'environmentobject', 'binding', 'state'
24
+ ]);
25
+ /**
26
+ * Shared token normalization logic used by both search and intent caching.
27
+ *
28
+ * - Lowercase
29
+ * - Strip non-word characters (keeping hyphens)
30
+ * - Split on whitespace
31
+ * - Split hyphenated terms
32
+ * - Filter stopwords while preserving Swift-specific terms
33
+ *
34
+ * @param text - Text to normalize
35
+ * @param applyTransform - Optional transform function (e.g., stemmer) applied to non-preserved terms
36
+ * @returns Array of normalized tokens
37
+ */
38
+ export function normalizeTokens(text, applyTransform) {
39
+ // 1. Clean text but keep hyphens temporarily
40
+ const rawTokens = text
41
+ .toLowerCase()
42
+ .replace(/[^\w\s-]/g, ' ')
43
+ .split(/\s+/)
44
+ .filter(t => t.length > 0);
45
+ const finalTokens = [];
46
+ for (const token of rawTokens) {
47
+ // 2. Check if the full token is a preserved term (e.g., "objective-c")
48
+ if (PRESERVE_TERMS.has(token)) {
49
+ finalTokens.push(token);
50
+ continue;
51
+ }
52
+ // 3. If not preserved, split on hyphens to separate words like "async-await" -> "async", "await"
53
+ const subTokens = token.split('-');
54
+ for (const sub of subTokens) {
55
+ if (sub.length <= 1 || STOPWORDS.has(sub))
56
+ continue;
57
+ // 4. Check sub-tokens against preserved terms or apply transform
58
+ if (PRESERVE_TERMS.has(sub)) {
59
+ finalTokens.push(sub);
60
+ }
61
+ else if (applyTransform) {
62
+ finalTokens.push(applyTransform(sub));
63
+ }
64
+ else {
65
+ finalTokens.push(sub);
66
+ }
67
+ }
68
+ }
69
+ return finalTokens;
70
+ }
71
+ //# sourceMappingURL=search-terms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-terms.js","sourceRoot":"","sources":["../../src/utils/search-terms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-terms.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-terms.test.d.ts","sourceRoot":"","sources":["../../src/utils/search-terms.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,107 @@
1
+ // src/utils/search-terms.test.ts
2
+ // Tests for shared normalization logic
3
+ import { describe, it, expect } from 'vitest';
4
+ import { normalizeTokens } from './search-terms.js';
5
+ describe('normalizeTokens', () => {
6
+ describe('basic normalization', () => {
7
+ it('should lowercase text', () => {
8
+ const result = normalizeTokens('SwiftUI Combine');
9
+ expect(result).toContain('swiftui');
10
+ expect(result).toContain('combine');
11
+ });
12
+ it('should filter stopwords', () => {
13
+ const result = normalizeTokens('how to use async await');
14
+ expect(result).not.toContain('how');
15
+ expect(result).not.toContain('to');
16
+ expect(result).toContain('use');
17
+ expect(result).toContain('async');
18
+ expect(result).toContain('await');
19
+ });
20
+ it('should handle hyphenated terms', () => {
21
+ const result = normalizeTokens('async-await patterns');
22
+ expect(result).toContain('async');
23
+ expect(result).toContain('await');
24
+ expect(result).toContain('patterns');
25
+ });
26
+ it('should preserve Swift-specific terms', () => {
27
+ const result = normalizeTokens('swiftui actor protocol');
28
+ expect(result).toContain('swiftui');
29
+ expect(result).toContain('actor');
30
+ expect(result).toContain('protocol');
31
+ });
32
+ it('should strip non-word characters', () => {
33
+ const result = normalizeTokens('test@email.com (example) [brackets]');
34
+ // Only valid word tokens should remain
35
+ expect(result).not.toContain('@');
36
+ expect(result).not.toContain('(');
37
+ expect(result).not.toContain(')');
38
+ });
39
+ it('should filter short tokens', () => {
40
+ const result = normalizeTokens('a b swift ui');
41
+ expect(result).not.toContain('a');
42
+ expect(result).not.toContain('b');
43
+ expect(result).toContain('swift');
44
+ });
45
+ });
46
+ describe('with transform function', () => {
47
+ it('should apply transform to non-preserved terms', () => {
48
+ const mockStemmer = (token) => token + '_stem';
49
+ const result = normalizeTokens('testing patterns', mockStemmer);
50
+ // "patterns" should be stemmed
51
+ expect(result).toContain('patterns_stem');
52
+ });
53
+ it('should not apply transform to preserved terms', () => {
54
+ const mockStemmer = (token) => token + '_stem';
55
+ const result = normalizeTokens('swiftui patterns', mockStemmer);
56
+ // "swiftui" should NOT be stemmed
57
+ expect(result).toContain('swiftui');
58
+ expect(result).not.toContain('swiftui_stem');
59
+ // "patterns" should be stemmed
60
+ expect(result).toContain('patterns_stem');
61
+ });
62
+ });
63
+ describe('edge cases', () => {
64
+ it('should handle empty string', () => {
65
+ const result = normalizeTokens('');
66
+ expect(result).toEqual([]);
67
+ });
68
+ it('should handle only stopwords', () => {
69
+ const result = normalizeTokens('the and or but');
70
+ expect(result).toEqual([]);
71
+ });
72
+ it('should handle whitespace-only', () => {
73
+ const result = normalizeTokens(' \t\n ');
74
+ expect(result).toEqual([]);
75
+ });
76
+ it('should handle mixed case preserved terms', () => {
77
+ const result = normalizeTokens('SwiftUI ASYNC Await');
78
+ expect(result).toContain('swiftui');
79
+ expect(result).toContain('async');
80
+ expect(result).toContain('await');
81
+ });
82
+ });
83
+ describe('consistency with IntentCache and search', () => {
84
+ it('should produce same tokens for query normalization (without transform)', () => {
85
+ const query = 'how to use async-await with SwiftUI';
86
+ const result = normalizeTokens(query);
87
+ // Should contain: use, async, await, swiftui (sorted elsewhere)
88
+ expect(result).toContain('use');
89
+ expect(result).toContain('async');
90
+ expect(result).toContain('await');
91
+ expect(result).toContain('swiftui');
92
+ // Should NOT contain stopwords
93
+ expect(result).not.toContain('how');
94
+ expect(result).not.toContain('to');
95
+ expect(result).not.toContain('with');
96
+ });
97
+ it('should handle technical terms consistently', () => {
98
+ const query = 'mvvm architecture objective-c';
99
+ const result = normalizeTokens(query);
100
+ expect(result).toContain('mvvm');
101
+ expect(result).toContain('architecture');
102
+ expect(result).toContain('objective'); // Split from hyphen
103
+ expect(result).not.toContain('c'); // Filtered as <= 1 char
104
+ });
105
+ });
106
+ });
107
+ //# sourceMappingURL=search-terms.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-terms.test.js","sourceRoot":"","sources":["../../src/utils/search-terms.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ export interface SearchableDocument {
2
+ id: string;
3
+ title: string;
4
+ content: string;
5
+ topics: string[];
6
+ }
7
+ export interface SearchResult<T> {
8
+ item: T;
9
+ score: number;
10
+ matches: string[];
11
+ }
12
+ export interface SearchOptions {
13
+ fuzzy?: number;
14
+ boost?: Record<string, number>;
15
+ minScore?: number;
16
+ }
17
+ export declare class SearchIndex<T extends SearchableDocument> {
18
+ private miniSearch;
19
+ private documents;
20
+ constructor(fields?: string[]);
21
+ addDocuments(docs: T[]): void;
22
+ search(query: string, options?: SearchOptions): SearchResult<T>[];
23
+ private findMatches;
24
+ }
25
+ export declare function fuzzySearch<T extends SearchableDocument>(documents: T[], query: string, options?: SearchOptions): SearchResult<T>[];
26
+ export declare function combineScores(searchScore: number, staticRelevance: number, searchWeight?: number): number;
27
+ export declare function suggestSimilar(query: string, knownTerms: string[], maxSuggestions?: number): string[];
28
+ /**
29
+ * CachedSearchIndex - Manages a SearchIndex with automatic invalidation based on document changes.
30
+ * Eliminates duplicated search caching logic across pattern sources.
31
+ */
32
+ export declare class CachedSearchIndex<T extends SearchableDocument> {
33
+ private searchIndex;
34
+ private indexedPatternsHash;
35
+ private fields;
36
+ constructor(fields?: string[]);
37
+ /**
38
+ * Search patterns with automatic index caching.
39
+ * Index is rebuilt only when patterns change (detected via hash).
40
+ */
41
+ search(patterns: T[], query: string, options?: SearchOptions): T[];
42
+ /**
43
+ * Invalidate the cached index (call after fetching new patterns)
44
+ */
45
+ invalidate(): void;
46
+ }
47
+ export default SearchIndex;
48
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/utils/search.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAYD,qBAAa,WAAW,CAAC,CAAC,SAAS,kBAAkB;IACnD,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,SAAS,CAA6B;gBAElC,MAAM,GAAE,MAAM,EAAmC;IAc7D,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI;IAmB7B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE;IAqCrE,OAAO,CAAC,WAAW;CAapB;AAGD,wBAAgB,WAAW,CAAC,CAAC,SAAS,kBAAkB,EACtD,SAAS,EAAE,CAAC,EAAE,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAAC,CAAC,CAAC,EAAE,CAInB;AAGD,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,YAAY,GAAE,MAAY,GACzB,MAAM,CASR;AAGD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,GAAE,MAAU,GACzB,MAAM,EAAE,CAeV;AAED;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,kBAAkB;IACzD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,MAAM,CAAW;gBAEb,MAAM,GAAE,MAAM,EAAmC;IAI7D;;;OAGG;IACH,MAAM,CACJ,QAAQ,EAAE,CAAC,EAAE,EACb,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,CAAC,EAAE;IA0BN;;OAEG;IACH,UAAU,IAAI,IAAI;CAInB;AAED,eAAe,WAAW,CAAC"}