reflex-icd11ect 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,105 @@
1
+ """Reflex custom component for the WHO ICD-11 Embedded Classification Tools.
2
+
3
+ Wraps `@whoicd/icd11ect <https://www.npmjs.com/package/@whoicd/icd11ect>`_,
4
+ the WHO's Embedded Coding Tool and Embedded Browser, powered by the ICD-API.
5
+
6
+ Quick start::
7
+
8
+ import reflex as rx
9
+ from reflex_icd11ect import icd11ect
10
+
11
+ class State(rx.State):
12
+ code: str = ""
13
+
14
+ @rx.event
15
+ def on_select(self, entity: dict[str, str]):
16
+ self.code = entity["code"]
17
+
18
+ def index():
19
+ return rx.vstack(
20
+ rx.text(State.code),
21
+ icd11ect.coding_tool(
22
+ api_server_url="https://id.who.int",
23
+ api_secured=True,
24
+ token=State.token,
25
+ on_select=State.on_select,
26
+ ),
27
+ )
28
+ """
29
+
30
+ from reflex_icd11ect import constants, handler, token
31
+ from reflex_icd11ect.constants import (
32
+ ALL_SETTINGS,
33
+ BROWSER_SETTINGS,
34
+ CODING_TOOL_SETTINGS,
35
+ COMMON_SETTINGS,
36
+ ECT_PACKAGE,
37
+ ECT_STYLESHEET,
38
+ ECT_VERSION,
39
+ ICD_TOKEN_ENDPOINT,
40
+ ICD_TOKEN_SCOPE,
41
+ LANGUAGES,
42
+ MMS_CHAPTERS,
43
+ OVERWRITABLE_SETTINGS,
44
+ RTL_LANGUAGES,
45
+ SELECT_BUTTON_MODES,
46
+ SOURCES,
47
+ WHO_CLOUD_API,
48
+ WHO_DEVELOPER_TEST_API,
49
+ )
50
+ from reflex_icd11ect.icd11ect import (
51
+ Icd11ectBrowser,
52
+ Icd11ectCodingTool,
53
+ Icd11ectController,
54
+ browser_window,
55
+ icd11ect_browser,
56
+ icd11ect_coding_tool,
57
+ icd11ect_controller,
58
+ icd11ect_provider,
59
+ result_window,
60
+ search_input,
61
+ )
62
+ from reflex_icd11ect.namespace import icd11ect
63
+ from reflex_icd11ect.token import IcdTokenError, IcdTokenProvider
64
+ from reflex_icd11ect.types import BrowserContent, SelectedEntity
65
+
66
+ __version__ = "0.1.0"
67
+
68
+ __all__ = [
69
+ "ALL_SETTINGS",
70
+ "BROWSER_SETTINGS",
71
+ "CODING_TOOL_SETTINGS",
72
+ "COMMON_SETTINGS",
73
+ "ECT_PACKAGE",
74
+ "ECT_STYLESHEET",
75
+ "ECT_VERSION",
76
+ "ICD_TOKEN_ENDPOINT",
77
+ "ICD_TOKEN_SCOPE",
78
+ "LANGUAGES",
79
+ "MMS_CHAPTERS",
80
+ "OVERWRITABLE_SETTINGS",
81
+ "RTL_LANGUAGES",
82
+ "SELECT_BUTTON_MODES",
83
+ "SOURCES",
84
+ "WHO_CLOUD_API",
85
+ "WHO_DEVELOPER_TEST_API",
86
+ "BrowserContent",
87
+ "Icd11ectBrowser",
88
+ "Icd11ectCodingTool",
89
+ "Icd11ectController",
90
+ "IcdTokenError",
91
+ "IcdTokenProvider",
92
+ "SelectedEntity",
93
+ "__version__",
94
+ "browser_window",
95
+ "constants",
96
+ "handler",
97
+ "icd11ect",
98
+ "icd11ect_browser",
99
+ "icd11ect_coding_tool",
100
+ "icd11ect_controller",
101
+ "icd11ect_provider",
102
+ "result_window",
103
+ "search_input",
104
+ "token",
105
+ ]
@@ -0,0 +1,291 @@
1
+ """The JavaScript runtime that bridges ECT to Reflex.
2
+
3
+ ``@whoicd/icd11ect`` is not a React component: it is an imperative library
4
+ that renders itself into DOM nodes carrying ``data-ctw-ino`` attributes, and
5
+ it keeps a single global configuration plus a single set of callbacks for the
6
+ whole page.
7
+
8
+ This module holds the JavaScript that reconciles that model with Reflex:
9
+
10
+ * a page level singleton (``window.__reflexIcd11ect``) that owns the ECT
11
+ configuration and routes ECT's global callbacks to the right component
12
+ instance, keyed by ``iNo``;
13
+ * ``useIcd11ect``, the hook each component emits, which registers the
14
+ instance, configures ECT once, applies the per instance overrides and binds
15
+ the tool after the DOM has been committed (``autoBind`` is always disabled,
16
+ because ECT's auto binding listens for ``window.onload``, an event that has
17
+ long fired by the time a single page app renders a route);
18
+ * OAUTH 2.0 token plumbing: either a token endpoint fetched from the browser,
19
+ or a round trip to the Reflex backend through the ``on_token_request``
20
+ event.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import json
26
+
27
+ from reflex_icd11ect.constants import OVERWRITABLE_SETTINGS
28
+
29
+ _RUNTIME_TEMPLATE = r"""
30
+ /* reflex-icd11ect runtime. Bridges the imperative @whoicd/icd11ect API to Reflex. */
31
+ const ICD11ECT_OVERWRITABLE = __OVERWRITABLE__;
32
+
33
+ const icd11ectRuntime = () => {
34
+ if (typeof window === "undefined") return null;
35
+ let rt = window.__reflexIcd11ect;
36
+ if (!rt) {
37
+ rt = window.__reflexIcd11ect = {
38
+ instances: {},
39
+ globalSettings: {},
40
+ globalSettingsKey: "",
41
+ configured: false,
42
+ verbose: false,
43
+ token: null,
44
+ tokenVersion: 0,
45
+ tokenAsks: 0,
46
+ tokenConfig: {},
47
+ tokenWaiters: [],
48
+ lastIno: null,
49
+ };
50
+ }
51
+ rt.ECT = ECT;
52
+ /* Exposed on the singleton so `rx.call_script` helpers can reach them. */
53
+ rt.setToken = icd11ectSetToken;
54
+ rt.callbacks = icd11ectCallbacks;
55
+ return rt;
56
+ };
57
+
58
+ const icd11ectLog = (...args) => {
59
+ const rt = icd11ectRuntime();
60
+ if (rt && rt.verbose) console.log("[reflex-icd11ect]", ...args);
61
+ };
62
+
63
+ const icd11ectSetToken = (token) => {
64
+ const rt = icd11ectRuntime();
65
+ if (!rt || !token || token === rt.token) return;
66
+ rt.token = token;
67
+ rt.tokenVersion += 1;
68
+ const waiters = rt.tokenWaiters;
69
+ rt.tokenWaiters = [];
70
+ waiters.forEach((resolve) => resolve(token));
71
+ icd11ectLog("token updated, version", rt.tokenVersion);
72
+ };
73
+
74
+ const icd11ectWaitForToken = (rt, timeoutMs) =>
75
+ new Promise((resolve) => {
76
+ let settled = false;
77
+ const finish = (value) => {
78
+ if (settled) return;
79
+ settled = true;
80
+ resolve(value || "");
81
+ };
82
+ const timer = setTimeout(() => finish(rt.token), timeoutMs);
83
+ rt.tokenWaiters.push((token) => {
84
+ clearTimeout(timer);
85
+ finish(token);
86
+ });
87
+ });
88
+
89
+ const icd11ectDispatch = (iNo, name, ...args) => {
90
+ const rt = icd11ectRuntime();
91
+ if (!rt) return;
92
+ if (iNo === null || iNo === undefined || iNo === "") {
93
+ Object.keys(rt.instances).forEach((key) => icd11ectDispatch(key, name, ...args));
94
+ return;
95
+ }
96
+ const instance = rt.instances[String(iNo)];
97
+ const handler =
98
+ instance && instance.callbacks && instance.callbacks.current
99
+ ? instance.callbacks.current[name]
100
+ : undefined;
101
+ if (handler) handler(...args);
102
+ };
103
+
104
+ /* ECT does not tell us which instance started or ended a search, so fall back
105
+ to the focused search box, then to the instance that last emitted. */
106
+ const icd11ectActiveIno = () => {
107
+ const rt = icd11ectRuntime();
108
+ if (!rt) return null;
109
+ if (typeof document !== "undefined") {
110
+ const active = document.activeElement;
111
+ if (active && active.classList && active.classList.contains("ctw-input")) {
112
+ const iNo = active.getAttribute("data-ctw-ino");
113
+ if (iNo) return iNo;
114
+ }
115
+ }
116
+ return rt.lastIno;
117
+ };
118
+
119
+ const icd11ectCallbacks = {
120
+ selectedEntityFunction: (selectedEntity) => {
121
+ const rt = icd11ectRuntime();
122
+ if (rt && selectedEntity) rt.lastIno = String(selectedEntity.iNo);
123
+ icd11ectDispatch(selectedEntity && selectedEntity.iNo, "onSelect", selectedEntity);
124
+ },
125
+ browserChangedFunction: (browserContent) => {
126
+ icd11ectDispatch(
127
+ browserContent && browserContent.iNo,
128
+ "onBrowserChange",
129
+ browserContent,
130
+ );
131
+ },
132
+ browserLoadedFunction: () => icd11ectDispatch(null, "onBrowserLoad"),
133
+ searchStartedFunction: () => icd11ectDispatch(icd11ectActiveIno(), "onSearchStart"),
134
+ searchEndedFunction: () => icd11ectDispatch(icd11ectActiveIno(), "onSearchEnd"),
135
+ getNewTokenFunction: async () => {
136
+ const rt = icd11ectRuntime();
137
+ if (!rt) return "";
138
+ const config = rt.tokenConfig || {};
139
+ rt.tokenAsks += 1;
140
+ if (config.endpoint) {
141
+ try {
142
+ const response = await fetch(config.endpoint, config.fetchOptions || {});
143
+ const payload = await response.json();
144
+ const token =
145
+ typeof payload === "string"
146
+ ? payload
147
+ : payload[config.field || "token"] || payload.access_token;
148
+ icd11ectSetToken(token);
149
+ return token || "";
150
+ } catch (error) {
151
+ console.error(
152
+ "[reflex-icd11ect] could not fetch an ICD-API token from " + config.endpoint,
153
+ error,
154
+ );
155
+ return rt.token || "";
156
+ }
157
+ }
158
+ /* The token handed over by the backend is still the fresh one on the
159
+ first request, ECT only asks again once it has expired. */
160
+ if (rt.token && rt.tokenAsks === 1) return rt.token;
161
+ const known = rt.tokenVersion;
162
+ icd11ectDispatch(null, "onTokenRequest");
163
+ if (rt.tokenVersion !== known) return rt.token || "";
164
+ const token = await icd11ectWaitForToken(rt, config.timeoutMs || 15000);
165
+ if (!token) {
166
+ console.error(
167
+ "[reflex-icd11ect] the ICD-API is configured with api_secured=True but no " +
168
+ "token was provided. Set the `token` prop, handle `on_token_request`, " +
169
+ "or set `token_endpoint`.",
170
+ );
171
+ }
172
+ return token;
173
+ },
174
+ };
175
+
176
+ /* A prop bound to state can legitimately be empty; treat that as "not set" so
177
+ ECT keeps its own default instead of receiving an empty setting. */
178
+ const icd11ectClean = (settings) =>
179
+ Object.fromEntries(
180
+ Object.entries(settings || {}).filter(
181
+ ([, value]) => value !== undefined && value !== null && value !== "",
182
+ ),
183
+ );
184
+
185
+ const icd11ectConfigure = (rt) => {
186
+ const settings = rt.globalSettings || {};
187
+ if (!settings.apiServerUrl) {
188
+ icd11ectLog("waiting for api_server_url before configuring ECT");
189
+ return false;
190
+ }
191
+ const key = JSON.stringify(settings);
192
+ if (rt.configured && rt.globalSettingsKey === key) return true;
193
+ rt.ECT.Handler.configure({ ...settings, autoBind: false }, icd11ectCallbacks);
194
+ rt.configured = true;
195
+ rt.globalSettingsKey = key;
196
+ icd11ectLog("ECT configured", settings);
197
+ return true;
198
+ };
199
+
200
+ /* Only the settings ECT can override per instance are worth sending, and only
201
+ when they differ from the page wide configuration. */
202
+ const icd11ectApplyInstance = (rt, iNo, settings) => {
203
+ const overrides = {};
204
+ ICD11ECT_OVERWRITABLE.forEach((key) => {
205
+ const value = settings[key];
206
+ if (value !== undefined && JSON.stringify(value) !== JSON.stringify(rt.globalSettings[key])) {
207
+ overrides[key] = value;
208
+ }
209
+ });
210
+ if (Object.keys(overrides).length === 0) return;
211
+ icd11ectLog("overwriteConfiguration", iNo, overrides);
212
+ rt.ECT.Handler.overwriteConfiguration(String(iNo), overrides, true);
213
+ };
214
+
215
+ const icd11ectBind = (rt, iNo) => {
216
+ icd11ectLog("bind", iNo);
217
+ rt.ECT.Handler.bind(String(iNo));
218
+ };
219
+
220
+ const icd11ectBindAll = (rt) => {
221
+ Object.keys(rt.instances).forEach((iNo) => {
222
+ icd11ectApplyInstance(rt, iNo, rt.instances[iNo].settings || {});
223
+ icd11ectBind(rt, iNo);
224
+ });
225
+ };
226
+
227
+ /* Registers one Coding Tool / Embedded Browser instance and keeps ECT in sync
228
+ with its props. */
229
+ const useIcd11ect = (iNo, settings, callbacks, options) => {
230
+ const key = String(iNo);
231
+ const opts = options || {};
232
+ const callbacksRef = useRef(callbacks);
233
+ callbacksRef.current = callbacks;
234
+ const cleanSettings = icd11ectClean(settings);
235
+ const settingsKey = JSON.stringify(cleanSettings);
236
+ const token = opts.token;
237
+ const tokenEndpoint = opts.tokenEndpoint;
238
+ const tokenField = opts.tokenField;
239
+ const tokenTimeout = opts.tokenTimeoutMs;
240
+ const verbose = opts.verbose;
241
+
242
+ useEffect(() => {
243
+ const rt = icd11ectRuntime();
244
+ if (!rt) return;
245
+ if (verbose) rt.verbose = true;
246
+ if (tokenEndpoint || tokenField || tokenTimeout) {
247
+ rt.tokenConfig = {
248
+ ...rt.tokenConfig,
249
+ endpoint: tokenEndpoint,
250
+ field: tokenField,
251
+ timeoutMs: tokenTimeout,
252
+ };
253
+ }
254
+ }, [tokenEndpoint, tokenField, tokenTimeout, verbose]);
255
+
256
+ useEffect(() => {
257
+ if (token) icd11ectSetToken(token);
258
+ }, [token]);
259
+
260
+ useEffect(() => {
261
+ const rt = icd11ectRuntime();
262
+ if (!rt) return undefined;
263
+ rt.instances[key] = { callbacks: callbacksRef, settings: cleanSettings, kind: opts.kind };
264
+ /* Page wide configuration is the merge of every mounted instance, so an
265
+ unmounted one stops contributing. */
266
+ rt.globalSettings = Object.keys(rt.instances).reduce(
267
+ (merged, instanceKey) => ({ ...merged, ...(rt.instances[instanceKey].settings || {}) }),
268
+ {},
269
+ );
270
+ const needsConfigure =
271
+ !rt.configured || rt.globalSettingsKey !== JSON.stringify(rt.globalSettings);
272
+ const cleanup = () => {
273
+ delete rt.instances[key];
274
+ };
275
+ if (!icd11ectConfigure(rt)) return cleanup;
276
+ if (needsConfigure) {
277
+ /* configure() resets every search box on the page, rebind them all. */
278
+ icd11ectBindAll(rt);
279
+ } else {
280
+ icd11ectApplyInstance(rt, key, cleanSettings);
281
+ icd11ectBind(rt, key);
282
+ }
283
+ return cleanup;
284
+ }, [key, settingsKey]);
285
+ };
286
+ """
287
+
288
+ #: The JavaScript emitted once per page by every ICD-11 ECT component.
289
+ ICD11ECT_RUNTIME_JS: str = _RUNTIME_TEMPLATE.replace(
290
+ "__OVERWRITABLE__", json.dumps(list(OVERWRITABLE_SETTINGS))
291
+ ).strip()
@@ -0,0 +1,194 @@
1
+ """Constants and setting maps for the ICD-11 Embedded Classification Tools.
2
+
3
+ Every entry of the ``*_SETTINGS`` maps below is ``python_prop_name ->
4
+ ECT setting name``. They are the single source of truth used to build the
5
+ JavaScript settings object handed to ``ECT.Handler.configure`` and
6
+ ``ECT.Handler.overwriteConfiguration``.
7
+
8
+ The names were verified against the ``@whoicd/icd11ect`` 1.8.0 bundle
9
+ (the ``Handler.configure`` implementation) and the WHO documentation for
10
+ ECT 1.5 through 1.8.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from typing import Final
16
+
17
+ #: Public WHO ICD-API cloud server. Requires OAUTH 2.0 (``api_secured=True``).
18
+ WHO_CLOUD_API: Final[str] = "https://id.who.int"
19
+
20
+ #: WHO test server for software development only. No authentication needed.
21
+ #: Do not use it in production; it is rate limited and may go away.
22
+ WHO_DEVELOPER_TEST_API: Final[str] = (
23
+ "https://icd11restapi-developer-test.azurewebsites.net"
24
+ )
25
+
26
+ #: OAUTH 2.0 token endpoint of the ICD-API access management service.
27
+ ICD_TOKEN_ENDPOINT: Final[str] = "https://icdaccessmanagement.who.int/connect/token"
28
+
29
+ #: OAUTH 2.0 scope required by the ICD-API.
30
+ ICD_TOKEN_SCOPE: Final[str] = "icdapi_access"
31
+
32
+ #: npm package wrapped by this component.
33
+ ECT_PACKAGE: Final[str] = "@whoicd/icd11ect"
34
+
35
+ #: npm version range installed in the frontend. ECT is released as
36
+ #: ``1.x`` with occasional breaking changes in the minor, so it is pinned
37
+ #: to the tested minor version.
38
+ ECT_VERSION: Final[str] = "1.8"
39
+
40
+ #: Stylesheet shipped by the npm package; required for the tools to look right.
41
+ ECT_STYLESHEET: Final[str] = f"{ECT_PACKAGE}/style.css"
42
+
43
+ # --------------------------------------------------------------------------- #
44
+ # Settings
45
+ # --------------------------------------------------------------------------- #
46
+
47
+ #: Settings shared by the Embedded Coding Tool and the Embedded Browser.
48
+ COMMON_SETTINGS: Final[dict[str, str]] = {
49
+ "api_server_url": "apiServerUrl",
50
+ "api_secured": "apiSecured",
51
+ "source": "source",
52
+ "minor_version": "minorVersion",
53
+ "language": "language",
54
+ "source_app": "sourceApp",
55
+ "height": "height",
56
+ "hierarchy_title": "hierarchyTitle",
57
+ "hierarchy_resizable": "hierarchyResizable",
58
+ "other_postcoordination": "otherPostcoordination",
59
+ "enable_keyboard": "enableKeyboard",
60
+ "include_diagnostic_criteria": "includeDiagnosticCriteria",
61
+ "verbose": "verbose",
62
+ }
63
+
64
+ #: Settings that only affect the Embedded Coding Tool.
65
+ CODING_TOOL_SETTINGS: Final[dict[str, str]] = {
66
+ "popup_mode": "popupMode",
67
+ "simplified_mode": "simplifiedMode",
68
+ "disable_hierarchy": "disableHierarchy",
69
+ "words_available": "wordsAvailable",
70
+ "chapters_available": "chaptersAvailable",
71
+ "chapters_filter": "chaptersFilter",
72
+ "subtrees_filter": "subtreesFilter",
73
+ "flexisearch_available": "flexisearchAvailable",
74
+ "search_by_code_or_uri": "searchByCodeOrURI",
75
+ "medical_coding_mode": "medicalCodingMode",
76
+ "view_selected_uri": "viewSelectedURI",
77
+ }
78
+
79
+ #: Settings that only affect the Embedded Browser.
80
+ BROWSER_SETTINGS: Final[dict[str, str]] = {
81
+ "enable_select_button": "enableSelectButton",
82
+ "browser_search_available": "browserSearchAvailable",
83
+ "browser_advanced_search_available": "browserAdvancedSearchAvailable",
84
+ "browser_hierarchy_available": "browserHierarchyAvailable",
85
+ "browser_hierarchy_root_uris": "browserHierarchyRootURIs",
86
+ "browser_uri": "browserURI",
87
+ "display_other_foundation_children": "displayOtherFoundationChildren",
88
+ }
89
+
90
+ #: Every setting understood by ECT, python name -> ECT name.
91
+ ALL_SETTINGS: Final[dict[str, str]] = {
92
+ **COMMON_SETTINGS,
93
+ **CODING_TOOL_SETTINGS,
94
+ **BROWSER_SETTINGS,
95
+ }
96
+
97
+ #: Settings that ``ECT.Handler.overwriteConfiguration`` can change for a
98
+ #: single instance. Anything else is global to the page and is applied
99
+ #: through ``ECT.Handler.configure``.
100
+ OVERWRITABLE_SETTINGS: Final[tuple[str, ...]] = (
101
+ "apiServerUrl",
102
+ "apiSecured",
103
+ "source",
104
+ "minorVersion",
105
+ "language",
106
+ "popupMode",
107
+ "simplifiedMode",
108
+ "disableHierarchy",
109
+ "wordsAvailable",
110
+ "chaptersAvailable",
111
+ "chaptersFilter",
112
+ "subtreesFilter",
113
+ "flexisearchAvailable",
114
+ "searchByCodeOrURI",
115
+ "hierarchyTitle",
116
+ "height",
117
+ )
118
+
119
+ # --------------------------------------------------------------------------- #
120
+ # Enumerations (plain strings, so they stay usable from rx.Var)
121
+ # --------------------------------------------------------------------------- #
122
+
123
+ #: ``source`` values. ``mms`` is the ICD-11 MMS linearization, ``icf`` the
124
+ #: International Classification of Functioning (ECT >= 1.7), ``foundation``
125
+ #: the ICD-11 Foundation (Embedded Browser only).
126
+ SOURCE_MMS: Final[str] = "mms"
127
+ SOURCE_ICF: Final[str] = "icf"
128
+ SOURCE_FOUNDATION: Final[str] = "foundation"
129
+ SOURCES: Final[tuple[str, ...]] = (SOURCE_MMS, SOURCE_ICF, SOURCE_FOUNDATION)
130
+
131
+ #: ``enable_select_button`` values for the Embedded Browser.
132
+ SELECT_BUTTON_NONE: Final[str] = "none"
133
+ SELECT_BUTTON_CATEGORIES: Final[str] = "categories"
134
+ SELECT_BUTTON_ALL: Final[str] = "all"
135
+ SELECT_BUTTON_ALL_BUT_ROOT: Final[str] = "allButRoot"
136
+ SELECT_BUTTON_MODES: Final[tuple[str, ...]] = (
137
+ SELECT_BUTTON_NONE,
138
+ SELECT_BUTTON_CATEGORIES,
139
+ SELECT_BUTTON_ALL,
140
+ SELECT_BUTTON_ALL_BUT_ROOT,
141
+ )
142
+
143
+ #: Languages the ICD-11 API serves, ISO 639-1 code -> English name.
144
+ #: Availability depends on the release and on the server deployment.
145
+ LANGUAGES: Final[dict[str, str]] = {
146
+ "ar": "Arabic",
147
+ "cs": "Czech",
148
+ "en": "English",
149
+ "es": "Spanish",
150
+ "fr": "French",
151
+ "it": "Italian",
152
+ "ja": "Japanese",
153
+ "ko": "Korean",
154
+ "pt": "Portuguese",
155
+ "ru": "Russian",
156
+ "tr": "Turkish",
157
+ "uz": "Uzbek",
158
+ "zh": "Chinese",
159
+ }
160
+
161
+ #: Languages written right to left. ECT adds the ``rtl`` class for these.
162
+ RTL_LANGUAGES: Final[tuple[str, ...]] = ("ar", "he")
163
+
164
+ #: ICD-11 MMS chapters, code -> title. Use the keys with ``chapters_filter``.
165
+ MMS_CHAPTERS: Final[dict[str, str]] = {
166
+ "01": "Certain infectious or parasitic diseases",
167
+ "02": "Neoplasms",
168
+ "03": "Diseases of the blood or blood-forming organs",
169
+ "04": "Diseases of the immune system",
170
+ "05": "Endocrine, nutritional or metabolic diseases",
171
+ "06": "Mental, behavioural or neurodevelopmental disorders",
172
+ "07": "Sleep-wake disorders",
173
+ "08": "Diseases of the nervous system",
174
+ "09": "Diseases of the visual system",
175
+ "10": "Diseases of the ear or mastoid process",
176
+ "11": "Diseases of the circulatory system",
177
+ "12": "Diseases of the respiratory system",
178
+ "13": "Diseases of the digestive system",
179
+ "14": "Diseases of the skin",
180
+ "15": "Diseases of the musculoskeletal system or connective tissue",
181
+ "16": "Diseases of the genitourinary system",
182
+ "17": "Conditions related to sexual health",
183
+ "18": "Pregnancy, childbirth or the puerperium",
184
+ "19": "Certain conditions originating in the perinatal period",
185
+ "20": "Developmental anomalies",
186
+ "21": "Symptoms, signs or clinical findings, not elsewhere classified",
187
+ "22": "Injury, poisoning or certain other consequences of external causes",
188
+ "23": "External causes of morbidity or mortality",
189
+ "24": "Factors influencing health status or contact with health services",
190
+ "25": "Codes for special purposes",
191
+ "26": "Supplementary Chapter Traditional Medicine Conditions - Module I",
192
+ "V": "Supplementary section for functioning assessment",
193
+ "X": "Extension Codes",
194
+ }