fhirsmith 0.3.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 (277) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/FHIRsmith.png +0 -0
  3. package/README.md +277 -0
  4. package/config-template.json +144 -0
  5. package/library/folder-setup.js +58 -0
  6. package/library/html-server.js +166 -0
  7. package/library/html.js +835 -0
  8. package/library/i18nsupport.js +259 -0
  9. package/library/languages.js +779 -0
  10. package/library/logger-telnet.js +205 -0
  11. package/library/logger.js +279 -0
  12. package/library/package-manager.js +876 -0
  13. package/library/utilities.js +196 -0
  14. package/library/version-utilities.js +1056 -0
  15. package/npmprojector/config-example.json +13 -0
  16. package/npmprojector/indexer.js +394 -0
  17. package/npmprojector/npmprojector.js +395 -0
  18. package/npmprojector/readme.md +174 -0
  19. package/npmprojector/watcher.js +335 -0
  20. package/package.json +119 -0
  21. package/packages/package-crawler.js +846 -0
  22. package/packages/packages-template.html +126 -0
  23. package/packages/packages.js +2838 -0
  24. package/passwords.ini +2 -0
  25. package/publisher/publisher-template.html +208 -0
  26. package/publisher/publisher.js +2167 -0
  27. package/publisher/task-draft.js +458 -0
  28. package/registry/api.js +735 -0
  29. package/registry/crawler.js +637 -0
  30. package/registry/model.js +513 -0
  31. package/registry/readme.md +243 -0
  32. package/registry/registry-data.json +121015 -0
  33. package/registry/registry-template.html +126 -0
  34. package/registry/registry.js +1395 -0
  35. package/registry/test-runner.js +237 -0
  36. package/root-template.html +124 -0
  37. package/server.js +524 -0
  38. package/shl/private-key.pem +5 -0
  39. package/shl/public-key.pem +18 -0
  40. package/shl/shl.js +1125 -0
  41. package/shl/vhl.js +69 -0
  42. package/static/FHIRsmith128.png +0 -0
  43. package/static/FHIRsmith16.png +0 -0
  44. package/static/FHIRsmith32.png +0 -0
  45. package/static/FHIRsmith64.png +0 -0
  46. package/static/assets/css/bootstrap-fhir.css +5302 -0
  47. package/static/assets/css/bootstrap-glyphicons.css +2 -0
  48. package/static/assets/css/bootstrap.css +4097 -0
  49. package/static/assets/css/jquery-ui.css +523 -0
  50. package/static/assets/css/jquery-ui.structure.css +863 -0
  51. package/static/assets/css/jquery-ui.structure.min.css +5 -0
  52. package/static/assets/css/jquery-ui.theme.css +439 -0
  53. package/static/assets/css/jquery-ui.theme.min.css +5 -0
  54. package/static/assets/css/jquery.ui.all.css +7 -0
  55. package/static/assets/css/modules.css +18 -0
  56. package/static/assets/css/project.css +367 -0
  57. package/static/assets/css/pygments-manni.css +66 -0
  58. package/static/assets/css/tags.css +74 -0
  59. package/static/assets/css/xml.css +2 -0
  60. package/static/assets/fonts/glyphiconshalflings-regular.eot +0 -0
  61. package/static/assets/fonts/glyphiconshalflings-regular.otf +0 -0
  62. package/static/assets/fonts/glyphiconshalflings-regular.svg +175 -0
  63. package/static/assets/fonts/glyphiconshalflings-regular.ttf +0 -0
  64. package/static/assets/fonts/glyphiconshalflings-regular.woff +0 -0
  65. package/static/assets/ico/apple-touch-icon-114-precomposed.png +0 -0
  66. package/static/assets/ico/apple-touch-icon-144-precomposed.png +0 -0
  67. package/static/assets/ico/apple-touch-icon-57-precomposed.png +0 -0
  68. package/static/assets/ico/apple-touch-icon-72-precomposed.png +0 -0
  69. package/static/assets/ico/favicon.ico +0 -0
  70. package/static/assets/ico/favicon.png +0 -0
  71. package/static/assets/images/fhir-logo-www.png +0 -0
  72. package/static/assets/images/fhir-logo.png +0 -0
  73. package/static/assets/images/hl7-logo.png +0 -0
  74. package/static/assets/images/logo_ansinew.jpg +0 -0
  75. package/static/assets/images/search.png +0 -0
  76. package/static/assets/images/stripe.png +0 -0
  77. package/static/assets/images/target.png +0 -0
  78. package/static/assets/images/tx-registry-root.gif +0 -0
  79. package/static/assets/images/tx-registry.png +0 -0
  80. package/static/assets/images/tx-server.png +0 -0
  81. package/static/assets/images/tx-version.png +0 -0
  82. package/static/assets/js/bootstrap.min.js +6 -0
  83. package/static/assets/js/fhir-gw.js +259 -0
  84. package/static/assets/js/fhir.js +2 -0
  85. package/static/assets/js/html5shiv.js +8 -0
  86. package/static/assets/js/jcookie.js +96 -0
  87. package/static/assets/js/jquery-ui.min.js +6 -0
  88. package/static/assets/js/jquery.js +10716 -0
  89. package/static/assets/js/jquery.min.js +2 -0
  90. package/static/assets/js/jquery.ui.core.js +314 -0
  91. package/static/assets/js/jquery.ui.draggable.js +825 -0
  92. package/static/assets/js/jquery.ui.mouse.js +162 -0
  93. package/static/assets/js/jquery.ui.resizable.js +842 -0
  94. package/static/assets/js/jquery.ui.widget.js +268 -0
  95. package/static/assets/js/json2.js +487 -0
  96. package/static/assets/js/jtip.js +97 -0
  97. package/static/assets/js/respond.min.js +6 -0
  98. package/static/assets/js/statuspage.js +70 -0
  99. package/static/assets/js/xml.js +2 -0
  100. package/static/dist/js/bootstrap.js +1964 -0
  101. package/static/favicon.png +0 -0
  102. package/static/fhir.css +626 -0
  103. package/static/icon-fhir-16.png +0 -0
  104. package/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  105. package/static/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  106. package/static/images/ui-bg_flat_10_000000_40x100.png +0 -0
  107. package/static/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  108. package/static/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  109. package/static/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  110. package/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  111. package/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  112. package/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  113. package/static/images/ui-icons_222222_256x240.png +0 -0
  114. package/static/images/ui-icons_228ef1_256x240.png +0 -0
  115. package/static/images/ui-icons_ef8c08_256x240.png +0 -0
  116. package/static/images/ui-icons_ffd27a_256x240.png +0 -0
  117. package/static/images/ui-icons_ffffff_256x240.png +0 -0
  118. package/static/js/jquery.effects.blind.js +49 -0
  119. package/static/js/jquery.effects.bounce.js +78 -0
  120. package/static/js/jquery.effects.clip.js +54 -0
  121. package/static/js/jquery.effects.core.js +763 -0
  122. package/static/js/jquery.effects.drop.js +50 -0
  123. package/static/js/jquery.effects.explode.js +79 -0
  124. package/static/js/jquery.effects.fade.js +32 -0
  125. package/static/js/jquery.effects.fold.js +56 -0
  126. package/static/js/jquery.effects.highlight.js +50 -0
  127. package/static/js/jquery.effects.pulsate.js +51 -0
  128. package/static/js/jquery.effects.scale.js +178 -0
  129. package/static/js/jquery.effects.shake.js +57 -0
  130. package/static/js/jquery.effects.slide.js +50 -0
  131. package/static/js/jquery.effects.transfer.js +45 -0
  132. package/static/js/jquery.ui.accordion.js +611 -0
  133. package/static/js/jquery.ui.autocomplete.js +612 -0
  134. package/static/js/jquery.ui.button.js +416 -0
  135. package/static/js/jquery.ui.datepicker.js +1823 -0
  136. package/static/js/jquery.ui.dialog.js +878 -0
  137. package/static/js/jquery.ui.droppable.js +296 -0
  138. package/static/js/jquery.ui.position.js +252 -0
  139. package/static/js/jquery.ui.progressbar.js +109 -0
  140. package/static/js/jquery.ui.selectable.js +266 -0
  141. package/static/js/jquery.ui.slider.js +666 -0
  142. package/static/js/jquery.ui.sortable.js +1077 -0
  143. package/static/js/jquery.ui.tabs.js +758 -0
  144. package/stats.js +80 -0
  145. package/test-cache/vsac/vsac-valuesets.db +0 -0
  146. package/token/nginx_passport_setup.md +383 -0
  147. package/token/security_guide.md +294 -0
  148. package/token/token-template.html +330 -0
  149. package/token/token.js +1300 -0
  150. package/translations/Messages.properties +1510 -0
  151. package/translations/Messages_ar.properties +1399 -0
  152. package/translations/Messages_de.properties +836 -0
  153. package/translations/Messages_es.properties +737 -0
  154. package/translations/Messages_fr.properties +1 -0
  155. package/translations/Messages_ja.properties +893 -0
  156. package/translations/Messages_nl.properties +1357 -0
  157. package/translations/Messages_pt.properties +1302 -0
  158. package/translations/Messages_ru.properties +1 -0
  159. package/translations/Messages_uz.properties +1 -0
  160. package/translations/Messages_zh.properties +1 -0
  161. package/translations/rendering-phrases.properties +1128 -0
  162. package/translations/rendering-phrases_ar.properties +1091 -0
  163. package/translations/rendering-phrases_de.properties +6 -0
  164. package/translations/rendering-phrases_es.properties +6 -0
  165. package/translations/rendering-phrases_fr.properties +624 -0
  166. package/translations/rendering-phrases_ja.properties +21 -0
  167. package/translations/rendering-phrases_nl.properties +970 -0
  168. package/translations/rendering-phrases_pt.properties +1020 -0
  169. package/translations/rendering-phrases_ru.properties +1094 -0
  170. package/translations/rendering-phrases_uz.properties +1 -0
  171. package/translations/rendering-phrases_zh.properties +1 -0
  172. package/tx/README.md +418 -0
  173. package/tx/cm/cm-api.js +110 -0
  174. package/tx/cm/cm-database.js +735 -0
  175. package/tx/cm/cm-package.js +325 -0
  176. package/tx/cs/cs-api.js +789 -0
  177. package/tx/cs/cs-areacode.js +615 -0
  178. package/tx/cs/cs-country.js +1110 -0
  179. package/tx/cs/cs-cpt.js +785 -0
  180. package/tx/cs/cs-cs.js +1579 -0
  181. package/tx/cs/cs-currency.js +539 -0
  182. package/tx/cs/cs-db.js +1321 -0
  183. package/tx/cs/cs-hgvs.js +329 -0
  184. package/tx/cs/cs-lang.js +465 -0
  185. package/tx/cs/cs-loinc.js +1485 -0
  186. package/tx/cs/cs-mimetypes.js +238 -0
  187. package/tx/cs/cs-ndc.js +704 -0
  188. package/tx/cs/cs-omop.js +1025 -0
  189. package/tx/cs/cs-provider-api.js +43 -0
  190. package/tx/cs/cs-provider-list.js +37 -0
  191. package/tx/cs/cs-rxnorm.js +808 -0
  192. package/tx/cs/cs-snomed.js +1102 -0
  193. package/tx/cs/cs-ucum.js +514 -0
  194. package/tx/cs/cs-unii.js +271 -0
  195. package/tx/cs/cs-uri.js +218 -0
  196. package/tx/cs/cs-usstates.js +305 -0
  197. package/tx/dev.fhir.org.yml +14 -0
  198. package/tx/fixtures/test-cases-setup.json +18 -0
  199. package/tx/fixtures/test-cases.yml +16 -0
  200. package/tx/html/codesystem-operations.liquid +25 -0
  201. package/tx/html/home-metrics.liquid +247 -0
  202. package/tx/html/operations-form.liquid +148 -0
  203. package/tx/html/search-form.liquid +62 -0
  204. package/tx/html/tx-template.html +133 -0
  205. package/tx/html/valueset-operations.liquid +54 -0
  206. package/tx/importers/atc-to-fhir.js +316 -0
  207. package/tx/importers/import-loinc.module.js +1536 -0
  208. package/tx/importers/import-ndc.module.js +1088 -0
  209. package/tx/importers/import-rxnorm.module.js +898 -0
  210. package/tx/importers/import-sct.module.js +2457 -0
  211. package/tx/importers/import-unii.module.js +601 -0
  212. package/tx/importers/readme.md +453 -0
  213. package/tx/importers/subset-loinc.module.js +1081 -0
  214. package/tx/importers/subset-rxnorm.module.js +938 -0
  215. package/tx/importers/tx-import-base.js +351 -0
  216. package/tx/importers/tx-import-settings.js +310 -0
  217. package/tx/importers/tx-import.js +357 -0
  218. package/tx/library/canonical-resource.js +88 -0
  219. package/tx/library/capabilitystatement.js +292 -0
  220. package/tx/library/codesystem.js +774 -0
  221. package/tx/library/conceptmap.js +568 -0
  222. package/tx/library/designations.js +932 -0
  223. package/tx/library/errors.js +77 -0
  224. package/tx/library/extensions.js +117 -0
  225. package/tx/library/namingsystem.js +322 -0
  226. package/tx/library/operation-outcome.js +127 -0
  227. package/tx/library/parameters.js +105 -0
  228. package/tx/library/renderer.js +1559 -0
  229. package/tx/library/terminologycapabilities.js +418 -0
  230. package/tx/library/ucum-parsers.js +1029 -0
  231. package/tx/library/ucum-service.js +370 -0
  232. package/tx/library/ucum-types.js +1099 -0
  233. package/tx/library/valueset.js +543 -0
  234. package/tx/library.js +676 -0
  235. package/tx/ocl/cm-ocl.js +106 -0
  236. package/tx/ocl/cs-ocl.js +39 -0
  237. package/tx/ocl/vs-ocl.js +105 -0
  238. package/tx/operation-context.js +568 -0
  239. package/tx/params.js +613 -0
  240. package/tx/provider.js +403 -0
  241. package/tx/sct/ecl.js +1560 -0
  242. package/tx/sct/expressions.js +2077 -0
  243. package/tx/sct/structures.js +1396 -0
  244. package/tx/tx-html.js +1063 -0
  245. package/tx/tx.fhir.org.yml +39 -0
  246. package/tx/tx.js +927 -0
  247. package/tx/vs/vs-api.js +112 -0
  248. package/tx/vs/vs-database.js +786 -0
  249. package/tx/vs/vs-package.js +358 -0
  250. package/tx/vs/vs-vsac.js +366 -0
  251. package/tx/workers/batch-validate.js +129 -0
  252. package/tx/workers/batch.js +361 -0
  253. package/tx/workers/closure.js +32 -0
  254. package/tx/workers/expand.js +1845 -0
  255. package/tx/workers/lookup.js +407 -0
  256. package/tx/workers/metadata.js +467 -0
  257. package/tx/workers/operations.js +34 -0
  258. package/tx/workers/read.js +164 -0
  259. package/tx/workers/search.js +384 -0
  260. package/tx/workers/subsumes.js +334 -0
  261. package/tx/workers/translate.js +492 -0
  262. package/tx/workers/validate.js +2504 -0
  263. package/tx/workers/worker.js +904 -0
  264. package/tx/xml/capabilitystatement-xml.js +63 -0
  265. package/tx/xml/codesystem-xml.js +62 -0
  266. package/tx/xml/conceptmap-xml.js +65 -0
  267. package/tx/xml/namingsystem-xml.js +65 -0
  268. package/tx/xml/operationoutcome-xml.js +127 -0
  269. package/tx/xml/parameters-xml.js +312 -0
  270. package/tx/xml/terminologycapabilities-xml.js +64 -0
  271. package/tx/xml/valueset-xml.js +64 -0
  272. package/tx/xml/xml-base.js +603 -0
  273. package/vcl/vcl-parser.js +1098 -0
  274. package/vcl/vcl.js +253 -0
  275. package/windows-install.js +19 -0
  276. package/xig/xig-template.html +124 -0
  277. package/xig/xig.js +3049 -0
@@ -0,0 +1,325 @@
1
+ const path = require('path');
2
+ const { AbstractConceptMapProvider } = require('./cm-api');
3
+ const { PackageContentLoader } = require('../../library/package-manager');
4
+ const { ConceptMapDatabase } = require('./cm-database');
5
+ const { VersionUtilities } = require('../../library/version-utilities');
6
+ const {validateParameter} = require("../../library/utilities");
7
+ const {ConceptMap} = require("../library/conceptmap");
8
+
9
+ /**
10
+ * Package-based ConceptMap provider using shared database layer
11
+ */
12
+ class PackageConceptMapProvider extends AbstractConceptMapProvider {
13
+ USE_DATABASE_SEARCH = true;
14
+
15
+ /**
16
+ * @param {PackageContentLoader} packageLoader - Path to the extracted package folder
17
+ */
18
+ constructor(packageLoader) {
19
+ super();
20
+ validateParameter(packageLoader, "packageLoader", PackageContentLoader);
21
+ this.packageLoader = packageLoader;
22
+ this.dbPath = path.join(packageLoader.packageFolder, '.conceptmaps.db');
23
+ this.database = new ConceptMapDatabase(this.dbPath);
24
+ this.conceptMapMap = new Map();
25
+ this.initialized = false;
26
+ this.count = 0;
27
+ }
28
+
29
+ /**
30
+ * Initialize the provider - check/create database and load concept maps into memory
31
+ * @returns {Promise<void>}
32
+ */
33
+ async initialize() {
34
+ if (this.initialized) {
35
+ return;
36
+ }
37
+
38
+ const dbExists = await this.database.exists();
39
+
40
+ if (!dbExists) {
41
+ await this.database.create();
42
+ await this._populateDatabase();
43
+ }
44
+
45
+ this.conceptMapMap = await this.database.loadAllConceptMaps();
46
+ this.initialized = true;
47
+ }
48
+
49
+ /**
50
+ * Populate the database with concept maps from the package
51
+ * @returns {Promise<void>}
52
+ * @private
53
+ */
54
+ async _populateDatabase() {
55
+ // Get all ConceptMap resources
56
+ const conceptMapEntries = await this.packageLoader.getResourcesByType('ConceptMap');
57
+
58
+ if (conceptMapEntries.length === 0) {
59
+ return; // No concept maps in this package
60
+ }
61
+
62
+ const conceptMaps = [];
63
+ for (const entry of conceptMapEntries) {
64
+ const conceptMap = await this.packageLoader.loadFile(entry);
65
+ if (conceptMap.url) {
66
+ conceptMaps.push(new ConceptMap(conceptMap, this.packageLoader.fhirVersion())); // get in converted to R5 format
67
+ }
68
+ }
69
+
70
+ if (conceptMaps.length > 0) {
71
+ await this.database.batchUpsertConceptMaps(conceptMaps);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Fetches a concept map by URL and version
77
+ * @param {string} url - The canonical URL of the concept map
78
+ * @param {string} version - The version of the concept map
79
+ * @returns {Promise<Object>} The requested concept map
80
+ */
81
+ async fetchConceptMap(url, version) {
82
+ await this.initialize();
83
+ this._validateFetchParams(url, version);
84
+
85
+ // Try exact match first: url|version
86
+ let key = `${url}|${version}`;
87
+ if (this.conceptMapMap.has(key)) {
88
+ return this.conceptMapMap.get(key);
89
+ }
90
+
91
+ // If version is semver, try url|major.minor
92
+ try {
93
+ if (VersionUtilities.isSemVer(version)) {
94
+ const majorMinor = VersionUtilities.getMajMin(version);
95
+ if (majorMinor) {
96
+ key = `${url}|${majorMinor}`;
97
+ if (this.conceptMapMap.has(key)) {
98
+ return this.conceptMapMap.get(key);
99
+ }
100
+ }
101
+ }
102
+ } catch (error) {
103
+ // Ignore version parsing errors
104
+ }
105
+
106
+ // Finally try just the URL
107
+ if (this.conceptMapMap.has(url)) {
108
+ return this.conceptMapMap.get(url);
109
+ }
110
+
111
+ return null;
112
+ }
113
+
114
+ /**
115
+ * Searches for concept maps based on criteria
116
+ * @param {Array<{name: string, value: string}>} searchParams - Search criteria
117
+ * @returns {Promise<Array<Object>>} List of matching concept maps
118
+ */
119
+ async searchConceptMaps(searchParams, elements = null) {
120
+ await this.initialize();
121
+ this._validateSearchParams(searchParams);
122
+
123
+ if (this.USE_DATABASE_SEARCH) {
124
+ return await this.database.search(this.spaceId, searchParams, elements);
125
+ } else {
126
+ const matches = [];
127
+ const seen = new Set(); // Track by URL to avoid duplicates from versioned keys
128
+
129
+ // Convert array format to object for easier access
130
+ const params = {};
131
+ for (const {name, value} of searchParams) {
132
+ params[name] = value.toLowerCase();
133
+ }
134
+
135
+ const hasSearchParams = Object.keys(params).length > 0;
136
+
137
+ for (const vs of this.conceptMapMap.values()) {
138
+ const json = vs.jsonObj || vs;
139
+
140
+ // Only process each ConceptMap once (use URL to deduplicate)
141
+ const vsUrl = json.url;
142
+ if (seen.has(vsUrl)) {
143
+ continue;
144
+ }
145
+
146
+ if (!hasSearchParams) {
147
+ seen.add(vsUrl);
148
+ matches.push(vs);
149
+ continue;
150
+ }
151
+
152
+ // Check each search parameter
153
+ let isMatch = true;
154
+ for (const [param, searchValue] of Object.entries(params)) {
155
+ // Ignore content-mode and supplements for ConceptMap search
156
+ if (param === 'content-mode' || param === 'supplements') {
157
+ continue;
158
+ }
159
+
160
+ if (param === 'system') {
161
+ // Special handling: match against compose.include[].system
162
+ if (!this._matchSystem(json, searchValue)) {
163
+ isMatch = false;
164
+ break;
165
+ }
166
+ } else if (param === 'jurisdiction') {
167
+ // Special handling for jurisdiction - array of CodeableConcept
168
+ if (!this._matchJurisdiction(json.jurisdiction, searchValue)) {
169
+ isMatch = false;
170
+ break;
171
+ }
172
+ } else if (param === 'identifier') {
173
+ // Special handling for identifier
174
+ if (!this._matchIdentifier(json.identifier, searchValue)) {
175
+ isMatch = false;
176
+ break;
177
+ }
178
+ } else {
179
+ // Standard partial text match on property
180
+ const propValue = json[param];
181
+ if (!this._matchValue(propValue, searchValue)) {
182
+ isMatch = false;
183
+ break;
184
+ }
185
+ }
186
+ }
187
+
188
+ if (isMatch) {
189
+ seen.add(vsUrl);
190
+ // Return with prefixed id
191
+ const result = { ...json, id: `${this.spaceId}-${json.id}` };
192
+ matches.push(result);
193
+ }
194
+ }
195
+
196
+ return matches;
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Check if a value matches the search term (partial, case-insensitive)
202
+ */
203
+ _matchValue(propValue, searchValue) {
204
+ if (propValue === undefined || propValue === null) {
205
+ return false;
206
+ }
207
+ const strValue = String(propValue).toLowerCase();
208
+ return strValue.includes(searchValue);
209
+ }
210
+
211
+ /**
212
+ * Check if system matches any compose.include[].system
213
+ */
214
+ _matchSystem(json, searchValue) {
215
+ if (!json.compose?.include || !Array.isArray(json.compose.include)) {
216
+ return false;
217
+ }
218
+ for (const include of json.compose.include) {
219
+ if (include.system && include.system.toLowerCase().includes(searchValue)) {
220
+ return true;
221
+ }
222
+ }
223
+ return false;
224
+ }
225
+
226
+ /**
227
+ * Check if jurisdiction matches - jurisdiction is an array of CodeableConcept
228
+ */
229
+ _matchJurisdiction(jurisdictions, searchValue) {
230
+ if (!jurisdictions || !Array.isArray(jurisdictions)) {
231
+ return false;
232
+ }
233
+ for (const cc of jurisdictions) {
234
+ if (cc.coding && Array.isArray(cc.coding)) {
235
+ for (const coding of cc.coding) {
236
+ if (coding.code && coding.code.toLowerCase().includes(searchValue)) {
237
+ return true;
238
+ }
239
+ if (coding.display && coding.display.toLowerCase().includes(searchValue)) {
240
+ return true;
241
+ }
242
+ }
243
+ }
244
+ if (cc.text && cc.text.toLowerCase().includes(searchValue)) {
245
+ return true;
246
+ }
247
+ }
248
+ return false;
249
+ }
250
+
251
+ /**
252
+ * Check if identifier matches
253
+ */
254
+ _matchIdentifier(identifiers, searchValue) {
255
+ if (!identifiers) {
256
+ return false;
257
+ }
258
+ const idArray = Array.isArray(identifiers) ? identifiers : [identifiers];
259
+ for (const id of idArray) {
260
+ if (id.system && id.system.toLowerCase().includes(searchValue)) {
261
+ return true;
262
+ }
263
+ if (id.value && id.value.toLowerCase().includes(searchValue)) {
264
+ return true;
265
+ }
266
+ }
267
+ return false;
268
+ }
269
+
270
+ /**
271
+ * Get statistics about the loaded concept maps
272
+ * @returns {Promise<Object>} Statistics object
273
+ */
274
+ async getStatistics() {
275
+ await this.initialize();
276
+ return await this.database.getStatistics();
277
+ }
278
+
279
+ /**
280
+ * Get the number of concept maps loaded into memory
281
+ * @returns {number} Number of unique concept maps in map
282
+ */
283
+ getMapSize() {
284
+ const uniqueUrls = new Set();
285
+ for (const [key, conceptMap] of this.conceptMapMap.entries()) {
286
+ if (!key.includes('|')) { // Only count base URL keys
287
+ uniqueUrls.add(conceptMap.url);
288
+ }
289
+ }
290
+ return uniqueUrls.size;
291
+ }
292
+
293
+ async fetchConceptMapById(id) {
294
+ if (!this.spaceId) {
295
+ return this.conceptMapMap.get(id);
296
+ } else if (id.startsWith(this.spaceId+"-")) {
297
+ let key = id.substring(this.spaceId.length + 1);
298
+ return this.conceptMapMap.get(key);
299
+ } else {
300
+ return null;
301
+ }
302
+ }
303
+
304
+ // eslint-disable-next-line no-unused-vars
305
+ assignIds(ids) {
306
+ // nothing - we don't do any assigning.
307
+ }
308
+
309
+ async findConceptMapForTranslation(opContext, conceptMaps, sourceSystem, sourceScope, targetScope, targetSystem) {
310
+ for (let cm of this.conceptMapMap.values()) {
311
+ if (cm.providesTranslation(sourceSystem, sourceScope, targetScope, targetSystem)) {
312
+ conceptMaps.push(cm);
313
+ }
314
+ }
315
+ }
316
+
317
+ cmCount() {
318
+ return this.database.cmCount;
319
+ }
320
+
321
+ }
322
+
323
+ module.exports = {
324
+ PackageConceptMapProvider
325
+ };