labfreed 1.0.0a3__py3-none-any.whl → 1.0.0a5__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.
labfreed/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  Python implementation of LabFREED building blocks
3
3
  '''
4
4
 
5
- __version__ = "1.0.0a3"
5
+ __version__ = "1.0.0a5"
6
6
 
7
7
  from labfreed.pac_id import * # noqa: F403
8
8
  from labfreed.pac_cat import * # noqa: F403
@@ -3,7 +3,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
3
3
 
4
4
  import requests
5
5
 
6
- from labfreed.labfreed_extended.app.pac_info import PacInfo
6
+ from labfreed.labfreed_extended.app.pac_info.pac_info import PacInfo
7
7
  from labfreed.pac_attributes.client.attribute_cache import MemoryAttributeCache
8
8
  from labfreed.pac_attributes.client.client import AttributeClient, http_attribute_request_default_callback_factory
9
9
  from labfreed.pac_attributes.pythonic.py_attributes import pyAttributeGroup
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>icons/external-link</title>
4
+ <g id="icons/external-link" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <path d="M5.10570888,18.8942911 C4.83722343,18.6258057 4.81484965,18.204406 5.03858752,17.9104349 L5.10570888,17.8336309 L15.9992174,6.94117952 L10.8105793,6.93942074 L10.7088087,6.93257412 C10.3427331,6.8829117 10.0605793,6.5691165 10.0605793,6.18942074 C10.0605793,5.81286295 10.3380887,5.50112097 10.6997498,5.44755266 L10.8105793,5.43942074 L18.5605793,5.43942074 L18.5605793,13.1894207 L18.5537326,13.2911913 C18.5090365,13.6206593 18.2503927,13.8821507 17.9223127,13.9311544 L17.8105793,13.9394207 L17.7088087,13.9325741 C17.3793407,13.8878779 17.1178493,13.6292342 17.0688456,13.3011542 L17.0605793,13.1894207 L17.0598776,8.00183969 L6.16636906,18.8942911 C5.87347584,19.1871843 5.3986021,19.1871843 5.10570888,18.8942911 Z" id="Icons/Navigation/External-Link/Dark" fill="#1C1847" fill-rule="nonzero"></path>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,188 @@
1
+ {# ---------- PAC-INFO MACROS ---------- #}
2
+ {# These macros render semantic HTML with light class hooks. #}
3
+
4
+ {%- macro info_card(pac_info) -%}
5
+ <section class="lf-info-card">
6
+ <div class="lf-info-title">{{ pac_info.display_name }}</div>
7
+ <div class="lf-info-grid">
8
+ {% if pac_info.image_url %}
9
+ <img src="{{ pac_info.image_url }}" class="prod_img lf-info-item" alt="">
10
+ {% endif %}
11
+
12
+ {% if pac_info.main_category %}
13
+ {% for c in pac_info.pac_id.categories %}
14
+ {% for k, v in c.segments_as_dict().items() %}
15
+ {% if k != "key" %}
16
+ <div class="lf-info-item">
17
+ {% if k %}
18
+ <div class="lf-info-key">{{ k }}</div>
19
+ {% else %}
20
+ <div class="lf-info-key"> <i>{{"No Key" }}</i></div>
21
+ {% endif %}
22
+ <div class="lf-info-val">{{ v }}</div>
23
+ </div>
24
+ {% endif %}
25
+ {% endfor %}
26
+ {% endfor %}
27
+ {% endif %}
28
+
29
+ </div>
30
+ {% if pac_info.safety_pictograms %}
31
+ {% for p in pac_info.safety_pictograms.values() %}
32
+ <figure class="lf-figure lf-figure--image">
33
+ <img src="{{ p.value|e }}" alt="{{ p.label|e }}" class="lf-attr-image">
34
+ <figcaption class="lf-figure__caption sr-only">{{ p.label }}</figcaption>
35
+ </figure>
36
+ {% endfor %}
37
+ {% endif %}
38
+
39
+ </section>
40
+ {%- endmacro -%}
41
+
42
+
43
+ {%- macro key_value_table(pairs) -%}
44
+ {# pairs: dict-like object #}
45
+ <table class="lf-table lf-table--kv">
46
+ <tbody>
47
+ {%- for k, v in pairs.items() -%}
48
+ {%- if k != "key" -%}
49
+ <tr>
50
+ <th class="lf-th lf-th--key">{{ k }}</th>
51
+ <td class="lf-td lf-td--val">{{ v }}</td>
52
+ </tr>
53
+ {%- endif -%}
54
+ {%- endfor -%}
55
+ </tbody>
56
+ </table>
57
+ {%- endmacro -%}
58
+
59
+
60
+ {%- macro category_block(category) -%}
61
+ <div class="lf-section lf-section--category">
62
+ <h5 class="lf-section__title">{{ category.__class__.__name__ }}</h5>
63
+ {{ key_value_table(category.segments_as_dict()) }}
64
+ </div>
65
+ {%- endmacro -%}
66
+
67
+
68
+ {%- macro services_table(user_handover_group) -%}
69
+ <div class="lf-section lf-section--services">
70
+ <div class="lf-origin-hint">from {{ user_handover_group.origin }}</div>
71
+ <div class="lf-services">
72
+ {%- for s in user_handover_group.services -%}
73
+ <a href="{{ s.url }}" target="_blank" rel="noopener" class="lf-service">
74
+ <span class="lf-service__icon">
75
+ {% include "external-link.svg" %}
76
+ </span>
77
+ <span class="lf-service__name">{{ s.service_name }}</span>
78
+ </a>
79
+ {%- endfor -%}
80
+ </div>
81
+ </div>
82
+ {%- endmacro -%}
83
+
84
+
85
+ {%- macro reference_value(value) -%}
86
+ <span class="lf-reference">{{ value }}</span>
87
+ {%- endmacro -%}
88
+
89
+
90
+ {%- macro attribute_row(a) -%}
91
+ <tr>
92
+ <th class="lf-th lf-th--key">{{ a.label }}</th>
93
+ <td class="lf-td lf-td--val">
94
+ {% set value = a.value %}
95
+ {%- if is_image(value) -%}
96
+ <figure class="lf-figure lf-figure--image">
97
+ <img src="{{ value|e }}" alt="{{ label|e }}" class="lf-attr-image">
98
+ <figcaption class="lf-figure__caption sr-only">{{ label }}</figcaption>
99
+ </figure>
100
+ {%- elif is_url(value) -%}
101
+ <a href="{{ value|e }}" target="_blank" rel="noopener" class="lf-link">{{ value }}</a>
102
+ {%- elif is_reference(value) -%}
103
+ {{ reference_value(value)}}
104
+ {%- else -%}
105
+ <span class="lf-text">{{ value }}</span>
106
+ {%- endif -%}
107
+ </td>
108
+ </tr>
109
+ {%- endmacro -%}
110
+
111
+
112
+ {%- macro attribute_group_block(ag) -%}
113
+ <div class="lf-section lf-section--attributes">
114
+ <h5 class="lf-section__title">
115
+ {{ ag.label }} <span class="lf-origin-hint">(from {{ ag.origin }})</span>
116
+ </h5>
117
+ <table class="lf-table lf-table--kv">
118
+ <tbody>
119
+ {%- for a in ag.attributes.values() -%}
120
+ {{ attribute_row(a) }}
121
+ {%- endfor -%}
122
+ </tbody>
123
+ </table>
124
+ </div>
125
+ {%- endmacro -%}
126
+
127
+
128
+ {%- macro data_table_inline(dt) -%}
129
+ {# Renders your DataTable structure; expects filters: is_data_table(dt) #}
130
+ {%- if dt.data | length == 1 -%}
131
+ <table class="lf-table lf-table--kv">
132
+ <tbody>
133
+ {%- for i in range(dt.col_names | length) -%}
134
+ <tr>
135
+ <th class="lf-th lf-th--key">{{ dt.col_names[i] }}</th>
136
+ <td class="lf-td lf-td--val">{{ dt.data[0][i] }}</td>
137
+ </tr>
138
+ {%- endfor -%}
139
+ </tbody>
140
+ </table>
141
+ {%- else -%}
142
+ <table class="lf-table lf-table--grid">
143
+ <thead>
144
+ <tr>
145
+ {%- for rn in dt.col_names -%}
146
+ <th class="lf-th">{{ rn }}</th>
147
+ {%- endfor -%}
148
+ </tr>
149
+ </thead>
150
+ <tbody>
151
+ {%- for row in dt.data -%}
152
+ <tr>
153
+ {%- for e in row -%}
154
+ <td class="lf-td">{{ e }}</td>
155
+ {%- endfor -%}
156
+ </tr>
157
+ {%- endfor -%}
158
+ </tbody>
159
+ </table>
160
+ {%- endif -%}
161
+ {%- endmacro -%}
162
+
163
+
164
+ {%- macro attached_data_block(attached_data) -%}
165
+ <div class="lf-section lf-section--attached">
166
+ {%- for name, trex in attached_data.items() -%}
167
+ <div class="lf-subsection">
168
+ <h5 class="lf-subsection__title">{{ name }}</h5>
169
+ <table class="lf-table lf-table--kv">
170
+ <tbody>
171
+ {%- for k, v in trex.items() -%}
172
+ <tr>
173
+ <th class="lf-th lf-th--key">{{ k }}</th>
174
+ <td class="lf-td lf-td--val">
175
+ {%- if is_data_table(v) -%}
176
+ {{ data_table_inline(v) }}
177
+ {%- else -%}
178
+ {{ v }}
179
+ {%- endif -%}
180
+ </td>
181
+ </tr>
182
+ {%- endfor -%}
183
+ </tbody>
184
+ </table>
185
+ </div>
186
+ {%- endfor -%}
187
+ </div>
188
+ {%- endmacro -%}
@@ -0,0 +1,176 @@
1
+
2
+ .lf-section {
3
+ margin-top: 0.5rem;
4
+ }
5
+
6
+ .lf-origin-hint {
7
+ font-style: italic; /* cursive */
8
+ font-size: 1rem; /* reset to regular text size */
9
+ font-weight: normal; /* not bold, even if inside a heading */
10
+ }
11
+
12
+
13
+ .lf-results {
14
+ display: grid;
15
+ gap: 1.5rem;
16
+ padding: 1rem; /* space around the whole grid */
17
+ }
18
+
19
+ .lf-info-card {
20
+ width:100%;
21
+ border: solid 1px #ccc;
22
+ border-radius: 8px;
23
+ }
24
+
25
+ .lf-info-card {
26
+ padding: 1rem;
27
+ border: 1px solid #e5e7eb;
28
+ border-radius: 8px;
29
+ background: #fff;
30
+ }
31
+
32
+ /* title as "slightly bigger text" */
33
+ .lf-info-title {
34
+ font-size: 1.25rem; /* a bit larger than normal text */
35
+ font-weight: 600;
36
+ margin-bottom: 1rem;
37
+ }
38
+
39
+ /* responsive grid for key/value */
40
+ .lf-info-grid {
41
+ display: grid;
42
+ gap: 1rem;
43
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
44
+ }
45
+
46
+ .lf-info-item {
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: 0.25rem;
50
+ padding: 0.5rem;
51
+ }
52
+
53
+ .lf-info-key {
54
+ font-size: 0.875rem;
55
+ font-weight: 600;
56
+ color: #374151; /* slate-700 */
57
+ }
58
+
59
+ .lf-info-val {
60
+ font-size: 1rem;
61
+ color: #111827; /* slate-900 */
62
+ }
63
+
64
+
65
+
66
+ .prod_img {
67
+ height: 10vw;
68
+ width: auto;
69
+ }
70
+
71
+
72
+ /* Apply to all PAC macro tables */
73
+ .lf-table {
74
+ width: 100%;
75
+ border-collapse: collapse;
76
+ table-layout: fixed; /* ensures consistent column widths */
77
+ }
78
+
79
+ .lf-table th,
80
+ .lf-table td {
81
+ border: 1px solid #ccc;
82
+ padding: 0.4rem 0.6rem;
83
+ vertical-align: top;
84
+ text-align: left;
85
+ }
86
+
87
+ /* Key/value style: 1/3 vs 2/3 columns */
88
+ .lf-table--kv th.lf-th--key {
89
+ width: 33%;
90
+ font-weight: 600;
91
+ }
92
+ .lf-table--kv td.lf-td--val {
93
+ width: 67%;
94
+ }
95
+
96
+ .lf-attr-image {
97
+ width: 30px;
98
+ }
99
+
100
+ /* Services laid out as equal-width grid columns */
101
+ .lf-services {
102
+ display: grid;
103
+ gap: 0.75rem;
104
+
105
+ /* 2 columns on small, 3 on md, 4 on lg — tweak as you like */
106
+ grid-template-columns: repeat(2, 1fr);
107
+ }
108
+
109
+ @media (min-width: 640px) {
110
+ .lf-services { grid-template-columns: repeat(3, 1fr); }
111
+ }
112
+ @media (min-width: 1024px) {
113
+ .lf-services { grid-template-columns: repeat(4, 1fr); }
114
+ }
115
+
116
+ /* Each service card fills its grid cell */
117
+ .lf-service {
118
+ display: flex; /* still use flex inside for icon + text */
119
+ align-items: center;
120
+ gap: 0.4rem;
121
+ padding: 0.4rem 0.6rem;
122
+ height: 100%; /* same height across a row (since your content height is uniform) */
123
+ width: 100%; /* ensure full cell width */
124
+ text-decoration: none;
125
+ color: var(--lf-link, #2563eb);
126
+ }
127
+
128
+ .lf-service:hover {
129
+ font-size: 1.05em; /* ~5% larger */
130
+ text-decoration: none;
131
+ }
132
+
133
+ .lf-service__icon { width: 1rem; height: 1rem; flex-shrink: 0; }
134
+ .lf-service__name {
135
+ flex: 1;
136
+ overflow: hidden;
137
+ text-overflow: ellipsis;
138
+ white-space: nowrap;
139
+ }
140
+
141
+
142
+
143
+ /* Position context */
144
+ .lf-ref-card-wrap {
145
+ position: relative;
146
+ display: inline-block;
147
+ }
148
+
149
+ /* The floating card is hidden by default */
150
+ .lf-ref-card {
151
+ display: none;
152
+ position: absolute;
153
+ top: 100%; /* appear below the reference text */
154
+ left: 0;
155
+ z-index: 1000;
156
+ width: min(420px, 90vw);
157
+ margin-top: .5rem;
158
+ padding: 1rem;
159
+ background: #fff;
160
+ border: 1px solid #e5e7eb;
161
+ border-radius: 8px;
162
+ box-shadow: 0 10px 20px rgba(0,0,0,.08);
163
+ }
164
+
165
+ /* Show on hover */
166
+ .lf-ref-card-wrap:hover .lf-ref-card {
167
+ display: block;
168
+ }
169
+
170
+ /* Style the inline reference */
171
+ .lf-reference {
172
+ color: var(--lf-link, #2563eb);
173
+ }
174
+
175
+
176
+
@@ -0,0 +1,46 @@
1
+ {% import "macros.jinja.html" as pac with context %}
2
+
3
+ <style>
4
+ {% include "pac-info-style.css" %}
5
+ </style>
6
+
7
+
8
+ {% if pac_info %}
9
+ <section class="lf-results">
10
+ {# ----- Info Card ---- #}
11
+ {{ pac.info_card(pac_info) }}
12
+
13
+ {# ---- Services ---- #}
14
+ {% if pac_info.user_handovers %}
15
+ <section>
16
+ <!--<h4>Services</h4>-->
17
+ {% for sg in pac_info.user_handovers %}
18
+ {{ pac.services_table(sg) }}
19
+ {% endfor %}
20
+ </section>
21
+ {% endif %}
22
+
23
+ {# ---- Attributes ---- #}
24
+ {% if pac_info.attributes %}
25
+ <section>
26
+ <!--<h4>Attributes</h4>-->
27
+ {% for ag in pac_info.attributes.values() %}
28
+ {% if ag.key not in hide_attribute_groups %}
29
+ {{ pac.attribute_group_block(ag) }}
30
+ {% endif %}
31
+ {% endfor %}
32
+ </section>
33
+
34
+ {% endif %}
35
+
36
+ {# ---- Attached Data ---- #}
37
+ {% if pac_info.attached_data %}
38
+ <section>
39
+ <!--<h4 class="lf-section__title">Attached Data</h4>-->
40
+ {{ pac.attached_data_block(pac_info.attached_data) }}
41
+ </section>
42
+ {% endif %}
43
+
44
+ </section>
45
+
46
+ {% endif %}
@@ -0,0 +1,7 @@
1
+ {% import "macros.jinja.html" as macros with context %}
2
+
3
+
4
+ <style>
5
+ {% include "pac-info-style.css" %}
6
+ </style>
7
+ {{ macros.info_card(pac_info) }}
@@ -1,13 +1,17 @@
1
1
 
2
2
 
3
3
  from functools import cached_property
4
+ from pathlib import Path
5
+ from urllib.parse import urlparse
6
+ from jinja2 import Environment, FileSystemLoader, select_autoescape
4
7
  from pydantic import BaseModel, Field
5
- from labfreed.pac_attributes.pythonic.py_attributes import pyAttribute, pyAttributeGroup, pyAttributes
8
+ from labfreed.pac_attributes.pythonic.py_attributes import pyAttribute, pyAttributeGroup, pyAttributes, pyReference
6
9
  from labfreed.pac_attributes.well_knonw_attribute_keys import MetaAttributeKeys
7
10
  from labfreed.pac_cat.pac_cat import PAC_CAT
8
11
  from labfreed.pac_id.pac_id import PAC_ID
9
12
  from labfreed.pac_id_resolver.services import ServiceGroup
10
13
  from labfreed.labfreed_extended.app.formatted_print import StringIOLineBreak
14
+ from labfreed.trex.pythonic.data_table import DataTable
11
15
  from labfreed.trex.pythonic.pyTREX import pyTREX
12
16
  from labfreed.well_known_extensions.display_name_extension import DisplayNameExtension
13
17
 
@@ -112,6 +116,39 @@ class PacInfo(BaseModel):
112
116
 
113
117
  return out
114
118
 
119
+
120
+
121
+ def render_html(self, hide_attribute_groups:list[str]=[]) -> str:
122
+ return PACInfo_HTMLRenderer.render_template('pac_info_main.jinja.html',
123
+ pac_info = self,
124
+ hide_attribute_groups=hide_attribute_groups
125
+ )
115
126
 
127
+ def render_html_card(self) -> str:
128
+ return PACInfo_HTMLRenderer.render_template('pac_info_card.jinja.html',
129
+ pac_info = self
130
+ )
131
+
116
132
 
133
+ class PACInfo_HTMLRenderer():
134
+ TEMPLATES_DIR = Path(__file__).parent / "html_renderer"
135
+ jinja_env = Environment(
136
+ loader=FileSystemLoader(str(TEMPLATES_DIR), encoding="utf-8"),
137
+ autoescape=select_autoescape(enabled_extensions=("html", "jinja", "jinja2", "jinja.html")),
138
+ )
139
+
140
+ @classmethod
141
+ def render_template(cls, template_name:str, pac_info:PacInfo, hide_attribute_groups):
142
+ # --- Jinja env pointing at /html_renderer ---
143
+ template = cls.jinja_env.get_template("pac_info.jinja.html")
144
+ html = template.render(
145
+ pac=pac_info.pac_id,
146
+ pac_info=pac_info, # your object
147
+ hide_attribute_groups=hide_attribute_groups,
148
+ is_data_table = lambda value: isinstance(value, DataTable),
149
+ is_url = lambda s: isinstance(s, str) and urlparse(s).scheme in ('http', 'https') and bool(urlparse(s).netloc),
150
+ is_image = lambda s: isinstance(s, str) and s.lower().startswith('http') and s.lower().endswith(('.jpg','.jpeg','.png','.gif','.bmp','.webp','.svg','.tif','.tiff')),
151
+ is_reference = lambda s: isinstance(s, pyReference) ,
152
+ )
153
+ return html
117
154
 
@@ -116,9 +116,9 @@ class Material_Consumable(PredefinedCategory):
116
116
  return self
117
117
 
118
118
  class Material_Misc(Material_Consumable):
119
- '''Represents the -MC category'''
119
+ '''Represents the -MX category'''
120
120
  # same fields as Consumable
121
- key: str = Field(default='-MM', frozen=True)
121
+ key: str = Field(default='-MX', frozen=True)
122
122
  product_number:str|None = Field( alias='240')
123
123
  batch_number:str|None = Field(default=None, alias='10')
124
124
  packaging_size:str|None = Field(default=None, alias='20')
@@ -187,15 +187,64 @@ class Data_Static(Data_Abstract):
187
187
  additional_segments: list[IDSegment] = Field(default_factory=list, exclude=True)
188
188
  ''' Category segments, which are not defined in the specification'''
189
189
 
190
+ class Data_Misc(Data_Abstract):
191
+ '''Represents the -DX category'''
192
+ key: str = Field(default='-DX', frozen=True)
193
+ id:str|None = Field( alias='21')
194
+ additional_segments: list[IDSegment] = Field(default_factory=list, exclude=True)
195
+ ''' Category segments, which are not defined in the specification'''
196
+
197
+
198
+
199
+
200
+ class Processor_Abstract(PredefinedCategory, ABC):
201
+ '''@private'''
202
+ key: str
203
+ processor_instance:str|None = Field( alias='21')
204
+ processor_code:str|None = Field( alias='240')
205
+
206
+ additional_segments: list[IDSegment] = Field(default_factory=list, exclude=True)
207
+ ''' Category segments, which are not defined in the specification'''
208
+
209
+ @model_validator(mode='after')
210
+ def _validate_mandatory_fields(self):
211
+ if not self.id:
212
+ self._add_validation_message(
213
+ source=f"Category {self.key}",
214
+ level = ValidationMsgLevel.ERROR,
215
+ msg=f"Category key {self.key} is missing mandatory field 'processor instance'",
216
+ highlight_pattern = f"{self.key}"
217
+ )
218
+ return self
219
+
220
+ class Processor_Software(Processor_Abstract):
221
+ '''Represents the -PS category'''
222
+ key: str = Field(default='-PS', frozen=True)
223
+ processor_instance:str|None = Field( alias='21')
224
+ processor_code:str|None = Field( alias='240')
225
+ additional_segments: list[IDSegment] = Field(default_factory=list, exclude=True)
226
+ ''' Category segments, which are not defined in the specification'''
227
+
228
+ class Processor_Misc(Processor_Abstract):
229
+ '''Represents the -PX category'''
230
+ key: str = Field(default='-PX', frozen=True)
231
+ processor_instance:str|None = Field( alias='21')
232
+ processor_code:str|None = Field( alias='240')
233
+ additional_segments: list[IDSegment] = Field(default_factory=list, exclude=True)
234
+ ''' Category segments, which are not defined in the specification'''
235
+
190
236
 
191
237
  category_key_to_class_map = {
192
238
  '-MD': Material_Device,
193
239
  '-MS': Material_Substance,
194
240
  '-MC': Material_Consumable,
195
- '-MM': Material_Misc,
241
+ '-MX': Material_Misc,
196
242
  '-DM': Data_Method,
197
243
  '-DR': Data_Result,
198
244
  '-DC': Data_Calibration,
199
245
  '-DP': Data_Progress,
200
- '-DS': Data_Static
246
+ '-DS': Data_Static,
247
+ '-DX': Data_Misc,
248
+ '-PS': Processor_Software,
249
+ '-PX': Processor_Misc
201
250
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labfreed
3
- Version: 1.0.0a3
3
+ Version: 1.0.0a5
4
4
  Summary: Python implementation of LabFREED building blocks
5
5
  Author-email: Reto Thürer <thuerer.r@buchi.com>
6
6
  Requires-Python: >=3.11
@@ -1,8 +1,13 @@
1
- labfreed/__init__.py,sha256=feEsSamwMYNQXaiqTt0oe0dEoLnkS-SJ5-YIdMtkerE,338
1
+ labfreed/__init__.py,sha256=7ep4pSxnKSCTXNnCY9m1eisddENI9mgk6BJzi6K6W_c,338
2
2
  labfreed/labfreed_infrastructure.py,sha256=YZmU-kgopyB1tvpTR_k_uIt1Q2ezexMrWvu-HaP65IE,10104
3
- labfreed/labfreed_extended/app/app_infrastructure.py,sha256=1VMc_Vtjwof9hwzSG95KuIUjT1h7uNsWf_lTORYFFuQ,3981
3
+ labfreed/labfreed_extended/app/app_infrastructure.py,sha256=qn6KesHiOrhTPgXwMZNqFArKlWluxFbk5bgp5u8KDb8,3990
4
4
  labfreed/labfreed_extended/app/formatted_print.py,sha256=DcwWP0ix1e_wYNIdceIp6cETkJdG2DqpU8Gs3aZAL40,1930
5
- labfreed/labfreed_extended/app/pac_info.py,sha256=oiU940sUJiV3yfNLOmkCsn7Go4qui_jijULeHTOFgrg,4163
5
+ labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=hAMKalOs-v5_5DawtTn63-OZILDJpmFpgw-H6uow5qA,6097
6
+ labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg,sha256=H5z9s4VvHq09UnHdqfrYNsx-Whljc0gE4qKJ6-3kfgQ,1158
7
+ labfreed/labfreed_extended/app/pac_info/html_renderer/macros.jinja.html,sha256=1S-dxibPwJshtdelsmyA4LpgOm84L6RTXPNO93gmPfg,5964
8
+ labfreed/labfreed_extended/app/pac_info/html_renderer/pac-info-style.css,sha256=C5pyD956fd6pJgUBjGxvxgL0Wbgq0v7ZLY4Vr-sJZ7A,4169
9
+ labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info.jinja.html,sha256=njXE9xexFdMlX65eDiwqE8PzbMATUOJAbwBCh5JvahY,1293
10
+ labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info_card.jinja.html,sha256=6UdsZtqJ3soSAYTKN43OB1Onm93WYz23TfM2GBYzJ-U,152
6
11
  labfreed/pac_attributes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
12
  labfreed/pac_attributes/well_knonw_attribute_keys.py,sha256=axE81MeJ3G_Wy1PbmNAXH6SfPtl96NXvQJMyrvK10t4,324
8
13
  labfreed/pac_attributes/api_data_models/request.py,sha256=-CI3rU_Bzw2DZGSS06Jl4zajrxMkfPGhKHWmIfnmWlk,1868
@@ -22,7 +27,7 @@ labfreed/pac_attributes/server/translation_data_sources.py,sha256=axALOqfP840sOS
22
27
  labfreed/pac_cat/__init__.py,sha256=KNPtQzBD1XVohvG_ucOs7RJj-oi6biUTGB1k-T2o6pk,568
23
28
  labfreed/pac_cat/category_base.py,sha256=wVejYgDnUIUQ71q05ctophtZY2w9fD-PZ0xk3wUAEkQ,2522
24
29
  labfreed/pac_cat/pac_cat.py,sha256=wcb_fhvgjS2xmqTsxS8_Oibvr1nsQt5zr8aUajLfK1E,5578
25
- labfreed/pac_cat/predefined_categories.py,sha256=5wnMCj-CrACV2W4lH13w7qynWIwi506G3uLNcxuJQGg,8832
30
+ labfreed/pac_cat/predefined_categories.py,sha256=lbQD8W3ncKLVnyWc2UToelgFRJ4Frok5BbkCOd2JgwM,11107
26
31
  labfreed/pac_id/__init__.py,sha256=NGMbzkwQ4txKeT5pxdIZordwHO8J3_q84jzPanjKoHg,675
27
32
  labfreed/pac_id/extension.py,sha256=NgLexs1LbRMMm4ETrn5m4EY2iWoMDgOTb0UV556jatQ,2227
28
33
  labfreed/pac_id/id_segment.py,sha256=r5JU1SJuRXhZJJxy5T3xjrb598wIDTLpivSJhIUAzjQ,4526
@@ -59,7 +64,7 @@ labfreed/well_known_keys/labfreed/well_known_keys.py,sha256=p-hXwEEIs7p2SKn9DQeL
59
64
  labfreed/well_known_keys/unece/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
60
65
  labfreed/well_known_keys/unece/__init__.py,sha256=MSP9lmjg9_D9iqG9Yq2_ajYfQSNS9wIT7FXA1c--59M,122
61
66
  labfreed/well_known_keys/unece/unece_units.py,sha256=J20d64H69qKDE3XlGdJoXIIh0G-d0jKoiIDsg9an5pk,1655
62
- labfreed-1.0.0a3.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
63
- labfreed-1.0.0a3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
64
- labfreed-1.0.0a3.dist-info/METADATA,sha256=y5M4I537vHyGZcYkVCEuFrOi4uMVLp74Yz21tne3WQM,19740
65
- labfreed-1.0.0a3.dist-info/RECORD,,
67
+ labfreed-1.0.0a5.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
68
+ labfreed-1.0.0a5.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
69
+ labfreed-1.0.0a5.dist-info/METADATA,sha256=vPurZ390HjmeLxAGeMMlK8rZ6f7klEuArURm2eDqmXI,19740
70
+ labfreed-1.0.0a5.dist-info/RECORD,,