euparliamentmonitor 0.8.4

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 (276) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1005 -0
  3. package/SECURITY.md +151 -0
  4. package/package.json +131 -0
  5. package/scripts/constants/committee-indicator-map.d.ts +199 -0
  6. package/scripts/constants/committee-indicator-map.d.ts.map +1 -0
  7. package/scripts/constants/committee-indicator-map.js +1224 -0
  8. package/scripts/constants/committee-indicator-map.js.map +1 -0
  9. package/scripts/constants/config.d.ts +38 -0
  10. package/scripts/constants/config.d.ts.map +1 -0
  11. package/scripts/constants/config.js +66 -0
  12. package/scripts/constants/config.js.map +1 -0
  13. package/scripts/constants/language-articles.d.ts +84 -0
  14. package/scripts/constants/language-articles.d.ts.map +1 -0
  15. package/scripts/constants/language-articles.js +6771 -0
  16. package/scripts/constants/language-articles.js.map +1 -0
  17. package/scripts/constants/language-core.d.ts +38 -0
  18. package/scripts/constants/language-core.d.ts.map +1 -0
  19. package/scripts/constants/language-core.js +90 -0
  20. package/scripts/constants/language-core.js.map +1 -0
  21. package/scripts/constants/language-ui.d.ts +82 -0
  22. package/scripts/constants/language-ui.d.ts.map +1 -0
  23. package/scripts/constants/language-ui.js +889 -0
  24. package/scripts/constants/language-ui.js.map +1 -0
  25. package/scripts/constants/languages.d.ts +14 -0
  26. package/scripts/constants/languages.d.ts.map +1 -0
  27. package/scripts/constants/languages.js +15 -0
  28. package/scripts/constants/languages.js.map +1 -0
  29. package/scripts/generators/analysis-builders.d.ts +266 -0
  30. package/scripts/generators/analysis-builders.d.ts.map +1 -0
  31. package/scripts/generators/analysis-builders.js +2903 -0
  32. package/scripts/generators/analysis-builders.js.map +1 -0
  33. package/scripts/generators/breaking-content.d.ts +45 -0
  34. package/scripts/generators/breaking-content.d.ts.map +1 -0
  35. package/scripts/generators/breaking-content.js +530 -0
  36. package/scripts/generators/breaking-content.js.map +1 -0
  37. package/scripts/generators/committee-helpers.d.ts +54 -0
  38. package/scripts/generators/committee-helpers.d.ts.map +1 -0
  39. package/scripts/generators/committee-helpers.js +154 -0
  40. package/scripts/generators/committee-helpers.js.map +1 -0
  41. package/scripts/generators/dashboard-content.d.ts +95 -0
  42. package/scripts/generators/dashboard-content.d.ts.map +1 -0
  43. package/scripts/generators/dashboard-content.js +630 -0
  44. package/scripts/generators/dashboard-content.js.map +1 -0
  45. package/scripts/generators/deep-analysis-content.d.ts +23 -0
  46. package/scripts/generators/deep-analysis-content.d.ts.map +1 -0
  47. package/scripts/generators/deep-analysis-content.js +831 -0
  48. package/scripts/generators/deep-analysis-content.js.map +1 -0
  49. package/scripts/generators/mindmap-content.d.ts +55 -0
  50. package/scripts/generators/mindmap-content.d.ts.map +1 -0
  51. package/scripts/generators/mindmap-content.js +512 -0
  52. package/scripts/generators/mindmap-content.js.map +1 -0
  53. package/scripts/generators/motions-content.d.ts +50 -0
  54. package/scripts/generators/motions-content.d.ts.map +1 -0
  55. package/scripts/generators/motions-content.js +391 -0
  56. package/scripts/generators/motions-content.js.map +1 -0
  57. package/scripts/generators/news-enhanced.d.ts +14 -0
  58. package/scripts/generators/news-enhanced.d.ts.map +1 -0
  59. package/scripts/generators/news-enhanced.js +169 -0
  60. package/scripts/generators/news-enhanced.js.map +1 -0
  61. package/scripts/generators/news-indexes.d.ts +31 -0
  62. package/scripts/generators/news-indexes.d.ts.map +1 -0
  63. package/scripts/generators/news-indexes.js +410 -0
  64. package/scripts/generators/news-indexes.js.map +1 -0
  65. package/scripts/generators/pipeline/fetch-stage.d.ts +352 -0
  66. package/scripts/generators/pipeline/fetch-stage.d.ts.map +1 -0
  67. package/scripts/generators/pipeline/fetch-stage.js +1522 -0
  68. package/scripts/generators/pipeline/fetch-stage.js.map +1 -0
  69. package/scripts/generators/pipeline/generate-stage.d.ts +43 -0
  70. package/scripts/generators/pipeline/generate-stage.d.ts.map +1 -0
  71. package/scripts/generators/pipeline/generate-stage.js +204 -0
  72. package/scripts/generators/pipeline/generate-stage.js.map +1 -0
  73. package/scripts/generators/pipeline/output-stage.d.ts +48 -0
  74. package/scripts/generators/pipeline/output-stage.d.ts.map +1 -0
  75. package/scripts/generators/pipeline/output-stage.js +145 -0
  76. package/scripts/generators/pipeline/output-stage.js.map +1 -0
  77. package/scripts/generators/pipeline/transform-stage.d.ts +57 -0
  78. package/scripts/generators/pipeline/transform-stage.d.ts.map +1 -0
  79. package/scripts/generators/pipeline/transform-stage.js +111 -0
  80. package/scripts/generators/pipeline/transform-stage.js.map +1 -0
  81. package/scripts/generators/propositions-content.d.ts +29 -0
  82. package/scripts/generators/propositions-content.d.ts.map +1 -0
  83. package/scripts/generators/propositions-content.js +90 -0
  84. package/scripts/generators/propositions-content.js.map +1 -0
  85. package/scripts/generators/sankey-content.d.ts +45 -0
  86. package/scripts/generators/sankey-content.d.ts.map +1 -0
  87. package/scripts/generators/sankey-content.js +227 -0
  88. package/scripts/generators/sankey-content.js.map +1 -0
  89. package/scripts/generators/sitemap.d.ts +66 -0
  90. package/scripts/generators/sitemap.d.ts.map +1 -0
  91. package/scripts/generators/sitemap.js +562 -0
  92. package/scripts/generators/sitemap.js.map +1 -0
  93. package/scripts/generators/strategies/article-strategy.d.ts +146 -0
  94. package/scripts/generators/strategies/article-strategy.d.ts.map +1 -0
  95. package/scripts/generators/strategies/article-strategy.js +4 -0
  96. package/scripts/generators/strategies/article-strategy.js.map +1 -0
  97. package/scripts/generators/strategies/breaking-news-strategy.d.ts +64 -0
  98. package/scripts/generators/strategies/breaking-news-strategy.d.ts.map +1 -0
  99. package/scripts/generators/strategies/breaking-news-strategy.js +246 -0
  100. package/scripts/generators/strategies/breaking-news-strategy.js.map +1 -0
  101. package/scripts/generators/strategies/committee-reports-strategy.d.ts +93 -0
  102. package/scripts/generators/strategies/committee-reports-strategy.d.ts.map +1 -0
  103. package/scripts/generators/strategies/committee-reports-strategy.js +447 -0
  104. package/scripts/generators/strategies/committee-reports-strategy.js.map +1 -0
  105. package/scripts/generators/strategies/month-ahead-strategy.d.ts +60 -0
  106. package/scripts/generators/strategies/month-ahead-strategy.d.ts.map +1 -0
  107. package/scripts/generators/strategies/month-ahead-strategy.js +175 -0
  108. package/scripts/generators/strategies/month-ahead-strategy.js.map +1 -0
  109. package/scripts/generators/strategies/monthly-review-strategy.d.ts +66 -0
  110. package/scripts/generators/strategies/monthly-review-strategy.d.ts.map +1 -0
  111. package/scripts/generators/strategies/monthly-review-strategy.js +204 -0
  112. package/scripts/generators/strategies/monthly-review-strategy.js.map +1 -0
  113. package/scripts/generators/strategies/motions-strategy.d.ts +61 -0
  114. package/scripts/generators/strategies/motions-strategy.d.ts.map +1 -0
  115. package/scripts/generators/strategies/motions-strategy.js +215 -0
  116. package/scripts/generators/strategies/motions-strategy.js.map +1 -0
  117. package/scripts/generators/strategies/propositions-strategy.d.ts +60 -0
  118. package/scripts/generators/strategies/propositions-strategy.d.ts.map +1 -0
  119. package/scripts/generators/strategies/propositions-strategy.js +257 -0
  120. package/scripts/generators/strategies/propositions-strategy.js.map +1 -0
  121. package/scripts/generators/strategies/week-ahead-strategy.d.ts +57 -0
  122. package/scripts/generators/strategies/week-ahead-strategy.d.ts.map +1 -0
  123. package/scripts/generators/strategies/week-ahead-strategy.js +178 -0
  124. package/scripts/generators/strategies/week-ahead-strategy.js.map +1 -0
  125. package/scripts/generators/strategies/weekly-review-strategy.d.ts +63 -0
  126. package/scripts/generators/strategies/weekly-review-strategy.d.ts.map +1 -0
  127. package/scripts/generators/strategies/weekly-review-strategy.js +211 -0
  128. package/scripts/generators/strategies/weekly-review-strategy.js.map +1 -0
  129. package/scripts/generators/swot-content.d.ts +42 -0
  130. package/scripts/generators/swot-content.d.ts.map +1 -0
  131. package/scripts/generators/swot-content.js +366 -0
  132. package/scripts/generators/swot-content.js.map +1 -0
  133. package/scripts/generators/week-ahead-content.d.ts +103 -0
  134. package/scripts/generators/week-ahead-content.d.ts.map +1 -0
  135. package/scripts/generators/week-ahead-content.js +610 -0
  136. package/scripts/generators/week-ahead-content.js.map +1 -0
  137. package/scripts/index.d.ts +40 -0
  138. package/scripts/index.d.ts.map +1 -0
  139. package/scripts/index.js +53 -0
  140. package/scripts/index.js.map +1 -0
  141. package/scripts/mcp/ep-mcp-client.d.ts +471 -0
  142. package/scripts/mcp/ep-mcp-client.d.ts.map +1 -0
  143. package/scripts/mcp/ep-mcp-client.js +734 -0
  144. package/scripts/mcp/ep-mcp-client.js.map +1 -0
  145. package/scripts/mcp/mcp-connection.d.ts +264 -0
  146. package/scripts/mcp/mcp-connection.d.ts.map +1 -0
  147. package/scripts/mcp/mcp-connection.js +790 -0
  148. package/scripts/mcp/mcp-connection.js.map +1 -0
  149. package/scripts/mcp/mcp-health.d.ts +75 -0
  150. package/scripts/mcp/mcp-health.d.ts.map +1 -0
  151. package/scripts/mcp/mcp-health.js +78 -0
  152. package/scripts/mcp/mcp-health.js.map +1 -0
  153. package/scripts/mcp/mcp-retry.d.ts +94 -0
  154. package/scripts/mcp/mcp-retry.d.ts.map +1 -0
  155. package/scripts/mcp/mcp-retry.js +127 -0
  156. package/scripts/mcp/mcp-retry.js.map +1 -0
  157. package/scripts/mcp/wb-mcp-client.d.ts +38 -0
  158. package/scripts/mcp/wb-mcp-client.d.ts.map +1 -0
  159. package/scripts/mcp/wb-mcp-client.js +112 -0
  160. package/scripts/mcp/wb-mcp-client.js.map +1 -0
  161. package/scripts/templates/article-template.d.ts +9 -0
  162. package/scripts/templates/article-template.d.ts.map +1 -0
  163. package/scripts/templates/article-template.js +378 -0
  164. package/scripts/templates/article-template.js.map +1 -0
  165. package/scripts/templates/section-builders.d.ts +28 -0
  166. package/scripts/templates/section-builders.d.ts.map +1 -0
  167. package/scripts/templates/section-builders.js +142 -0
  168. package/scripts/templates/section-builders.js.map +1 -0
  169. package/scripts/types/analysis.d.ts +115 -0
  170. package/scripts/types/analysis.d.ts.map +1 -0
  171. package/scripts/types/analysis.js +4 -0
  172. package/scripts/types/analysis.js.map +1 -0
  173. package/scripts/types/common.d.ts +584 -0
  174. package/scripts/types/common.d.ts.map +1 -0
  175. package/scripts/types/common.js +96 -0
  176. package/scripts/types/common.js.map +1 -0
  177. package/scripts/types/generation.d.ts +104 -0
  178. package/scripts/types/generation.d.ts.map +1 -0
  179. package/scripts/types/generation.js +4 -0
  180. package/scripts/types/generation.js.map +1 -0
  181. package/scripts/types/index.d.ts +24 -0
  182. package/scripts/types/index.d.ts.map +1 -0
  183. package/scripts/types/index.js +16 -0
  184. package/scripts/types/index.js.map +1 -0
  185. package/scripts/types/intelligence.d.ts +129 -0
  186. package/scripts/types/intelligence.d.ts.map +1 -0
  187. package/scripts/types/intelligence.js +4 -0
  188. package/scripts/types/intelligence.js.map +1 -0
  189. package/scripts/types/mcp.d.ts +418 -0
  190. package/scripts/types/mcp.d.ts.map +1 -0
  191. package/scripts/types/mcp.js +4 -0
  192. package/scripts/types/mcp.js.map +1 -0
  193. package/scripts/types/parliament.d.ts +388 -0
  194. package/scripts/types/parliament.d.ts.map +1 -0
  195. package/scripts/types/parliament.js +4 -0
  196. package/scripts/types/parliament.js.map +1 -0
  197. package/scripts/types/quality.d.ts +114 -0
  198. package/scripts/types/quality.d.ts.map +1 -0
  199. package/scripts/types/quality.js +4 -0
  200. package/scripts/types/quality.js.map +1 -0
  201. package/scripts/types/stakeholder.d.ts +88 -0
  202. package/scripts/types/stakeholder.d.ts.map +1 -0
  203. package/scripts/types/stakeholder.js +16 -0
  204. package/scripts/types/stakeholder.js.map +1 -0
  205. package/scripts/types/visualization.d.ts +708 -0
  206. package/scripts/types/visualization.d.ts.map +1 -0
  207. package/scripts/types/visualization.js +4 -0
  208. package/scripts/types/visualization.js.map +1 -0
  209. package/scripts/types/world-bank.d.ts +85 -0
  210. package/scripts/types/world-bank.d.ts.map +1 -0
  211. package/scripts/types/world-bank.js +4 -0
  212. package/scripts/types/world-bank.js.map +1 -0
  213. package/scripts/utils/article-category.d.ts +18 -0
  214. package/scripts/utils/article-category.d.ts.map +1 -0
  215. package/scripts/utils/article-category.js +49 -0
  216. package/scripts/utils/article-category.js.map +1 -0
  217. package/scripts/utils/article-quality-scorer.d.ts +87 -0
  218. package/scripts/utils/article-quality-scorer.d.ts.map +1 -0
  219. package/scripts/utils/article-quality-scorer.js +1048 -0
  220. package/scripts/utils/article-quality-scorer.js.map +1 -0
  221. package/scripts/utils/content-metadata.d.ts +34 -0
  222. package/scripts/utils/content-metadata.d.ts.map +1 -0
  223. package/scripts/utils/content-metadata.js +249 -0
  224. package/scripts/utils/content-metadata.js.map +1 -0
  225. package/scripts/utils/content-validator.d.ts +94 -0
  226. package/scripts/utils/content-validator.d.ts.map +1 -0
  227. package/scripts/utils/content-validator.js +489 -0
  228. package/scripts/utils/content-validator.js.map +1 -0
  229. package/scripts/utils/copy-test-reports.d.ts +9 -0
  230. package/scripts/utils/copy-test-reports.d.ts.map +1 -0
  231. package/scripts/utils/copy-test-reports.js +508 -0
  232. package/scripts/utils/copy-test-reports.js.map +1 -0
  233. package/scripts/utils/file-utils.d.ts +144 -0
  234. package/scripts/utils/file-utils.d.ts.map +1 -0
  235. package/scripts/utils/file-utils.js +374 -0
  236. package/scripts/utils/file-utils.js.map +1 -0
  237. package/scripts/utils/fix-articles.d.ts +27 -0
  238. package/scripts/utils/fix-articles.d.ts.map +1 -0
  239. package/scripts/utils/fix-articles.js +510 -0
  240. package/scripts/utils/fix-articles.js.map +1 -0
  241. package/scripts/utils/generate-docs-index.d.ts +8 -0
  242. package/scripts/utils/generate-docs-index.d.ts.map +1 -0
  243. package/scripts/utils/generate-docs-index.js +275 -0
  244. package/scripts/utils/generate-docs-index.js.map +1 -0
  245. package/scripts/utils/html-sanitize.d.ts +18 -0
  246. package/scripts/utils/html-sanitize.d.ts.map +1 -0
  247. package/scripts/utils/html-sanitize.js +57 -0
  248. package/scripts/utils/html-sanitize.js.map +1 -0
  249. package/scripts/utils/intelligence-analysis.d.ts +173 -0
  250. package/scripts/utils/intelligence-analysis.d.ts.map +1 -0
  251. package/scripts/utils/intelligence-analysis.js +936 -0
  252. package/scripts/utils/intelligence-analysis.js.map +1 -0
  253. package/scripts/utils/intelligence-index.d.ts +126 -0
  254. package/scripts/utils/intelligence-index.d.ts.map +1 -0
  255. package/scripts/utils/intelligence-index.js +731 -0
  256. package/scripts/utils/intelligence-index.js.map +1 -0
  257. package/scripts/utils/metadata-utils.d.ts +14 -0
  258. package/scripts/utils/metadata-utils.d.ts.map +1 -0
  259. package/scripts/utils/metadata-utils.js +18 -0
  260. package/scripts/utils/metadata-utils.js.map +1 -0
  261. package/scripts/utils/news-metadata.d.ts +47 -0
  262. package/scripts/utils/news-metadata.d.ts.map +1 -0
  263. package/scripts/utils/news-metadata.js +259 -0
  264. package/scripts/utils/news-metadata.js.map +1 -0
  265. package/scripts/utils/validate-articles.d.ts +2 -0
  266. package/scripts/utils/validate-articles.d.ts.map +1 -0
  267. package/scripts/utils/validate-articles.js +284 -0
  268. package/scripts/utils/validate-articles.js.map +1 -0
  269. package/scripts/utils/validate-ep-api.d.ts +51 -0
  270. package/scripts/utils/validate-ep-api.d.ts.map +1 -0
  271. package/scripts/utils/validate-ep-api.js +160 -0
  272. package/scripts/utils/validate-ep-api.js.map +1 -0
  273. package/scripts/utils/world-bank-data.d.ts +84 -0
  274. package/scripts/utils/world-bank-data.d.ts.map +1 -0
  275. package/scripts/utils/world-bank-data.js +311 -0
  276. package/scripts/utils/world-bank-data.js.map +1 -0
@@ -0,0 +1,175 @@
1
+ // SPDX-FileCopyrightText: 2024-2026 Hack23 AB
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { ArticleCategory } from '../../types/index.js';
4
+ import { MONTH_AHEAD_TITLES, getLocalizedString } from '../../constants/languages.js';
5
+ import { fetchWeekAheadData, fetchEPFeedData } from '../pipeline/fetch-stage.js';
6
+ import { buildWeekAheadContent, buildKeywords } from '../week-ahead-content.js';
7
+ import { buildDeepAnalysisSection } from '../deep-analysis-content.js';
8
+ import { buildProspectiveAnalysis, buildProspectiveSwot, buildProspectiveDashboard, buildProspectiveMindmap, } from '../analysis-builders.js';
9
+ import { buildSwotSection } from '../swot-content.js';
10
+ import { buildDashboardSection } from '../dashboard-content.js';
11
+ import { buildIntelligenceMindmapSection } from '../mindmap-content.js';
12
+ import { pl } from '../../utils/metadata-utils.js';
13
+ /** Keywords shared by all Month Ahead articles */
14
+ const MONTH_AHEAD_KEYWORDS = [
15
+ 'European Parliament',
16
+ 'month ahead',
17
+ 'strategic outlook',
18
+ 'legislative calendar',
19
+ ];
20
+ /**
21
+ * Build a content-aware title suffix from month-ahead data counts.
22
+ *
23
+ * @param monthData - Aggregated month-ahead domain data
24
+ * @returns Short suffix for the title, or empty string
25
+ */
26
+ function buildMonthAheadTitleSuffix(monthData) {
27
+ const parts = [];
28
+ if (monthData.events.length > 0)
29
+ parts.push(pl(monthData.events.length, 'Event', 'Events'));
30
+ if (monthData.committees.length > 0)
31
+ parts.push(pl(monthData.committees.length, 'Committee Meeting', 'Committee Meetings'));
32
+ if (monthData.pipeline.length > 0)
33
+ parts.push(pl(monthData.pipeline.length, 'Pipeline Item', 'Pipeline Items'));
34
+ return parts.join(', ');
35
+ }
36
+ /**
37
+ * Build a content-aware description from month-ahead data.
38
+ *
39
+ * @param monthData - Aggregated month-ahead domain data
40
+ * @param monthLabel - Display label for the target month
41
+ * @returns SEO-friendly description (≤ 200 chars)
42
+ */
43
+ function buildMonthAheadDescription(monthData, monthLabel) {
44
+ const parts = [];
45
+ if (monthData.events.length > 0)
46
+ parts.push(pl(monthData.events.length, 'scheduled event', 'scheduled events'));
47
+ if (monthData.committees.length > 0)
48
+ parts.push(pl(monthData.committees.length, 'committee meeting', 'committee meetings'));
49
+ if (monthData.pipeline.length > 0)
50
+ parts.push(pl(monthData.pipeline.length, 'pipeline procedure', 'pipeline procedures'));
51
+ if (monthData.questions.length > 0)
52
+ parts.push(pl(monthData.questions.length, 'parliamentary question', 'parliamentary questions'));
53
+ if (parts.length === 0) {
54
+ return `European Parliament strategic outlook for ${monthLabel} — legislative milestones and policy agenda.`;
55
+ }
56
+ const desc = `EP month ahead (${monthLabel}): ${parts.join(', ')}.`;
57
+ return desc.length > 200 ? desc.slice(0, 197) + '...' : desc;
58
+ }
59
+ // ─── Date-range helper ────────────────────────────────────────────────────────
60
+ /**
61
+ * Compute the month-ahead date range spanning 30 days from the day after `baseDate`.
62
+ *
63
+ * @param baseDate - ISO 8601 publication date (YYYY-MM-DD)
64
+ * @returns Date range spanning the next 30 days
65
+ */
66
+ function computeMonthAheadDateRange(baseDate) {
67
+ const base = new Date(`${baseDate}T00:00:00Z`);
68
+ const startDate = new Date(base);
69
+ startDate.setUTCDate(base.getUTCDate() + 1);
70
+ const endDate = new Date(startDate);
71
+ endDate.setUTCDate(startDate.getUTCDate() + 30);
72
+ const startParts = startDate.toISOString().split('T');
73
+ const endParts = endDate.toISOString().split('T');
74
+ if (!startParts[0] || !endParts[0]) {
75
+ throw new Error('Invalid date format generated in computeMonthAheadDateRange');
76
+ }
77
+ return {
78
+ start: startParts[0],
79
+ end: endParts[0],
80
+ };
81
+ }
82
+ /**
83
+ * Format a month label from a date string (e.g. "February 2026").
84
+ *
85
+ * @param dateStr - ISO 8601 date
86
+ * @returns Human-readable month label, using the runtime's default locale
87
+ */
88
+ function formatMonthLabel(dateStr) {
89
+ const date = new Date(`${dateStr}T00:00:00Z`);
90
+ return date.toLocaleDateString(undefined, { month: 'long', year: 'numeric', timeZone: 'UTC' });
91
+ }
92
+ // ─── Strategy implementation ──────────────────────────────────────────────────
93
+ /**
94
+ * Article strategy for {@link ArticleCategory.MONTH_AHEAD}.
95
+ * Fetches plenary, committee, document, and pipeline data then builds
96
+ * a forward-looking 30-day strategic outlook of parliamentary activity.
97
+ */
98
+ export class MonthAheadStrategy {
99
+ type = ArticleCategory.MONTH_AHEAD;
100
+ requiredMCPTools = [
101
+ 'get_plenary_sessions',
102
+ 'get_committee_info',
103
+ 'search_documents',
104
+ 'monitor_legislative_pipeline',
105
+ 'get_parliamentary_questions',
106
+ 'get_events',
107
+ 'get_events_feed',
108
+ 'get_adopted_texts_feed',
109
+ 'get_procedures_feed',
110
+ ];
111
+ /**
112
+ * Fetch month-ahead data from MCP.
113
+ *
114
+ * @param client - MCP client or null
115
+ * @param date - ISO 8601 publication date
116
+ * @returns Populated month-ahead data payload
117
+ */
118
+ async fetchData(client, date) {
119
+ const dateRange = computeMonthAheadDateRange(date);
120
+ console.log(` 📆 Month-ahead range: ${dateRange.start} to ${dateRange.end}`);
121
+ // Fetch traditional MCP data and EP feeds in parallel
122
+ const [monthData, feedData] = await Promise.all([
123
+ fetchWeekAheadData(client, dateRange),
124
+ fetchEPFeedData(client, 'one-month', dateRange),
125
+ ]);
126
+ const keywords = [...MONTH_AHEAD_KEYWORDS, ...buildKeywords(monthData)];
127
+ const monthLabel = formatMonthLabel(dateRange.start);
128
+ return { date, dateRange, monthData, keywords, monthLabel, feedData };
129
+ }
130
+ /**
131
+ * Build the month-ahead HTML body for the specified language.
132
+ *
133
+ * @param data - Month-ahead data payload
134
+ * @param lang - Target language code used for editorial strings
135
+ * @returns Article HTML body
136
+ */
137
+ buildContent(data, lang) {
138
+ const base = buildWeekAheadContent(data.monthData, data.dateRange, lang);
139
+ const analysis = buildProspectiveAnalysis(data.monthData, data.dateRange, 'month');
140
+ const analysisSection = buildDeepAnalysisSection(analysis, lang, 'en');
141
+ const mindmapData = buildProspectiveMindmap(data.monthData, lang);
142
+ const mindmapSection = buildIntelligenceMindmapSection(mindmapData, lang);
143
+ const swotData = buildProspectiveSwot(data.monthData, 'month', lang);
144
+ const swotSection = buildSwotSection(swotData, lang);
145
+ const dashboardData = buildProspectiveDashboard(data.monthData, 'month', lang);
146
+ const dashboardSection = buildDashboardSection(dashboardData, lang);
147
+ return base.replace('<!-- /article-content -->', analysisSection + mindmapSection + swotSection + dashboardSection);
148
+ }
149
+ /**
150
+ * Return language-specific metadata for the month-ahead article.
151
+ *
152
+ * @param data - Month-ahead data payload
153
+ * @param lang - Target language code
154
+ * @returns Localised metadata
155
+ */
156
+ getMetadata(data, lang) {
157
+ const titleFn = getLocalizedString(MONTH_AHEAD_TITLES, lang);
158
+ const { title: baseTitle, subtitle: baseSubtitle } = titleFn(data.monthLabel);
159
+ const suffix = lang === 'en' ? buildMonthAheadTitleSuffix(data.monthData) : '';
160
+ const title = suffix ? `${baseTitle} — ${suffix}` : baseTitle;
161
+ const subtitle = lang === 'en'
162
+ ? buildMonthAheadDescription(data.monthData, data.monthLabel) || baseSubtitle
163
+ : baseSubtitle;
164
+ return {
165
+ title,
166
+ subtitle,
167
+ keywords: data.keywords,
168
+ category: ArticleCategory.MONTH_AHEAD,
169
+ sources: [],
170
+ };
171
+ }
172
+ }
173
+ /** Singleton instance for use by the strategy registry */
174
+ export const monthAheadStrategy = new MonthAheadStrategy();
175
+ //# sourceMappingURL=month-ahead-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"month-ahead-strategy.js","sourceRoot":"","sources":["../../../src/generators/strategies/month-ahead-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @module Generators/Strategies/MonthlyReviewStrategy
3
+ * @description Article strategy for the Month In Review article type.
4
+ * Fetches voting records, voting patterns, voting anomalies, and
5
+ * parliamentary questions from the past 30 days, then renders a
6
+ * comprehensive retrospective analysis article.
7
+ */
8
+ import type { EuropeanParliamentMCPClient } from '../../mcp/ep-mcp-client.js';
9
+ import { ArticleCategory } from '../../types/index.js';
10
+ import type { LanguageCode, DateRange, VotingRecord, VotingPattern, VotingAnomaly, MotionsQuestion, EPFeedData } from '../../types/index.js';
11
+ import type { ArticleStrategy, ArticleData, ArticleMetadata } from './article-strategy.js';
12
+ /** Data fetched and pre-processed by {@link MonthlyReviewStrategy} */
13
+ export interface MonthlyReviewArticleData extends ArticleData {
14
+ /** Review period date range (30 days) */
15
+ readonly dateRange: DateRange;
16
+ /** Voting records from the review period */
17
+ readonly votingRecords: readonly VotingRecord[];
18
+ /** Voting patterns analysis */
19
+ readonly votingPatterns: readonly VotingPattern[];
20
+ /** Detected voting anomalies */
21
+ readonly anomalies: readonly VotingAnomaly[];
22
+ /** Parliamentary questions from the period */
23
+ readonly questions: readonly MotionsQuestion[];
24
+ /** Start date string for display */
25
+ readonly dateFromStr: string;
26
+ /** Display label for the review month */
27
+ readonly monthLabel: string;
28
+ /** EP feed data for enrichment (when available) */
29
+ readonly feedData?: EPFeedData | undefined;
30
+ }
31
+ /**
32
+ * Article strategy for {@link ArticleCategory.MONTH_IN_REVIEW}.
33
+ * Fetches voting records, anomalies, patterns, and questions for the
34
+ * past 30 days and builds a comprehensive retrospective analysis.
35
+ */
36
+ export declare class MonthlyReviewStrategy implements ArticleStrategy<MonthlyReviewArticleData> {
37
+ readonly type = ArticleCategory.MONTH_IN_REVIEW;
38
+ readonly requiredMCPTools: readonly ["get_voting_records", "analyze_voting_patterns", "detect_voting_anomalies", "get_parliamentary_questions", "get_adopted_texts_feed", "get_procedures_feed", "get_events_feed"];
39
+ /**
40
+ * Fetch monthly review data from MCP.
41
+ *
42
+ * @param client - MCP client or null
43
+ * @param date - ISO 8601 publication date
44
+ * @returns Populated monthly review data payload
45
+ */
46
+ fetchData(client: EuropeanParliamentMCPClient | null, date: string): Promise<MonthlyReviewArticleData>;
47
+ /**
48
+ * Build the monthly review HTML body for the specified language.
49
+ *
50
+ * @param data - Monthly review data payload
51
+ * @param lang - Target language code used for editorial strings
52
+ * @returns Article HTML body
53
+ */
54
+ buildContent(data: MonthlyReviewArticleData, lang: LanguageCode): string;
55
+ /**
56
+ * Return language-specific metadata for the monthly review article.
57
+ *
58
+ * @param data - Monthly review data payload
59
+ * @param lang - Target language code
60
+ * @returns Localised metadata
61
+ */
62
+ getMetadata(data: MonthlyReviewArticleData, lang: LanguageCode): ArticleMetadata;
63
+ }
64
+ /** Singleton instance for use by the strategy registry */
65
+ export declare const monthlyReviewStrategy: MonthlyReviewStrategy;
66
+ //# sourceMappingURL=monthly-review-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monthly-review-strategy.d.ts","sourceRoot":"","sources":["../../../src/generators/strategies/monthly-review-strategy.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACX,MAAM,sBAAsB,CAAC;AAoB9B,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK3F,sEAAsE;AACtE,MAAM,WAAW,wBAAyB,SAAQ,WAAW;IAC3D,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,+BAA+B;IAC/B,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IAClD,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,oCAAoC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAC5C;AAiHD;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,eAAe,CAAC,wBAAwB,CAAC;IACrF,QAAQ,CAAC,IAAI,mCAAmC;IAEhD,QAAQ,CAAC,gBAAgB,2LAQd;IAEX;;;;;;OAMG;IACG,SAAS,CACb,MAAM,EAAE,2BAA2B,GAAG,IAAI,EAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,wBAAwB,CAAC;IA4BpC;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM;IAyCxE;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,YAAY,GAAG,eAAe;CAejF;AAED,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,uBAA8B,CAAC"}
@@ -0,0 +1,204 @@
1
+ // SPDX-FileCopyrightText: 2024-2026 Hack23 AB
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { ArticleCategory } from '../../types/index.js';
4
+ import { MONTHLY_REVIEW_TITLES, getLocalizedString } from '../../constants/languages.js';
5
+ import { fetchVotingRecords, fetchVotingPatterns, fetchMotionsAnomalies, fetchParliamentaryQuestionsForMotions, fetchEPFeedData, } from '../pipeline/fetch-stage.js';
6
+ import { generateMotionsContent } from '../motions-content.js';
7
+ import { buildDeepAnalysisSection } from '../deep-analysis-content.js';
8
+ import { buildVotingAnalysis, buildVotingSwot, buildVotingDashboard, buildVotingMindmap, } from '../analysis-builders.js';
9
+ import { buildSwotSection } from '../swot-content.js';
10
+ import { buildDashboardSection } from '../dashboard-content.js';
11
+ import { buildIntelligenceMindmapSection } from '../mindmap-content.js';
12
+ import { pl } from '../../utils/metadata-utils.js';
13
+ /** Base keywords shared by all Monthly Review articles */
14
+ const MONTHLY_REVIEW_BASE_KEYWORDS = [
15
+ 'European Parliament',
16
+ 'monthly review',
17
+ 'legislative output',
18
+ 'coalition dynamics',
19
+ ];
20
+ /**
21
+ * Extract content-aware keywords from monthly review data.
22
+ *
23
+ * @param data - Monthly review article data payload
24
+ * @returns Deduplicated keyword array
25
+ */
26
+ function buildMonthlyReviewKeywords(data) {
27
+ const keywords = [...MONTHLY_REVIEW_BASE_KEYWORDS];
28
+ for (const r of data.votingRecords.slice(0, 5)) {
29
+ if (r.title)
30
+ keywords.push(r.title.slice(0, 60));
31
+ }
32
+ for (const a of data.anomalies.slice(0, 3)) {
33
+ if (a.type)
34
+ keywords.push(a.type);
35
+ }
36
+ for (const q of data.questions.slice(0, 3)) {
37
+ if (q.topic)
38
+ keywords.push(q.topic);
39
+ }
40
+ return [...new Set(keywords)];
41
+ }
42
+ /**
43
+ * Build a content-aware description from monthly review data.
44
+ *
45
+ * @param data - Monthly review article data payload
46
+ * @returns SEO-friendly description (≤ 200 chars)
47
+ */
48
+ function buildMonthlyReviewDescription(data) {
49
+ const parts = [];
50
+ if (data.votingRecords.length > 0)
51
+ parts.push(`${pl(data.votingRecords.length, 'vote', 'votes')} analysed`);
52
+ if (data.anomalies.length > 0)
53
+ parts.push(pl(data.anomalies.length, 'voting anomaly', 'voting anomalies'));
54
+ if (data.questions.length > 0)
55
+ parts.push(`${pl(data.questions.length, 'question', 'questions')} tabled`);
56
+ if (parts.length === 0) {
57
+ return `European Parliament monthly review for ${data.monthLabel} — legislative output and coalition dynamics.`;
58
+ }
59
+ const highlight = data.votingRecords[0]?.title ?? '';
60
+ const base = `EP month in review (${data.monthLabel}): ${parts.join(', ')}`;
61
+ if (highlight) {
62
+ const full = `${base}. Key: ${highlight}`;
63
+ return full.length > 200 ? full.slice(0, 197) + '...' : full;
64
+ }
65
+ return base.length > 200 ? base.slice(0, 197) + '...' : base;
66
+ }
67
+ /**
68
+ * Build a content-aware title suffix from monthly review data counts.
69
+ *
70
+ * @param data - Monthly review article data payload
71
+ * @returns Short suffix for the title, or empty string
72
+ */
73
+ function buildMonthlyReviewTitleSuffix(data) {
74
+ const parts = [];
75
+ if (data.votingRecords.length > 0)
76
+ parts.push(pl(data.votingRecords.length, 'Vote', 'Votes'));
77
+ if (data.anomalies.length > 0)
78
+ parts.push(pl(data.anomalies.length, 'Anomaly', 'Anomalies'));
79
+ return parts.join(', ');
80
+ }
81
+ // ─── Date-range helper ────────────────────────────────────────────────────────
82
+ /**
83
+ * Compute the review period covering the 30 days ending on `baseDate`.
84
+ *
85
+ * @param baseDate - ISO 8601 publication date (YYYY-MM-DD)
86
+ * @returns Date range covering the past 30 days
87
+ */
88
+ function computeMonthlyReviewDateRange(baseDate) {
89
+ const end = new Date(`${baseDate}T00:00:00Z`);
90
+ const start = new Date(end);
91
+ start.setUTCDate(end.getUTCDate() - 30);
92
+ const startParts = start.toISOString().split('T');
93
+ const endParts = end.toISOString().split('T');
94
+ if (!startParts[0] || !endParts[0]) {
95
+ throw new Error('Invalid date format generated in computeMonthlyReviewDateRange');
96
+ }
97
+ return {
98
+ start: startParts[0],
99
+ end: endParts[0],
100
+ };
101
+ }
102
+ /**
103
+ * Format a month label from a date string (e.g. "February 2026").
104
+ *
105
+ * @param dateStr - ISO 8601 date
106
+ * @returns Human-readable month label, using the runtime's default locale
107
+ */
108
+ function formatMonthLabel(dateStr) {
109
+ const date = new Date(`${dateStr}T00:00:00Z`);
110
+ return date.toLocaleDateString(undefined, { month: 'long', year: 'numeric', timeZone: 'UTC' });
111
+ }
112
+ // ─── Strategy implementation ──────────────────────────────────────────────────
113
+ /**
114
+ * Article strategy for {@link ArticleCategory.MONTH_IN_REVIEW}.
115
+ * Fetches voting records, anomalies, patterns, and questions for the
116
+ * past 30 days and builds a comprehensive retrospective analysis.
117
+ */
118
+ export class MonthlyReviewStrategy {
119
+ type = ArticleCategory.MONTH_IN_REVIEW;
120
+ requiredMCPTools = [
121
+ 'get_voting_records',
122
+ 'analyze_voting_patterns',
123
+ 'detect_voting_anomalies',
124
+ 'get_parliamentary_questions',
125
+ 'get_adopted_texts_feed',
126
+ 'get_procedures_feed',
127
+ 'get_events_feed',
128
+ ];
129
+ /**
130
+ * Fetch monthly review data from MCP.
131
+ *
132
+ * @param client - MCP client or null
133
+ * @param date - ISO 8601 publication date
134
+ * @returns Populated monthly review data payload
135
+ */
136
+ async fetchData(client, date) {
137
+ const dateRange = computeMonthlyReviewDateRange(date);
138
+ console.log(` 📊 Monthly review range: ${dateRange.start} to ${dateRange.end}`);
139
+ // Fetch voting data and EP feed data in parallel
140
+ const [votingRecords, votingPatterns, anomalies, questions, feedData] = await Promise.all([
141
+ fetchVotingRecords(client, dateRange.start, dateRange.end),
142
+ fetchVotingPatterns(client, dateRange.start, dateRange.end),
143
+ fetchMotionsAnomalies(client, dateRange.start, dateRange.end),
144
+ fetchParliamentaryQuestionsForMotions(client, dateRange.start, dateRange.end),
145
+ fetchEPFeedData(client, 'one-month', dateRange),
146
+ ]);
147
+ const monthLabel = formatMonthLabel(dateRange.start);
148
+ return {
149
+ date,
150
+ dateRange,
151
+ dateFromStr: dateRange.start,
152
+ votingRecords,
153
+ votingPatterns,
154
+ anomalies,
155
+ questions,
156
+ monthLabel,
157
+ feedData,
158
+ };
159
+ }
160
+ /**
161
+ * Build the monthly review HTML body for the specified language.
162
+ *
163
+ * @param data - Monthly review data payload
164
+ * @param lang - Target language code used for editorial strings
165
+ * @returns Article HTML body
166
+ */
167
+ buildContent(data, lang) {
168
+ const base = generateMotionsContent(data.dateRange.start, data.dateRange.end, [...data.votingRecords], [...data.votingPatterns], [...data.anomalies], [...data.questions], lang);
169
+ const analysis = buildVotingAnalysis(data.dateRange.start, data.dateRange.end, data.votingRecords, data.votingPatterns, data.anomalies, data.questions);
170
+ const deepSection = buildDeepAnalysisSection(analysis, lang, 'en');
171
+ const mindmapData = buildVotingMindmap(data.votingRecords, data.votingPatterns, data.anomalies, lang);
172
+ const mindmapSection = buildIntelligenceMindmapSection(mindmapData, lang);
173
+ const swotData = buildVotingSwot(data.votingRecords, data.votingPatterns, data.anomalies, lang);
174
+ const swotSection = buildSwotSection(swotData, lang);
175
+ const dashboardData = buildVotingDashboard(data.votingRecords, data.votingPatterns, data.anomalies, lang);
176
+ const dashboardSection = buildDashboardSection(dashboardData, lang);
177
+ return base.replace('<!-- /article-content -->', deepSection + mindmapSection + swotSection + dashboardSection);
178
+ }
179
+ /**
180
+ * Return language-specific metadata for the monthly review article.
181
+ *
182
+ * @param data - Monthly review data payload
183
+ * @param lang - Target language code
184
+ * @returns Localised metadata
185
+ */
186
+ getMetadata(data, lang) {
187
+ const titleFn = getLocalizedString(MONTHLY_REVIEW_TITLES, lang);
188
+ const { title: baseTitle, subtitle: baseSubtitle } = titleFn(data.monthLabel);
189
+ const suffix = lang === 'en' ? buildMonthlyReviewTitleSuffix(data) : '';
190
+ const title = suffix ? `${baseTitle} — ${suffix}` : baseTitle;
191
+ const description = lang === 'en' ? buildMonthlyReviewDescription(data) : '';
192
+ const subtitle = description || baseSubtitle;
193
+ return {
194
+ title,
195
+ subtitle,
196
+ keywords: buildMonthlyReviewKeywords(data),
197
+ category: ArticleCategory.MONTH_IN_REVIEW,
198
+ sources: [],
199
+ };
200
+ }
201
+ }
202
+ /** Singleton instance for use by the strategy registry */
203
+ export const monthlyReviewStrategy = new MonthlyReviewStrategy();
204
+ //# sourceMappingURL=monthly-review-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monthly-review-strategy.js","sourceRoot":"","sources":["../../../src/generators/strategies/monthly-review-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @module Generators/Strategies/MotionsStrategy
3
+ * @description Article strategy for the Motions article type.
4
+ * Fetches voting records, patterns, anomalies and parliamentary questions
5
+ * over a rolling 30-day window then renders a voting-behaviour overview.
6
+ */
7
+ import type { EuropeanParliamentMCPClient } from '../../mcp/ep-mcp-client.js';
8
+ import { ArticleCategory } from '../../types/index.js';
9
+ import type { LanguageCode, VotingRecord, VotingPattern, VotingAnomaly, MotionsQuestion, EPFeedData } from '../../types/index.js';
10
+ import type { ArticleStrategy, ArticleData, ArticleMetadata } from './article-strategy.js';
11
+ /** Data fetched and pre-processed by {@link MotionsStrategy} */
12
+ export interface MotionsArticleData extends ArticleData {
13
+ /** Start of the 30-day look-back window */
14
+ readonly dateFromStr: string;
15
+ /** Voting records for the period */
16
+ readonly votingRecords: readonly VotingRecord[];
17
+ /** Voting patterns for the period */
18
+ readonly votingPatterns: readonly VotingPattern[];
19
+ /** Voting anomalies detected in the period */
20
+ readonly anomalies: readonly VotingAnomaly[];
21
+ /** Parliamentary questions raised in the period */
22
+ readonly questions: readonly MotionsQuestion[];
23
+ /** EP feed data for enrichment (when available) */
24
+ readonly feedData?: EPFeedData | undefined;
25
+ }
26
+ /**
27
+ * Article strategy for {@link ArticleCategory.MOTIONS}.
28
+ * Aggregates voting data over a rolling 30-day window and surfaces
29
+ * patterns, anomalies and parliamentary questions.
30
+ */
31
+ export declare class MotionsStrategy implements ArticleStrategy<MotionsArticleData> {
32
+ readonly type = ArticleCategory.MOTIONS;
33
+ readonly requiredMCPTools: readonly ["get_voting_records", "analyze_voting_patterns", "detect_voting_anomalies", "get_parliamentary_questions", "get_adopted_texts_feed", "get_parliamentary_questions_feed"];
34
+ /**
35
+ * Fetch all motions data for the last 30 days.
36
+ *
37
+ * @param client - MCP client or null
38
+ * @param date - ISO 8601 publication date (end of the look-back window)
39
+ * @returns Populated motions data payload
40
+ */
41
+ fetchData(client: EuropeanParliamentMCPClient | null, date: string): Promise<MotionsArticleData>;
42
+ /**
43
+ * Build the motions HTML body for the specified language.
44
+ *
45
+ * @param data - Motions data payload
46
+ * @param lang - Target language code used for editorial strings
47
+ * @returns Article HTML body
48
+ */
49
+ buildContent(data: MotionsArticleData, lang: LanguageCode): string;
50
+ /**
51
+ * Return language-specific metadata for the motions article.
52
+ *
53
+ * @param data - Motions data payload
54
+ * @param lang - Target language code
55
+ * @returns Localised metadata
56
+ */
57
+ getMetadata(data: MotionsArticleData, lang: LanguageCode): ArticleMetadata;
58
+ }
59
+ /** Singleton instance for use by the strategy registry */
60
+ export declare const motionsStrategy: MotionsStrategy;
61
+ //# sourceMappingURL=motions-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motions-strategy.d.ts","sourceRoot":"","sources":["../../../src/generators/strategies/motions-strategy.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACX,MAAM,sBAAsB,CAAC;AAmB9B,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoG3F,gEAAgE;AAChE,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,qCAAqC;IACrC,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAC5C;AAID;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,eAAe,CAAC,kBAAkB,CAAC;IACzE,QAAQ,CAAC,IAAI,2BAA2B;IAExC,QAAQ,CAAC,gBAAgB,qLAOd;IAEX;;;;;;OAMG;IACG,SAAS,CACb,MAAM,EAAE,2BAA2B,GAAG,IAAI,EAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,CAAC;IA6B9B;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM;IAsDlE;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,YAAY,GAAG,eAAe;CAe3E;AAED,0DAA0D;AAC1D,eAAO,MAAM,eAAe,iBAAwB,CAAC"}