obm-upload-form-ui 0.1.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.
- package/LICENSE +674 -0
- package/README.md +153 -0
- package/dist/_plugin-vue_export-helper-DQLEQ__A.js +44 -0
- package/dist/_plugin-vue_export-helper-DQLEQ__A.js.map +1 -0
- package/dist/core/client/auth.d.ts +37 -0
- package/dist/core/client/errors.d.ts +31 -0
- package/dist/core/client/formApi.d.ts +23 -0
- package/dist/core/client/http.d.ts +10 -0
- package/dist/core/config.d.ts +25 -0
- package/dist/core/geo/wkt.d.ts +7 -0
- package/dist/core/i18n/messages.d.ts +13 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/schema/guards.d.ts +12 -0
- package/dist/core/schema/normalize.d.ts +10 -0
- package/dist/core/schema/types.d.ts +119 -0
- package/dist/core/submit/linked.d.ts +58 -0
- package/dist/core/submit/metadata.d.ts +37 -0
- package/dist/core/submit/submitClient.d.ts +40 -0
- package/dist/core/validation/engine.d.ts +18 -0
- package/dist/core/validation/rules.d.ts +29 -0
- package/dist/core/validation/types.d.ts +48 -0
- package/dist/core.js +377 -0
- package/dist/core.js.map +1 -0
- package/dist/custom-elements/obm-upload-form-ui.css +1 -0
- package/dist/custom-elements/obm-upload-form.iife.js +21 -0
- package/dist/custom-elements/obm-upload-form.iife.js.map +1 -0
- package/dist/custom-elements/obm-upload-form.js +16889 -0
- package/dist/custom-elements/obm-upload-form.js.map +1 -0
- package/dist/engine-7r1HChwT.js +174 -0
- package/dist/engine-7r1HChwT.js.map +1 -0
- package/dist/obm-upload-form-ui.css +1 -0
- package/dist/vue/FieldWrapper.vue.d.ts +30 -0
- package/dist/vue/UploadForm.vue.d.ts +58 -0
- package/dist/vue/ValidationSummary.vue.d.ts +13 -0
- package/dist/vue/fieldRegistry.d.ts +5 -0
- package/dist/vue/fields/ArrayField.vue.d.ts +14 -0
- package/dist/vue/fields/AutocompleteField.vue.d.ts +15 -0
- package/dist/vue/fields/BooleanField.vue.d.ts +14 -0
- package/dist/vue/fields/NumericField.vue.d.ts +14 -0
- package/dist/vue/fields/SelectField.vue.d.ts +15 -0
- package/dist/vue/fields/TemporalField.vue.d.ts +14 -0
- package/dist/vue/fields/TextAreaField.vue.d.ts +14 -0
- package/dist/vue/fields/TextField.vue.d.ts +14 -0
- package/dist/vue/fields/TimeIntervalField.vue.d.ts +14 -0
- package/dist/vue/fields/UnsupportedField.vue.d.ts +8 -0
- package/dist/vue/fields/WktTextField.vue.d.ts +14 -0
- package/dist/vue/index.d.ts +19 -0
- package/dist/vue/types.d.ts +22 -0
- package/dist/vue/uiText.d.ts +3 -0
- package/dist/vue/useFormState.d.ts +13 -0
- package/dist/vue-leaflet/GeometryField.vue.d.ts +14 -0
- package/dist/vue-leaflet/index.d.ts +9 -0
- package/dist/vue-leaflet.js +117 -0
- package/dist/vue-leaflet.js.map +1 -0
- package/dist/vue.js +813 -0
- package/dist/vue.js.map +1 -0
- package/dist/wkt-C0dkXG1x.js +359 -0
- package/dist/wkt-C0dkXG1x.js.map +1 -0
- package/package.json +113 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ColumnSchema, FormSchema } from '../schema/types';
|
|
2
|
+
import { DocumentState, ValidationIssue, ValidationOptions, ValidationResult } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Validate a single field value.
|
|
5
|
+
*
|
|
6
|
+
* The API performs no field-level validation on write, so this engine is the
|
|
7
|
+
* enforcement layer (see ADR 0002 for the full policy model).
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateField(column: ColumnSchema, value: unknown, state: DocumentState, options?: ValidationOptions): ValidationIssue[];
|
|
10
|
+
/**
|
|
11
|
+
* Validate a whole record against the form schema.
|
|
12
|
+
*
|
|
13
|
+
* `blocking` is true only for enforcement 'refuse' + state 'final' with at
|
|
14
|
+
* least one error-severity issue; drafts and 'warn' enforcement never block.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateForm(schema: FormSchema, data: Record<string, unknown>, state: DocumentState, options?: ValidationOptions): ValidationResult;
|
|
17
|
+
/** The single submission gate consulted by the submit client and the UI layer. */
|
|
18
|
+
export declare function canSubmit(result: ValidationResult): boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MessageOverrides } from '../i18n/messages';
|
|
2
|
+
import { ColumnSchema } from '../schema/types';
|
|
3
|
+
import { ValidationIssue } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* A value counts as empty when the user provided nothing: null, undefined,
|
|
6
|
+
* empty/whitespace-only string, or an empty array. `false` and `0` are values.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isEmpty(value: unknown): boolean;
|
|
9
|
+
interface MessageContext {
|
|
10
|
+
language?: string;
|
|
11
|
+
messages?: MessageOverrides;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkRequired(column: ColumnSchema, value: unknown, context: MessageContext): ValidationIssue[];
|
|
14
|
+
export declare function checkRegexp(column: ColumnSchema, value: unknown, context: MessageContext): ValidationIssue[];
|
|
15
|
+
/**
|
|
16
|
+
* Parse the minmax rule payload. The observed legacy convention is
|
|
17
|
+
* "min,max" (":" and ";" tolerated as separators); either bound may be blank.
|
|
18
|
+
* Returns null when the payload is unparseable.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseMinmaxBounds(rule: string): {
|
|
21
|
+
min: number | null;
|
|
22
|
+
max: number | null;
|
|
23
|
+
} | null;
|
|
24
|
+
export declare function checkMinmax(column: ColumnSchema, value: unknown, context: MessageContext): ValidationIssue[];
|
|
25
|
+
/** v0 stub: spatial rules are not evaluated client-side (see ADR 0002). */
|
|
26
|
+
export declare function checkSpatial(column: ColumnSchema, value: unknown, context: MessageContext): ValidationIssue[];
|
|
27
|
+
/** v0 stub: custom_check functions live server-side and are not evaluated here. */
|
|
28
|
+
export declare function checkCustomCheck(column: ColumnSchema, value: unknown, context: MessageContext): ValidationIssue[];
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MessageKey, MessageOverrides } from '../i18n/messages';
|
|
2
|
+
/**
|
|
3
|
+
* Lifecycle state of the record being validated. Mirrors the established OBM
|
|
4
|
+
* client convention: drafts save with little or no validation, finalization
|
|
5
|
+
* enforces the rules.
|
|
6
|
+
*/
|
|
7
|
+
export type DocumentState = 'draft' | 'final';
|
|
8
|
+
export type IssueSeverity = 'error' | 'warning' | 'unsupported';
|
|
9
|
+
export type ValidationRuleName = 'required' | 'regexp' | 'minmax' | 'spatial' | 'custom_check';
|
|
10
|
+
export interface ValidationIssue {
|
|
11
|
+
column: string;
|
|
12
|
+
rule: ValidationRuleName;
|
|
13
|
+
/**
|
|
14
|
+
* error: blocks under enforcement 'refuse' + state 'final'.
|
|
15
|
+
* warning: soft rules; reported, never blocks.
|
|
16
|
+
* unsupported: the rule cannot be checked client-side (or is misconfigured); never blocks.
|
|
17
|
+
*/
|
|
18
|
+
severity: IssueSeverity;
|
|
19
|
+
messageKey: MessageKey;
|
|
20
|
+
/** Human-readable message in the requested language. */
|
|
21
|
+
message: string;
|
|
22
|
+
params?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface ValidationPolicy {
|
|
25
|
+
/**
|
|
26
|
+
* 'refuse': error-severity issues block finalization.
|
|
27
|
+
* 'warn': issues are reported but never block (for when server-side
|
|
28
|
+
* validation takes over enforcement).
|
|
29
|
+
*/
|
|
30
|
+
enforcement: 'refuse' | 'warn';
|
|
31
|
+
/** Which checks run when validating a draft. Draft issues never block either way. */
|
|
32
|
+
draftChecks: 'skip' | 'requiredOnly' | 'all';
|
|
33
|
+
}
|
|
34
|
+
/** thr_vizfolyasok precedent: drafts skip validation, finalization refuses on errors. */
|
|
35
|
+
export declare const DEFAULT_VALIDATION_POLICY: ValidationPolicy;
|
|
36
|
+
export interface ValidationOptions {
|
|
37
|
+
policy?: Partial<ValidationPolicy>;
|
|
38
|
+
/** Language for generated messages ('en' default; 'hu' built in). */
|
|
39
|
+
language?: string;
|
|
40
|
+
/** Per-key message overrides. */
|
|
41
|
+
messages?: MessageOverrides;
|
|
42
|
+
}
|
|
43
|
+
export interface ValidationResult {
|
|
44
|
+
state: DocumentState;
|
|
45
|
+
issues: ValidationIssue[];
|
|
46
|
+
/** True when submission must be refused under the active policy. */
|
|
47
|
+
blocking: boolean;
|
|
48
|
+
}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
var v = Object.defineProperty;
|
|
2
|
+
var F = (e, t, r) => t in e ? v(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
|
+
var y = (e, t, r) => F(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
|
+
import { O as N, a as T, b as _, c as g } from "./wkt-C0dkXG1x.js";
|
|
5
|
+
import { d as ne, g as ie, i as oe, w as se } from "./wkt-C0dkXG1x.js";
|
|
6
|
+
import { F as U, U as z, v as L, c as j } from "./engine-7r1HChwT.js";
|
|
7
|
+
import { D as le, a as ue, f as ce, i as fe, p as de, b as me } from "./engine-7r1HChwT.js";
|
|
8
|
+
function E(e) {
|
|
9
|
+
return e.replace(/\/+$/, "");
|
|
10
|
+
}
|
|
11
|
+
function Q() {
|
|
12
|
+
return {
|
|
13
|
+
apply(e) {
|
|
14
|
+
e.credentials = "include";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function X(e) {
|
|
19
|
+
return {
|
|
20
|
+
async apply(t) {
|
|
21
|
+
const r = await e();
|
|
22
|
+
r && t.headers.set("Authorization", `Bearer ${r}`);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function x(e) {
|
|
27
|
+
const t = e.trim();
|
|
28
|
+
if (t === "") return null;
|
|
29
|
+
try {
|
|
30
|
+
const r = JSON.parse(t);
|
|
31
|
+
if (typeof r == "string") return r;
|
|
32
|
+
if (typeof r == "object" && r !== null) {
|
|
33
|
+
const n = r;
|
|
34
|
+
for (const s of ["token", "jwt", "access_token"])
|
|
35
|
+
if (typeof n[s] == "string") return n[s];
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
} catch {
|
|
39
|
+
return /^[\w-]+\.[\w-]+\.[\w-]+$/.test(t) ? t : null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function Z(e) {
|
|
43
|
+
const t = e.fetchImpl ?? ((...i) => globalThis.fetch(...i));
|
|
44
|
+
let r = null, n = null;
|
|
45
|
+
async function s() {
|
|
46
|
+
const i = await t(e.tokenUrl, { credentials: "include" });
|
|
47
|
+
return i.ok ? (r = x(await i.text()), r !== null) : (r = null, !1);
|
|
48
|
+
}
|
|
49
|
+
function u() {
|
|
50
|
+
return n ?? (n = s().finally(() => {
|
|
51
|
+
n = null;
|
|
52
|
+
})), n;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
async apply(i) {
|
|
56
|
+
r === null && await u(), r !== null && i.headers.set("Authorization", `Bearer ${r}`), i.credentials = "include";
|
|
57
|
+
},
|
|
58
|
+
onUnauthorized() {
|
|
59
|
+
return r = null, u();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function A(e, t, r = {}) {
|
|
64
|
+
var a;
|
|
65
|
+
const n = E(e.baseUrl) + t, s = e.fetchImpl ?? ((...o) => globalThis.fetch(...o)), u = async () => {
|
|
66
|
+
var d;
|
|
67
|
+
const o = new Headers(r.headers);
|
|
68
|
+
e.language && !o.has("Accept-Language") && o.set("Accept-Language", e.language);
|
|
69
|
+
const f = { ...r, headers: o };
|
|
70
|
+
await ((d = e.auth) == null ? void 0 : d.apply(f));
|
|
71
|
+
try {
|
|
72
|
+
return await s(n, f);
|
|
73
|
+
} catch (m) {
|
|
74
|
+
throw new T(`Request to ${n} failed before a response arrived`, { cause: m });
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
let i = await u();
|
|
78
|
+
if (i.status === 401 && ((a = e.auth) != null && a.onUnauthorized) && await e.auth.onUnauthorized() && (i = await u()), !i.ok)
|
|
79
|
+
throw new N(i.status, ...await I(i));
|
|
80
|
+
return i;
|
|
81
|
+
}
|
|
82
|
+
async function I(e) {
|
|
83
|
+
let t = "";
|
|
84
|
+
try {
|
|
85
|
+
t = await e.text();
|
|
86
|
+
} catch {
|
|
87
|
+
return ["", null];
|
|
88
|
+
}
|
|
89
|
+
const r = e.headers.get("Content-Type") ?? "";
|
|
90
|
+
if (/application\/(problem\+)?json/.test(r))
|
|
91
|
+
try {
|
|
92
|
+
const n = JSON.parse(t);
|
|
93
|
+
if (typeof n == "object" && n !== null && !Array.isArray(n))
|
|
94
|
+
return [t, n];
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
return [t, null];
|
|
98
|
+
}
|
|
99
|
+
async function b(e, t, r = {}) {
|
|
100
|
+
return await (await A(e, t, r)).json();
|
|
101
|
+
}
|
|
102
|
+
function $(e) {
|
|
103
|
+
return typeof e == "string" && U.includes(e);
|
|
104
|
+
}
|
|
105
|
+
function c(e) {
|
|
106
|
+
return typeof e == "object" && e !== null && !Array.isArray(e);
|
|
107
|
+
}
|
|
108
|
+
function l(e, t = !1) {
|
|
109
|
+
if (typeof e == "boolean") return e;
|
|
110
|
+
if (typeof e == "number") return e !== 0;
|
|
111
|
+
if (typeof e == "string") {
|
|
112
|
+
const r = e.trim().toLowerCase();
|
|
113
|
+
if (["1", "t", "true", "yes", "on"].includes(r)) return !0;
|
|
114
|
+
if (["0", "f", "false", "no", "off", ""].includes(r)) return !1;
|
|
115
|
+
}
|
|
116
|
+
return t;
|
|
117
|
+
}
|
|
118
|
+
function h(e, t = 0) {
|
|
119
|
+
if (typeof e == "number" && Number.isFinite(e)) return e;
|
|
120
|
+
if (typeof e == "string" && e.trim() !== "") {
|
|
121
|
+
const r = Number(e);
|
|
122
|
+
if (Number.isFinite(r)) return r;
|
|
123
|
+
}
|
|
124
|
+
return t;
|
|
125
|
+
}
|
|
126
|
+
function p(e) {
|
|
127
|
+
return e == null ? null : String(e);
|
|
128
|
+
}
|
|
129
|
+
function S(e) {
|
|
130
|
+
return Array.isArray(e) ? e.filter((t) => t != null).map((t) => String(t)) : [];
|
|
131
|
+
}
|
|
132
|
+
const V = [
|
|
133
|
+
"custom_check",
|
|
134
|
+
"minmax",
|
|
135
|
+
"nocheck",
|
|
136
|
+
"regexp",
|
|
137
|
+
"spatial"
|
|
138
|
+
];
|
|
139
|
+
function C(e) {
|
|
140
|
+
if (!c(e))
|
|
141
|
+
throw new _("Form details response is not a JSON object");
|
|
142
|
+
if (!c(e.form_header))
|
|
143
|
+
throw new _("Form details response has no form_header object");
|
|
144
|
+
if (!Array.isArray(e.form_body))
|
|
145
|
+
throw new _("Form details response has no form_body array");
|
|
146
|
+
const t = e.form_body.filter(c).map(P).sort((r, n) => r.position_order - n.position_order);
|
|
147
|
+
return {
|
|
148
|
+
header: D(e.form_header),
|
|
149
|
+
columns: t
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function D(e) {
|
|
153
|
+
return {
|
|
154
|
+
user: e.user,
|
|
155
|
+
form_id: h(e.form_id),
|
|
156
|
+
published_form_id: h(e.published_form_id),
|
|
157
|
+
name: String(e.name ?? ""),
|
|
158
|
+
description: p(e.description),
|
|
159
|
+
project_table: String(e.project_table ?? ""),
|
|
160
|
+
destination_table: String(e.destination_table ?? ""),
|
|
161
|
+
tracklog_mode: p(e.tracklog_mode),
|
|
162
|
+
observation_list: c(e.observation_list) ? e.observation_list : null,
|
|
163
|
+
periodic_notification: e.periodic_notification,
|
|
164
|
+
important_fields: Array.isArray(e.important_fields) ? e.important_fields.filter(c).map((t) => ({
|
|
165
|
+
...t,
|
|
166
|
+
column: String(t.column ?? ""),
|
|
167
|
+
type: String(t.type ?? "")
|
|
168
|
+
})) : [],
|
|
169
|
+
highlighted_fields: S(e.highlighted_fields)
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function P(e) {
|
|
173
|
+
const t = String(e.type ?? ""), r = String(e.column ?? "");
|
|
174
|
+
return {
|
|
175
|
+
column: r,
|
|
176
|
+
short_name: String(e.short_name ?? "") || r,
|
|
177
|
+
description: p(e.description),
|
|
178
|
+
type: $(t) ? t : z,
|
|
179
|
+
raw_type: t,
|
|
180
|
+
default_value: e.default_value ?? null,
|
|
181
|
+
relation: p(e.relation),
|
|
182
|
+
position_order: h(e.position_order),
|
|
183
|
+
validate: w(e.validate),
|
|
184
|
+
pseudo_column: p(e.pseudo_column),
|
|
185
|
+
api_params: M(e.api_params),
|
|
186
|
+
has_empty_line: l(e.has_empty_line),
|
|
187
|
+
list_definition: R(e.list_definition),
|
|
188
|
+
generated_list_elements: O(e.generated_list_elements),
|
|
189
|
+
filterable_list_elements: J(e.filterable_list_elements)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function w(e) {
|
|
193
|
+
if (!c(e))
|
|
194
|
+
return { required: !1, soft: !1, type: "nocheck", value: null };
|
|
195
|
+
const t = String(e.type ?? "nocheck");
|
|
196
|
+
return {
|
|
197
|
+
required: l(e.required),
|
|
198
|
+
soft: l(e.soft),
|
|
199
|
+
type: V.includes(t) ? t : "nocheck",
|
|
200
|
+
value: p(e.value)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function M(e) {
|
|
204
|
+
const t = c(e) ? e : {}, r = {
|
|
205
|
+
sticky: l(t.sticky),
|
|
206
|
+
hidden: l(t.hidden),
|
|
207
|
+
readonly: l(t.readonly),
|
|
208
|
+
list_elements_as_buttons: l(t.list_elements_as_buttons),
|
|
209
|
+
once_field: l(t.once_field),
|
|
210
|
+
unfolding_list: l(t.unfolding_list)
|
|
211
|
+
};
|
|
212
|
+
return "auto_geometry" in t && (r.auto_geometry = t.auto_geometry), r;
|
|
213
|
+
}
|
|
214
|
+
function R(e) {
|
|
215
|
+
return c(e) ? {
|
|
216
|
+
...e,
|
|
217
|
+
custom_list: l(e.custom_list),
|
|
218
|
+
extendable: l(e.extendable),
|
|
219
|
+
trigger_target_column: S(e.trigger_target_column),
|
|
220
|
+
selected: e.selected ?? null,
|
|
221
|
+
multiselect: l(e.multiselect)
|
|
222
|
+
} : null;
|
|
223
|
+
}
|
|
224
|
+
function O(e) {
|
|
225
|
+
return Array.isArray(e) ? e.filter(c).map((t) => {
|
|
226
|
+
const r = String(t.value ?? ""), n = String(t.label ?? "") || r, s = { value: r, label: n };
|
|
227
|
+
return t.filter_value !== void 0 && t.filter_value !== null && (s.filter_value = String(t.filter_value)), s;
|
|
228
|
+
}) : [];
|
|
229
|
+
}
|
|
230
|
+
function J(e) {
|
|
231
|
+
if (!c(e)) return null;
|
|
232
|
+
const t = {};
|
|
233
|
+
for (const [r, n] of Object.entries(e))
|
|
234
|
+
t[r] = O(n);
|
|
235
|
+
return t;
|
|
236
|
+
}
|
|
237
|
+
function B(e) {
|
|
238
|
+
let t = null;
|
|
239
|
+
const r = /* @__PURE__ */ new Map();
|
|
240
|
+
function n() {
|
|
241
|
+
return t ?? (t = b(e, "/forms").catch((i) => {
|
|
242
|
+
throw t = null, i;
|
|
243
|
+
})), t;
|
|
244
|
+
}
|
|
245
|
+
function s(i) {
|
|
246
|
+
let a = r.get(i);
|
|
247
|
+
return a || (a = b(e, `/forms/${i}`).then(C).catch((o) => {
|
|
248
|
+
throw r.delete(i), o;
|
|
249
|
+
}), r.set(i, a)), a;
|
|
250
|
+
}
|
|
251
|
+
async function u(i) {
|
|
252
|
+
const o = (await n()).find((f) => f.published_form_id === i);
|
|
253
|
+
if (!o)
|
|
254
|
+
throw new g(`Published form ${i} not found in the project's form list`);
|
|
255
|
+
return { formId: o.form_id, formVersion: o.last_modification_timestamp };
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
listForms: n,
|
|
259
|
+
getForm: s,
|
|
260
|
+
resolveLiveForm: u,
|
|
261
|
+
invalidate() {
|
|
262
|
+
t = null, r.clear();
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function k() {
|
|
267
|
+
if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
|
|
268
|
+
return crypto.randomUUID();
|
|
269
|
+
const e = crypto.getRandomValues(new Uint8Array(16));
|
|
270
|
+
e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
|
|
271
|
+
const t = Array.from(e, (r) => r.toString(16).padStart(2, "0")).join("");
|
|
272
|
+
return `${t.slice(0, 8)}-${t.slice(8, 12)}-${t.slice(12, 16)}-${t.slice(16, 20)}-${t.slice(20)}`;
|
|
273
|
+
}
|
|
274
|
+
function q(e) {
|
|
275
|
+
const t = Math.floor(Date.now() / 1e3);
|
|
276
|
+
return {
|
|
277
|
+
...e.extra,
|
|
278
|
+
id: k(),
|
|
279
|
+
app_version: e.appVersion ?? "obm-upload-form-ui",
|
|
280
|
+
form_version: e.formVersion,
|
|
281
|
+
timezone: -((/* @__PURE__ */ new Date()).getTimezoneOffset() / 60),
|
|
282
|
+
started_at: e.startedAt ?? t,
|
|
283
|
+
finished_at: e.finishedAt ?? t,
|
|
284
|
+
...e.rules !== void 0 ? { rules: e.rules } : {}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
class G extends g {
|
|
288
|
+
constructor(r) {
|
|
289
|
+
super("Submission refused by client-side validation");
|
|
290
|
+
y(this, "result");
|
|
291
|
+
this.result = r;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async function Y(e, t) {
|
|
295
|
+
let r;
|
|
296
|
+
if (t.validate && (r = L(
|
|
297
|
+
t.validate.schema,
|
|
298
|
+
t.data,
|
|
299
|
+
t.validate.state,
|
|
300
|
+
t.validate.options
|
|
301
|
+
), !j(r)))
|
|
302
|
+
throw new G(r);
|
|
303
|
+
const n = await A(e, `/forms/${t.formId}`, {
|
|
304
|
+
method: "POST",
|
|
305
|
+
headers: { "Content-Type": "application/json" },
|
|
306
|
+
body: JSON.stringify({ data: t.data, metadata: t.metadata })
|
|
307
|
+
});
|
|
308
|
+
return {
|
|
309
|
+
status: n.status,
|
|
310
|
+
message: await n.text(),
|
|
311
|
+
...r !== void 0 ? { validation: r } : {}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
async function ee(e, t, r = {}) {
|
|
315
|
+
const n = r.formApi ?? B(e), s = t.sharedId ?? k(), u = [], i = [
|
|
316
|
+
{ ref: "parent", item: t.parent },
|
|
317
|
+
...t.children.map((a, o) => ({ ref: o, item: a }))
|
|
318
|
+
];
|
|
319
|
+
for (let a = 0; a < i.length; a += 1) {
|
|
320
|
+
const { ref: o, item: f } = i[a];
|
|
321
|
+
try {
|
|
322
|
+
const d = await n.resolveLiveForm(f.publishedFormId), m = await Y(e, {
|
|
323
|
+
formId: d.formId,
|
|
324
|
+
data: { ...f.data, [t.sharedIdColumn]: s },
|
|
325
|
+
metadata: q({
|
|
326
|
+
formVersion: d.formVersion,
|
|
327
|
+
appVersion: e.appVersion,
|
|
328
|
+
rules: t.rules
|
|
329
|
+
})
|
|
330
|
+
});
|
|
331
|
+
u.push({ item: o, publishedFormId: f.publishedFormId, result: m });
|
|
332
|
+
} catch (d) {
|
|
333
|
+
return {
|
|
334
|
+
sharedId: s,
|
|
335
|
+
complete: !1,
|
|
336
|
+
succeeded: u,
|
|
337
|
+
failed: { item: o, publishedFormId: f.publishedFormId, error: d },
|
|
338
|
+
remaining: i.slice(a + 1).map(({ ref: m }) => m).filter((m) => m !== "parent")
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return { sharedId: s, complete: !0, succeeded: u, remaining: [] };
|
|
343
|
+
}
|
|
344
|
+
export {
|
|
345
|
+
le as DEFAULT_LANGUAGE,
|
|
346
|
+
ue as DEFAULT_VALIDATION_POLICY,
|
|
347
|
+
U as FORM_COLUMN_TYPES,
|
|
348
|
+
N as ObmApiError,
|
|
349
|
+
g as ObmError,
|
|
350
|
+
ne as ObmGeometryError,
|
|
351
|
+
T as ObmNetworkError,
|
|
352
|
+
_ as ObmSchemaError,
|
|
353
|
+
z as UNKNOWN_COLUMN_TYPE,
|
|
354
|
+
G as ValidationRefusedError,
|
|
355
|
+
A as apiFetch,
|
|
356
|
+
b as apiFetchJson,
|
|
357
|
+
X as bearerAuth,
|
|
358
|
+
q as buildMetadata,
|
|
359
|
+
j as canSubmit,
|
|
360
|
+
Q as cookieAuth,
|
|
361
|
+
B as createFormApi,
|
|
362
|
+
ce as formatMessage,
|
|
363
|
+
k as generateUuid,
|
|
364
|
+
ie as geoJSONToWkt,
|
|
365
|
+
fe as isEmpty,
|
|
366
|
+
oe as isWkt,
|
|
367
|
+
Z as jwtAuth,
|
|
368
|
+
E as normalizeBaseUrl,
|
|
369
|
+
C as normalizeFormDetails,
|
|
370
|
+
de as parseMinmaxBounds,
|
|
371
|
+
ee as submitLinked,
|
|
372
|
+
Y as submitObservation,
|
|
373
|
+
me as validateField,
|
|
374
|
+
L as validateForm,
|
|
375
|
+
se as wktToGeoJSON
|
|
376
|
+
};
|
|
377
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sources":["../src/core/config.ts","../src/core/client/auth.ts","../src/core/client/http.ts","../src/core/schema/guards.ts","../src/core/schema/normalize.ts","../src/core/client/formApi.ts","../src/core/submit/metadata.ts","../src/core/submit/submitClient.ts","../src/core/submit/linked.ts"],"sourcesContent":["import type { AuthStrategy } from './client/auth';\n\n/**\n * Project configuration, injected explicitly wherever the library talks to\n * the API — never read from globals (a deliberate break from the\n * thr_vizfolyasok precedent of module-level config constants).\n */\nexport interface ObmClientConfig {\n /**\n * Base URL of the project API, e.g.\n * \"https://example.org/projects/my_project/api/v3\". Trailing slash tolerated.\n */\n baseUrl: string;\n /**\n * Language sent as Accept-Language on reads. The API uses the first two\n * characters and falls back to the project language, then Hungarian.\n */\n language?: string;\n /** Client application identifier reported in upload metadata (`app_version`). */\n appVersion?: string;\n /** Authentication strategy; defaults to cookie/session auth. */\n auth?: AuthStrategy;\n /** Custom fetch implementation (tests, Node hosts). Defaults to globalThis.fetch. */\n fetchImpl?: typeof fetch;\n}\n\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '');\n}\n","/**\n * Pluggable authentication strategies. Which one applies depends entirely on\n * where the library is hosted (same-origin page, separate SPA, no-build host),\n * so auth is injected via ObmClientConfig, never assumed.\n */\nexport interface AuthStrategy {\n /** Adjust the outgoing request (headers/credentials) before it is sent. */\n apply(init: RequestInit & { headers: Headers }): void | Promise<void>;\n /**\n * Called once when a request gets HTTP 401. Return true to retry the\n * request (e.g. after refreshing a token).\n */\n onUnauthorized?(): Promise<boolean>;\n}\n\n/**\n * Same-origin session-cookie auth — the proven path for pages hosted inside\n * an OBM project (the API also accepts the `access_token` cookie).\n */\nexport function cookieAuth(): AuthStrategy {\n return {\n apply(init) {\n init.credentials = 'include';\n },\n };\n}\n\n/** Opaque or pre-obtained bearer token, supplied by the host. */\nexport function bearerAuth(tokenProvider: () => string | Promise<string>): AuthStrategy {\n return {\n async apply(init) {\n const token = await tokenProvider();\n if (token) {\n init.headers.set('Authorization', `Bearer ${token}`);\n }\n },\n };\n}\n\nexport interface JwtAuthOptions {\n /**\n * Endpoint returning a JWT for the current session, e.g. the spa_integration\n * host pattern `https://host/projects/<project>/<appName>/ajax?jwt`.\n * Fetched with credentials included (the session cookie authenticates it).\n */\n tokenUrl: string;\n fetchImpl?: typeof fetch;\n}\n\nfunction extractToken(body: string): string | null {\n const trimmed = body.trim();\n if (trimmed === '') return null;\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (typeof parsed === 'string') return parsed;\n if (typeof parsed === 'object' && parsed !== null) {\n const record = parsed as Record<string, unknown>;\n for (const key of ['token', 'jwt', 'access_token']) {\n if (typeof record[key] === 'string') return record[key];\n }\n }\n return null;\n } catch {\n // Not JSON: accept the raw body when it is JWT-shaped (three dot-separated segments).\n return /^[\\w-]+\\.[\\w-]+\\.[\\w-]+$/.test(trimmed) ? trimmed : null;\n }\n}\n\n/**\n * JWT auth that lazily fetches (and on 401 refreshes) its token from a host\n * endpoint. The refresh is single-flighted: concurrent 401s share one fetch.\n */\nexport function jwtAuth(options: JwtAuthOptions): AuthStrategy {\n const doFetch: typeof fetch =\n options.fetchImpl ?? ((...args: Parameters<typeof fetch>) => globalThis.fetch(...args));\n let token: string | null = null;\n let pendingRefresh: Promise<boolean> | null = null;\n\n async function refresh(): Promise<boolean> {\n const response = await doFetch(options.tokenUrl, { credentials: 'include' });\n if (!response.ok) {\n token = null;\n return false;\n }\n token = extractToken(await response.text());\n return token !== null;\n }\n\n function refreshOnce(): Promise<boolean> {\n pendingRefresh ??= refresh().finally(() => {\n pendingRefresh = null;\n });\n return pendingRefresh;\n }\n\n return {\n async apply(init) {\n if (token === null) {\n await refreshOnce();\n }\n if (token !== null) {\n init.headers.set('Authorization', `Bearer ${token}`);\n }\n init.credentials = 'include';\n },\n onUnauthorized() {\n token = null;\n return refreshOnce();\n },\n };\n}\n","import { normalizeBaseUrl, type ObmClientConfig } from '../config';\nimport { ObmApiError, ObmNetworkError, type ProblemDetails } from './errors';\n\n/**\n * Thin fetch wrapper shared by every API call: applies the configured auth\n * strategy and Accept-Language, retries once after a successful\n * auth.onUnauthorized() on 401, and turns non-2xx responses into ObmApiError\n * (parsing RFC 9457 Problem JSON bodies when present).\n */\nexport async function apiFetch(\n config: ObmClientConfig,\n path: string,\n init: RequestInit = {},\n): Promise<Response> {\n const url = normalizeBaseUrl(config.baseUrl) + path;\n const doFetch: typeof fetch =\n config.fetchImpl ?? ((...args: Parameters<typeof fetch>) => globalThis.fetch(...args));\n\n const send = async (): Promise<Response> => {\n const headers = new Headers(init.headers);\n if (config.language && !headers.has('Accept-Language')) {\n headers.set('Accept-Language', config.language);\n }\n const request: RequestInit & { headers: Headers } = { ...init, headers };\n await config.auth?.apply(request);\n try {\n return await doFetch(url, request);\n } catch (cause) {\n throw new ObmNetworkError(`Request to ${url} failed before a response arrived`, { cause });\n }\n };\n\n let response = await send();\n\n if (response.status === 401 && config.auth?.onUnauthorized) {\n const shouldRetry = await config.auth.onUnauthorized();\n if (shouldRetry) {\n response = await send();\n }\n }\n\n if (!response.ok) {\n throw new ObmApiError(response.status, ...(await readErrorBody(response)));\n }\n return response;\n}\n\nasync function readErrorBody(response: Response): Promise<[string, ProblemDetails | null]> {\n let body = '';\n try {\n body = await response.text();\n } catch {\n return ['', null];\n }\n const contentType = response.headers.get('Content-Type') ?? '';\n if (/application\\/(problem\\+)?json/.test(contentType)) {\n try {\n const parsed: unknown = JSON.parse(body);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return [body, parsed as ProblemDetails];\n }\n } catch {\n // fall through: keep the raw body\n }\n }\n return [body, null];\n}\n\n/** apiFetch + JSON body parsing. */\nexport async function apiFetchJson<T>(\n config: ObmClientConfig,\n path: string,\n init: RequestInit = {},\n): Promise<T> {\n const response = await apiFetch(config, path, init);\n return (await response.json()) as T;\n}\n","import { FORM_COLUMN_TYPES, type FormColumnType } from './types';\n\nexport function isFormColumnType(value: unknown): value is FormColumnType {\n return typeof value === 'string' && (FORM_COLUMN_TYPES as readonly string[]).includes(value);\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Tolerant boolean coercion for values that legacy data may deliver as\n * 0/1, '0'/'1', 't'/'f' or 'true'/'false' instead of JSON booleans.\n */\nexport function toBoolean(value: unknown, fallback = false): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'number') return value !== 0;\n if (typeof value === 'string') {\n const lowered = value.trim().toLowerCase();\n if (['1', 't', 'true', 'yes', 'on'].includes(lowered)) return true;\n if (['0', 'f', 'false', 'no', 'off', ''].includes(lowered)) return false;\n }\n return fallback;\n}\n\n/** Tolerant numeric coercion; returns the fallback for non-numeric input. */\nexport function toNumber(value: unknown, fallback = 0): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return fallback;\n}\n\nexport function toNullableString(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n return String(value);\n}\n\nexport function toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item) => item !== null && item !== undefined).map((item) => String(item));\n}\n","import { ObmSchemaError } from '../client/errors';\nimport {\n isFormColumnType,\n isPlainObject,\n toBoolean,\n toNullableString,\n toNumber,\n toStringArray,\n} from './guards';\nimport {\n UNKNOWN_COLUMN_TYPE,\n type ColumnSchema,\n type ColumnValidation,\n type FormApiParameters,\n type FormHeader,\n type FormListElement,\n type FormSchema,\n type ListDefinition,\n type ValidationControlType,\n} from './types';\n\nconst CONTROL_TYPES: readonly ValidationControlType[] = [\n 'custom_check',\n 'minmax',\n 'nocheck',\n 'regexp',\n 'spatial',\n];\n\n/**\n * Normalize a raw GET /forms/{publishedFormId} response into a FormSchema.\n *\n * Structural problems (not an object, missing form_body array) throw\n * ObmSchemaError. Per-column oddities never throw: the schema is re-derived\n * server-side from legacy data, so unknown types, missing blocks and loosely\n * typed booleans are smoothed into safe defaults instead.\n */\nexport function normalizeFormDetails(raw: unknown): FormSchema {\n if (!isPlainObject(raw)) {\n throw new ObmSchemaError('Form details response is not a JSON object');\n }\n if (!isPlainObject(raw.form_header)) {\n throw new ObmSchemaError('Form details response has no form_header object');\n }\n if (!Array.isArray(raw.form_body)) {\n throw new ObmSchemaError('Form details response has no form_body array');\n }\n\n const columns = raw.form_body\n .filter(isPlainObject)\n .map(normalizeColumn)\n .sort((a, b) => a.position_order - b.position_order);\n\n return {\n header: normalizeHeader(raw.form_header),\n columns,\n };\n}\n\nfunction normalizeHeader(raw: Record<string, unknown>): FormHeader {\n return {\n user: raw.user,\n form_id: toNumber(raw.form_id),\n published_form_id: toNumber(raw.published_form_id),\n name: String(raw.name ?? ''),\n description: toNullableString(raw.description),\n project_table: String(raw.project_table ?? ''),\n destination_table: String(raw.destination_table ?? ''),\n tracklog_mode: toNullableString(raw.tracklog_mode),\n observation_list: isPlainObject(raw.observation_list) ? raw.observation_list : null,\n periodic_notification: raw.periodic_notification,\n important_fields: Array.isArray(raw.important_fields)\n ? raw.important_fields.filter(isPlainObject).map((field) => ({\n ...field,\n column: String(field.column ?? ''),\n type: String(field.type ?? ''),\n }))\n : [],\n highlighted_fields: toStringArray(raw.highlighted_fields),\n };\n}\n\nfunction normalizeColumn(raw: Record<string, unknown>): ColumnSchema {\n const rawType = String(raw.type ?? '');\n const column = String(raw.column ?? '');\n return {\n column,\n short_name: String(raw.short_name ?? '') || column,\n description: toNullableString(raw.description),\n type: isFormColumnType(rawType) ? rawType : UNKNOWN_COLUMN_TYPE,\n raw_type: rawType,\n default_value: raw.default_value ?? null,\n relation: toNullableString(raw.relation),\n position_order: toNumber(raw.position_order),\n validate: normalizeValidation(raw.validate),\n pseudo_column: toNullableString(raw.pseudo_column),\n api_params: normalizeApiParams(raw.api_params),\n has_empty_line: toBoolean(raw.has_empty_line),\n list_definition: normalizeListDefinition(raw.list_definition),\n generated_list_elements: normalizeListElements(raw.generated_list_elements),\n filterable_list_elements: normalizeFilterableListElements(raw.filterable_list_elements),\n };\n}\n\nfunction normalizeValidation(raw: unknown): ColumnValidation {\n if (!isPlainObject(raw)) {\n return { required: false, soft: false, type: 'nocheck', value: null };\n }\n const type = String(raw.type ?? 'nocheck');\n return {\n required: toBoolean(raw.required),\n soft: toBoolean(raw.soft),\n type: (CONTROL_TYPES as readonly string[]).includes(type)\n ? (type as ValidationControlType)\n : 'nocheck',\n value: toNullableString(raw.value),\n };\n}\n\nfunction normalizeApiParams(raw: unknown): FormApiParameters {\n const source = isPlainObject(raw) ? raw : {};\n const params: FormApiParameters = {\n sticky: toBoolean(source.sticky),\n hidden: toBoolean(source.hidden),\n readonly: toBoolean(source.readonly),\n list_elements_as_buttons: toBoolean(source.list_elements_as_buttons),\n once_field: toBoolean(source.once_field),\n unfolding_list: toBoolean(source.unfolding_list),\n };\n if ('auto_geometry' in source) {\n params.auto_geometry = source.auto_geometry;\n }\n return params;\n}\n\nfunction normalizeListDefinition(raw: unknown): ListDefinition | null {\n if (!isPlainObject(raw)) return null;\n return {\n ...raw,\n custom_list: toBoolean(raw.custom_list),\n extendable: toBoolean(raw.extendable),\n trigger_target_column: toStringArray(raw.trigger_target_column),\n selected: raw.selected ?? null,\n multiselect: toBoolean(raw.multiselect),\n };\n}\n\nfunction normalizeListElements(raw: unknown): FormListElement[] {\n if (!Array.isArray(raw)) return [];\n return raw.filter(isPlainObject).map((element) => {\n const value = String(element.value ?? '');\n const label = String(element.label ?? '') || value;\n const normalized: FormListElement = { value, label };\n if (element.filter_value !== undefined && element.filter_value !== null) {\n normalized.filter_value = String(element.filter_value);\n }\n return normalized;\n });\n}\n\nfunction normalizeFilterableListElements(raw: unknown): Record<string, FormListElement[]> | null {\n if (!isPlainObject(raw)) return null;\n const normalized: Record<string, FormListElement[]> = {};\n for (const [filterValue, elements] of Object.entries(raw)) {\n normalized[filterValue] = normalizeListElements(elements);\n }\n return normalized;\n}\n","import type { ObmClientConfig } from '../config';\nimport { normalizeFormDetails } from '../schema/normalize';\nimport type { FormListItem, FormSchema } from '../schema/types';\nimport { ObmError } from './errors';\nimport { apiFetchJson } from './http';\n\nexport interface LiveFormRef {\n /** The live form id POST /forms/{formId} expects. */\n formId: number;\n /** The form's last_modification_timestamp, sent as metadata.form_version. */\n formVersion: number;\n}\n\nexport interface FormApi {\n /** GET /forms — memoized. */\n listForms(): Promise<FormListItem[]>;\n /** GET /forms/{publishedFormId}, normalized — memoized per id. */\n getForm(publishedFormId: number): Promise<FormSchema>;\n /**\n * Resolve a stable published form id to the live form id + version via the\n * form list. Host configs should store published ids; uploads need this\n * mapping (thr_vizfolyasok getFormMapping precedent).\n */\n resolveLiveForm(publishedFormId: number): Promise<LiveFormRef>;\n /** Drop all memoized responses. */\n invalidate(): void;\n}\n\nexport function createFormApi(config: ObmClientConfig): FormApi {\n // Promises (not results) are cached so concurrent callers share one request;\n // rejected promises are evicted so a retry re-fetches.\n let formListPromise: Promise<FormListItem[]> | null = null;\n const formPromises = new Map<number, Promise<FormSchema>>();\n\n function listForms(): Promise<FormListItem[]> {\n formListPromise ??= apiFetchJson<FormListItem[]>(config, '/forms').catch((error: unknown) => {\n formListPromise = null;\n throw error;\n });\n return formListPromise;\n }\n\n function getForm(publishedFormId: number): Promise<FormSchema> {\n let promise = formPromises.get(publishedFormId);\n if (!promise) {\n promise = apiFetchJson<unknown>(config, `/forms/${publishedFormId}`)\n .then(normalizeFormDetails)\n .catch((error: unknown) => {\n formPromises.delete(publishedFormId);\n throw error;\n });\n formPromises.set(publishedFormId, promise);\n }\n return promise;\n }\n\n async function resolveLiveForm(publishedFormId: number): Promise<LiveFormRef> {\n const forms = await listForms();\n const match = forms.find((form) => form.published_form_id === publishedFormId);\n if (!match) {\n throw new ObmError(`Published form ${publishedFormId} not found in the project's form list`);\n }\n return { formId: match.form_id, formVersion: match.last_modification_timestamp };\n }\n\n return {\n listForms,\n getForm,\n resolveLiveForm,\n invalidate() {\n formListPromise = null;\n formPromises.clear();\n },\n };\n}\n","/**\n * Upload metadata for POST /forms/{formId}. Field semantics follow the\n * working thr_vizfolyasok client (getBaseMetadata): epoch-second timestamps,\n * timezone as signed hours (UTC+2 → 2), a fresh UUID per observation.\n */\nexport interface UploadMetadata {\n /** Unique id of this observation upload; the API requires it. */\n id: string;\n app_version: string;\n /** The form's last_modification_timestamp (see FormApi.resolveLiveForm). */\n form_version: number | null;\n /** Signed offset from UTC in hours (UTC+2 → 2). */\n timezone: number;\n /** Epoch seconds. */\n started_at: number;\n /** Epoch seconds. */\n finished_at: number;\n rules?: Record<string, unknown>;\n [extension: string]: unknown;\n}\n\nexport interface BuildMetadataOptions {\n /** The form's last_modification_timestamp; null only when genuinely unknown. */\n formVersion: number | null;\n /** Client application identifier; falls back to the library's own name. */\n appVersion?: string;\n /** Epoch seconds; defaults to now. */\n startedAt?: number;\n /** Epoch seconds; defaults to now. */\n finishedAt?: number;\n /** Access rules, e.g. `{ write: [...user groups] }`. */\n rules?: Record<string, unknown>;\n /** Extra metadata fields spread into the payload (e.g. observation_list). */\n extra?: Record<string, unknown>;\n}\n\n/** crypto.randomUUID with a getRandomValues-based fallback for older webviews. */\nexport function generateUuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport function buildMetadata(options: BuildMetadataOptions): UploadMetadata {\n const nowSeconds = Math.floor(Date.now() / 1000);\n return {\n ...options.extra,\n id: generateUuid(),\n app_version: options.appVersion ?? 'obm-upload-form-ui',\n form_version: options.formVersion,\n timezone: -(new Date().getTimezoneOffset() / 60),\n started_at: options.startedAt ?? nowSeconds,\n finished_at: options.finishedAt ?? nowSeconds,\n ...(options.rules !== undefined ? { rules: options.rules } : {}),\n };\n}\n","import { ObmError } from '../client/errors';\nimport { apiFetch } from '../client/http';\nimport type { ObmClientConfig } from '../config';\nimport type { FormSchema } from '../schema/types';\nimport { canSubmit, validateForm } from '../validation/engine';\nimport type { DocumentState, ValidationOptions, ValidationResult } from '../validation/types';\nimport type { UploadMetadata } from './metadata';\n\n/** Thrown by submitObservation when its validation gate blocks the payload. */\nexport class ValidationRefusedError extends ObmError {\n readonly result: ValidationResult;\n\n constructor(result: ValidationResult) {\n super('Submission refused by client-side validation');\n this.result = result;\n }\n}\n\nexport interface SubmitValidationGate {\n schema: FormSchema;\n state: DocumentState;\n options?: ValidationOptions;\n}\n\nexport interface SubmitObservationOptions {\n /** The live form id (not the published id — see FormApi.resolveLiveForm). */\n formId: number;\n data: Record<string, unknown>;\n metadata: UploadMetadata;\n /**\n * Optional validation gate: when present, the payload is validated first\n * and a blocking result throws ValidationRefusedError. The refuse-vs-warn\n * knob lives in the gate's ValidationPolicy, not here.\n */\n validate?: SubmitValidationGate;\n}\n\nexport interface SubmitResult {\n status: number;\n /** The API responds 201 with a text/plain confirmation message. */\n message: string;\n /** Present when a validation gate ran (blocking or not). */\n validation?: ValidationResult;\n}\n\n/**\n * POST /forms/{formId} with the `{data, metadata}` JSON body. Success is\n * HTTP 201 with a text/plain body — not JSON. API errors arrive as\n * RFC 9457 Problem JSON and are thrown as ObmApiError by the HTTP layer.\n */\nexport async function submitObservation(\n config: ObmClientConfig,\n options: SubmitObservationOptions,\n): Promise<SubmitResult> {\n let validation: ValidationResult | undefined;\n if (options.validate) {\n validation = validateForm(\n options.validate.schema,\n options.data,\n options.validate.state,\n options.validate.options,\n );\n if (!canSubmit(validation)) {\n throw new ValidationRefusedError(validation);\n }\n }\n\n const response = await apiFetch(config, `/forms/${options.formId}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ data: options.data, metadata: options.metadata }),\n });\n\n return {\n status: response.status,\n message: await response.text(),\n ...(validation !== undefined ? { validation } : {}),\n };\n}\n","import { createFormApi, type FormApi } from '../client/formApi';\nimport type { ObmClientConfig } from '../config';\nimport { buildMetadata, generateUuid } from './metadata';\nimport { submitObservation, type SubmitResult } from './submitClient';\n\n/**\n * Linked submissions generalize the OBM convention for repeated/nested field\n * groups: the form schema is flat, so \"add another X\" data goes into separate\n * linked forms whose rows carry a client-generated shared UUID as a foreign\n * key (thr_vizfolyasok precedent: one parent POST + N child POSTs).\n */\nexport interface LinkedSubmissionItem {\n /** Stable published form id; resolved to the live form id at submit time. */\n publishedFormId: number;\n data: Record<string, unknown>;\n}\n\nexport interface LinkedSubmissionPlan {\n /** Data column that carries the shared UUID in the parent and every child. */\n sharedIdColumn: string;\n /** Shared UUID; generated when omitted. */\n sharedId?: string;\n parent: LinkedSubmissionItem;\n children: LinkedSubmissionItem[];\n /** Access rules included in every item's metadata, e.g. `{ write: [...] }`. */\n rules?: Record<string, unknown>;\n}\n\nexport type LinkedItemRef = 'parent' | number;\n\nexport interface LinkedItemSuccess {\n item: LinkedItemRef;\n publishedFormId: number;\n result: SubmitResult;\n}\n\nexport interface LinkedItemFailure {\n item: LinkedItemRef;\n publishedFormId: number;\n error: unknown;\n}\n\nexport interface LinkedSubmissionResult {\n sharedId: string;\n /** True when the parent and every child were accepted. */\n complete: boolean;\n succeeded: LinkedItemSuccess[];\n /** The first failing item; submission stops there. */\n failed?: LinkedItemFailure;\n /** Child indexes that were not attempted because of the failure. */\n remaining: number[];\n}\n\n/**\n * Submit a parent record and its linked children, all stamped with a shared\n * UUID, sequentially (parent first). Each POST gets fresh metadata with its\n * own id and the target form's version.\n *\n * There is NO server-side transaction — each POST hits the legacy upload\n * engine independently. On failure this resolves (never rejects) with\n * `failed` + `remaining` so the caller can retry the remainder with the same\n * `sharedId`.\n */\nexport async function submitLinked(\n config: ObmClientConfig,\n plan: LinkedSubmissionPlan,\n dependencies: { formApi?: FormApi } = {},\n): Promise<LinkedSubmissionResult> {\n const formApi = dependencies.formApi ?? createFormApi(config);\n const sharedId = plan.sharedId ?? generateUuid();\n const succeeded: LinkedItemSuccess[] = [];\n\n const items: { ref: LinkedItemRef; item: LinkedSubmissionItem }[] = [\n { ref: 'parent', item: plan.parent },\n ...plan.children.map((item, index) => ({ ref: index as LinkedItemRef, item })),\n ];\n\n for (let position = 0; position < items.length; position += 1) {\n const { ref, item } = items[position];\n try {\n const live = await formApi.resolveLiveForm(item.publishedFormId);\n const result = await submitObservation(config, {\n formId: live.formId,\n data: { ...item.data, [plan.sharedIdColumn]: sharedId },\n metadata: buildMetadata({\n formVersion: live.formVersion,\n appVersion: config.appVersion,\n rules: plan.rules,\n }),\n });\n succeeded.push({ item: ref, publishedFormId: item.publishedFormId, result });\n } catch (error) {\n return {\n sharedId,\n complete: false,\n succeeded,\n failed: { item: ref, publishedFormId: item.publishedFormId, error },\n remaining: items\n .slice(position + 1)\n .map(({ ref: laterRef }) => laterRef)\n .filter((laterRef): laterRef is number => laterRef !== 'parent'),\n };\n }\n }\n\n return { sharedId, complete: true, succeeded, remaining: [] };\n}\n"],"names":["normalizeBaseUrl","baseUrl","cookieAuth","init","bearerAuth","tokenProvider","token","extractToken","body","trimmed","parsed","record","key","jwtAuth","options","doFetch","args","pendingRefresh","refresh","response","refreshOnce","apiFetch","config","path","url","send","headers","request","_a","cause","ObmNetworkError","ObmApiError","readErrorBody","contentType","apiFetchJson","isFormColumnType","value","FORM_COLUMN_TYPES","isPlainObject","toBoolean","fallback","lowered","toNumber","toNullableString","toStringArray","item","CONTROL_TYPES","normalizeFormDetails","raw","ObmSchemaError","columns","normalizeColumn","a","b","normalizeHeader","field","rawType","column","UNKNOWN_COLUMN_TYPE","normalizeValidation","normalizeApiParams","normalizeListDefinition","normalizeListElements","normalizeFilterableListElements","type","source","params","element","label","normalized","filterValue","elements","createFormApi","formListPromise","formPromises","listForms","error","getForm","publishedFormId","promise","resolveLiveForm","match","form","ObmError","generateUuid","bytes","hex","byte","buildMetadata","nowSeconds","ValidationRefusedError","result","__publicField","submitObservation","validation","validateForm","canSubmit","submitLinked","plan","dependencies","formApi","sharedId","succeeded","items","index","position","ref","live","laterRef"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.dp--btn-base{font:inherit;transition:var(--dp-common-transition);border:none;line-height:normal}.dp--bg-none{background:0 0}.dp--active{background:var(--dp-primary-color);color:var(--dp-primary-text-color)}.dp--flex{align-items:center;display:flex}.dp--pointer{cursor:pointer}.dp--icon{stroke:currentColor;fill:currentColor}.dp--button{text-align:center;width:100%;color:var(--dp-icon-color);cursor:pointer;padding:var(--dp-common-padding);box-sizing:border-box;height:var(--dp-button-height);place-content:center;align-items:center;display:flex}.dp--button.dp--overlay-action{position:absolute;bottom:0}.dp--button .dp--main{font-family:var(--dp-font-family);-webkit-user-select:none;user-select:none;box-sizing:border-box;width:100%;position:relative}.dp--button .dp--main *{direction:var(--dp-direction,ltr)}.dp--button:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}.dp--button svg{height:var(--dp-button-icon-height);width:auto}.dp--button-bottom{border-bottom-left-radius:var(--dp-border-radius);border-bottom-right-radius:var(--dp-border-radius)}.dp--flex-display{display:flex}.dp--relative{position:relative}.dp--highlighted{background-color:var(--dp-highlight-color)}.dp--hidden-el{visibility:hidden}.dp--centered{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.dp--action-row{width:100%;padding:var(--dp-action-row-padding);box-sizing:border-box;color:var(--dp-text-color);flex-flow:row;align-items:center;display:flex}.dp--action-row svg{height:var(--dp-button-icon-height);width:auto}.dp--selection-preview{color:var(--dp-text-color);font-size:var(--dp-preview-font-size);white-space:nowrap;text-overflow:ellipsis;display:block;overflow:hidden}.dp--action-buttons{white-space:nowrap;flex:0;justify-content:flex-end;align-items:center;margin-inline-start:auto;display:flex}.dp--action-button{padding:var(--dp-action-buttons-padding);line-height:var(--dp-action-button-height);height:var(--dp-action-button-height);cursor:pointer;border-radius:var(--dp-border-radius);font-size:var(--dp-preview-font-size);font-family:var(--dp-font-family);background:0 0;border:1px solid #0000;align-items:center;margin-inline-start:3px;display:inline-flex}.dp--action-cancel{color:var(--dp-text-color);border:1px solid var(--dp-border-color)}.dp--action-cancel:hover{border-color:var(--dp-primary-color);transition:var(--dp-action-row-transition)}.dp--action-buttons .dp--action-select{background:var(--dp-primary-color);color:var(--dp-primary-text-color)}.dp--action-buttons .dp--action-select:hover{background:var(--dp-primary-color);transition:var(--dp-action-row-transition)}.dp--action-buttons .dp--action-select:disabled{background:var(--dp-primary-disabled-color);cursor:not-allowed}.dp--calendar-header{color:var(--dp-text-color);white-space:nowrap;justify-content:center;align-items:center;font-weight:700;display:flex;position:relative}.dp--calendar-header-item{text-align:center;height:var(--dp-cell-size);padding:var(--dp-cell-padding);width:var(--dp-cell-size);box-sizing:border-box;flex-grow:1}.dp--calendar-row{margin:var(--dp-row-margin);justify-content:center;align-items:center;display:flex}.dp--calendar-item{text-align:center;box-sizing:border-box;color:var(--dp-text-color);flex-grow:1}.dp--calendar{position:relative}.dp--calendar-header-cell{border-bottom:thin solid var(--dp-border-color);padding:var(--dp-calendar-header-cell-padding)}.dp--cell-inner{text-align:center;border-radius:var(--dp-cell-border-radius);height:var(--dp-cell-size);padding:var(--dp-cell-padding);width:var(--dp-cell-size);box-sizing:border-box;border:1px solid #0000;justify-content:center;align-items:center;display:flex;position:relative}.dp--cell-inner:hover{transition:all .2s}.dp--range-border-start{border-start-end-radius:0;border-end-end-radius:0}.dp--range-border-end{border-start-start-radius:0;border-end-start-radius:0}.dp--range-preview{border-top:1px dashed var(--dp-primary-color);border-bottom:1px dashed var(--dp-primary-color)}.dp--cell-offset{color:var(--dp-secondary-color)}.dp--cell-disabled{color:var(--dp-secondary-color);cursor:not-allowed}.dp--date-hoverable:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--date-hoverable-start:hover{border-start-end-radius:0;border-end-end-radius:0}.dp--date-hoverable-end:hover{border-start-start-radius:0;border-end-start-radius:0}.dp--range-between{background:var(--dp-range-between-dates-background-color);color:var(--dp-range-between-dates-text-color);border:1px solid var(--dp-range-between-border-color);border-radius:0}.dp--range-between-week{background:var(--dp-primary-color);color:var(--dp-primary-text-color);border-radius:0}.dp--today{border:1px solid var(--dp-primary-color)}.dp--week-num{color:var(--dp-secondary-color);text-align:center}.dp--cell-auto-range{border-radius:0}.dp--cell-auto-range-start{border-inline-start:1px dashed var(--dp-primary-color);border-start-start-radius:var(--dp-cell-border-radius);border-end-start-radius:var(--dp-cell-border-radius)}.dp--cell-auto-range-end{border-inline-end:1px dashed var(--dp-primary-color);border-start-end-radius:var(--dp-cell-border-radius);border-end-end-radius:var(--dp-cell-border-radius)}.dp--calendar-header-separator{background:var(--dp-border-color);width:100%;height:1px}.dp--calendar-next{margin-inline-start:var(--dp-multi-calendars-spacing)}.dp--marker-base{background-color:var(--dp-marker-color);height:5px;position:absolute;bottom:0}.dp--marker-dot{border-radius:50%;width:5px;left:50%;transform:translate(-50%)}.dp--marker-line{width:100%;left:0}.dp--marker-tooltip{border-radius:var(--dp-border-radius);background-color:var(--dp-tooltip-color);border:1px solid var(--dp-border-color);z-index:99999;box-sizing:border-box;cursor:default;padding:5px;position:absolute}.dp--tooltip-content{white-space:nowrap}.dp--tooltip-text{color:var(--dp-text-color);flex-flow:row;align-items:center;display:flex}.dp--tooltip-mark{background-color:var(--dp-text-color);width:5px;height:5px;color:var(--dp-text-color);border-radius:50%;margin-inline-end:5px}.dp--arrow-bottom-tp{background-color:var(--dp-tooltip-color);border-inline-end:1px solid var(--dp-border-color);border-bottom:1px solid var(--dp-border-color);width:8px;height:8px;position:absolute;bottom:0;transform:translate(-50%,50%)rotate(45deg)}.dp--instance-calendar{width:100%;position:relative}.dp--flex-display[data-dp-mobile],.dp--flex-display-collapsed{flex-direction:column}.dp--cell-highlight{background-color:var(--dp-highlight-color)}.dp--input-wrap{width:100%;box-sizing:unset;position:relative}.dp--input-wrap:focus{border-color:var(--dp-border-color-hover);outline:none}.dp--input-valid{box-shadow:0 0 var(--dp-border-radius) var(--dp-success-color);border-color:var(--dp-success-color)}.dp--input-valid:hover{border-color:var(--dp-success-color)}.dp--input-invalid{box-shadow:0 0 var(--dp-border-radius) var(--dp-danger-color);border-color:var(--dp-danger-color)}.dp--input-invalid:hover{border-color:var(--dp-danger-color)}.dp--input{background-color:var(--dp-background-color);border-radius:var(--dp-border-radius);font-family:var(--dp-font-family);border:1px solid var(--dp-border-color);width:100%;font-size:var(--dp-font-size);line-height:calc(var(--dp-font-size) * 1.5);padding:var(--dp-input-padding);color:var(--dp-text-color);box-sizing:border-box;outline:none;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.dp--input::placeholder{opacity:.7}.dp--input:hover:not(.dp--input-focus){border-color:var(--dp-border-color-hover)}.dp--input-not-clearable{padding-inline-end:var(--dp-input-not-clearable-padding)!important}.dp--input-reg{caret-color:#0000}.dp--input-focus{border-color:var(--dp-border-color-focus)}.dp--disabled{background:var(--dp-disabled-color)}.dp--disabled::placeholder{color:var(--dp-disabled-color-text)}.dp--input-icons{width:var(--dp-font-size);height:var(--dp-font-size);stroke-width:0;font-size:var(--dp-font-size);line-height:calc(var(--dp-font-size) * 1.5);color:var(--dp-icon-color);box-sizing:content-box;padding:6px 12px;display:inline-block}.dp--input-icon{cursor:pointer;top:50%;color:var(--dp-icon-color);position:absolute;inset-inline-start:0;transform:translateY(-50%)}.dp--clear-btn{top:50%;cursor:pointer;color:var(--dp-icon-color);background:0 0;border:none;align-items:center;margin:0;padding:0;display:inline-flex;position:absolute;inset-inline-end:0;transform:translateY(-50%)}.dp--input-icon-pad{padding-inline-start:var(--dp-input-icon-padding)}.dp--menu{background:var(--dp-background-color);border-radius:var(--dp-border-radius);min-width:var(--dp-menu-min-width);font-family:var(--dp-font-family);font-size:var(--dp-font-size);-webkit-user-select:none;user-select:none;border:1px solid var(--dp-menu-border-color);box-sizing:border-box}.dp--menu:after,.dp--menu:before{box-sizing:border-box}.dp--menu:focus{border:1px solid var(--dp-menu-border-color);outline:none}.dp--menu-wrapper{z-index:99999;position:absolute}.dp--menu-inner{padding:var(--dp-menu-padding)}.dp--menu--inner-stretched{padding:6px 0}.dp--menu-index{z-index:99999}.dp--menu-unclickable{z-index:999999;position:absolute;top:0;right:0;bottom:0;left:0}.dp--menu-disabled{cursor:not-allowed;background:#ffffff80}.dp--menu-readonly{cursor:default;background:0 0}.dp-menu-loading{cursor:default;background:#ffffff80}.dp--menu-load-container{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.dp--menu-loader{border:var(--dp-loader);box-sizing:border-box;border-bottom-color:#0000;border-radius:50%;width:48px;height:48px;animation:1s linear infinite dp-load-rotation;display:inline-block;position:absolute}@keyframes dp-load-rotation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.dp--arrow-top{background-color:var(--dp-background-color);border-inline-end:1px solid var(--dp-menu-border-color);border-top:1px solid var(--dp-menu-border-color);width:12px;height:12px;position:absolute;transform:translateY(-50%)rotate(-45deg)}.dp--arrow-bottom{left:var(--dp-arrow-left);background-color:var(--dp-background-color);border-inline-end:1px solid var(--dp-menu-border-color);border-bottom:1px solid var(--dp-menu-border-color);width:12px;height:12px;position:absolute;bottom:0;transform:translate(-50%,50%)rotate(45deg)}.dp--action-extra{text-align:center;padding:2px 0}.dp--preset-dates{border-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--preset-dates[data-dp-mobile],.dp--preset-dates-collapsed{max-width:calc(var(--dp-menu-width) - var(--dp-action-row-padding) * 2);border:none;align-self:center;display:flex;overflow-x:auto}.dp--sidebar-left{border-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--sidebar-right{margin-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--preset-range{text-align:left;white-space:nowrap;width:100%;color:var(--dp-text-color);border-radius:var(--dp-border-radius);transition:var(--dp-common-transition);padding:5px;display:block}.dp--preset-range:hover{background-color:var(--dp-hover-color);color:var(--dp-hover-text-color);cursor:pointer}.dp--preset-range[data-dp-mobile]{border:1px solid var(--dp-border-color);margin:0 3px}.dp--preset-range[data-dp-mobile]:first-child{margin-left:0}.dp--preset-range[data-dp-mobile]:last-child{margin-right:0}.dp--preset-range-collapsed{border:1px solid var(--dp-border-color);margin:0 3px}.dp--preset-range-collapsed:first-child{margin-left:0}.dp--preset-range-collapsed:last-child{margin-right:0}.dp--menu-content-wrapper{display:flex}.dp--menu-content-wrapper[data-dp-mobile],.dp--menu-content-wrapper-collapsed{flex-direction:column-reverse}.dp--month-year-row{height:var(--dp-month-year-row-height);color:var(--dp-text-color);box-sizing:border-box;align-items:center;display:flex}.dp--inner-nav{cursor:pointer;height:var(--dp-month-year-row-button-size);width:var(--dp-month-year-row-button-size);color:var(--dp-icon-color);text-align:center;border-radius:50%;justify-content:center;align-items:center;display:flex}.dp--inner-nav svg{height:var(--dp-button-icon-height);width:var(--dp-button-icon-height)}.dp--inner-nav:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}[dir=rtl] .dp--inner-nav{transform:rotate(180deg)}.dp--inner-nav-disabled,.dp--inner-nav-disabled:hover{background:var(--dp-disabled-color);color:var(--dp-disabled-color-text);cursor:not-allowed}.dp--month-year-select-base{text-align:center;cursor:pointer;height:var(--dp-month-year-row-height);border-radius:var(--dp-border-radius);box-sizing:border-box;color:var(--dp-text-color);justify-content:center;align-items:center;display:flex}.dp--month-year-select-base:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--month-year-select{width:50%}.dp--year-select{width:100%}.dp--month-year-wrap{flex-direction:row;align-items:center;width:100%;display:flex}.dp--year-disable-select{justify-content:space-around}.dp--header-wrap{flex-direction:column;width:100%;display:flex}.dp--year-mode-picker{width:100%;height:var(--dp-cell-size);justify-content:space-between;align-items:center;display:flex}.dp--arrow-btn-nav{transition:var(--dp-common-transition);height:100%}.dp-quarter-picker-wrap{height:100%;min-width:var(--dp-menu-min-width);flex-direction:column;display:flex}.dp--qr-btn-disabled{cursor:not-allowed;background:var(--dp-disabled-color)}.dp--qr-btn-disabled:hover{background:var(--dp-disabled-color)}.dp--qr-btn{width:100%;padding:var(--dp-common-padding)}.dp--qr-btn:not(.dp--highlighted,.dp--active,.dp--qr-btn-disabled,.dp--qr-btn-between){background:0 0}.dp--qr-btn:hover:not(.dp--active,.dp--qr-btn-disabled){background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--quarter-items{flex-direction:column;flex:1;justify-content:space-evenly;width:100%;height:100%;display:flex}.dp--qr-btn-between{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--overlay{background:var(--dp-background-color);z-index:99999;width:100%;font-family:var(--dp-font-family);color:var(--dp-text-color);box-sizing:border-box;transition:opacity 1s ease-out}.dp--overlay-absolute{height:100%;position:absolute;top:0;left:0}.dp--overlay-relative{position:relative}.dp--overlay-container::-webkit-scrollbar-track{box-shadow:var(--dp-scroll-bar-background);background-color:var(--dp-scroll-bar-background)}.dp--overlay-container::-webkit-scrollbar{background-color:var(--dp-scroll-bar-background);width:5px}.dp--overlay-container::-webkit-scrollbar-thumb{background-color:var(--dp-scroll-bar-color);border-radius:10px}.dp--overlay:focus{border:none;outline:none}.dp--container-flex{display:flex}.dp--container-block{display:block}.dp--overlay-container{height:var(--dp-overlay-height);flex-direction:column;overflow-y:auto}.dp--time-picker-overlay-container{height:100%}.dp--overlay-row{box-sizing:border-box;flex-wrap:wrap;align-items:center;width:100%;max-width:100%;margin-inline:auto;padding:0;display:flex}.dp--flex-row{flex:1}.dp--overlay-col{box-sizing:border-box;width:33%;padding:var(--dp-overlay-col-padding);white-space:nowrap}.dp--overlay-cell-pad{padding:var(--dp-common-padding) 0}.dp--overlay-cell-active,.dp--overlay-cell{cursor:pointer;border-radius:var(--dp-border-radius);text-align:center}.dp--overlay-cell:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--cell-in-between{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--over-action-scroll{box-sizing:border-box;right:5px}.dp--overlay-cell-disabled{cursor:not-allowed;background:var(--dp-disabled-color)}.dp--overlay-cell-disabled:hover{background:var(--dp-disabled-color)}.dp--overlay-cell-active-disabled{cursor:not-allowed;background:var(--dp-primary-disabled-color)}.dp--overlay-cell-active-disabled:hover{background:var(--dp-primary-disabled-color)}.dp--tp-wrap{width:100%}.dp--tp-wrap[data-dp-mobile]{max-width:100%}.dp--time-input{-webkit-user-select:none;user-select:none;width:100%;font-family:var(--dp-font-family);color:var(--dp-text-color);justify-content:center;align-items:center;display:flex}.dp--time-col-reg-block{padding:0 20px}.dp--time-col-reg-inline{padding:0 10px}.dp--time-col-reg-with-button{padding:0 15px}.dp--time-col-reg-with-button[data-compact~=true]{padding:0 5px}.dp--time-col-sec{padding:0 10px}.dp--time-col-sec-with-button{padding:0 5px}.dp--time-col-sec-with-button[data-collapsed~=true]{padding:0}.dp--time-col{text-align:center;flex-direction:column;justify-content:center;align-items:center;display:flex}.dp--time-col-block{font-size:var(--dp-time-font-size)}.dp--inc-dec-button-disabled,.dp--inc-dec-button-disabled:hover{background:var(--dp-disabled-color);color:var(--dp-disabled-color-text);cursor:not-allowed}.dp--time-display-block{padding:0 3px}.dp--time-display-inline{padding:5px}.dp--time-picker-inline-container{justify-content:center;width:100%;display:flex}.dp--inc-dec-button{height:var(--dp-time-inc-dec-button-size);width:var(--dp-time-inc-dec-button-size);cursor:pointer;color:var(--dp-icon-color);box-sizing:border-box;border-radius:50%;justify-content:center;align-items:center;margin:0;padding:5px;display:flex}.dp--inc-dec-button svg{height:var(--dp-time-inc-dec-button-size);width:var(--dp-time-inc-dec-button-size)}.dp--inc-dec-button:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}.dp--time-display{cursor:pointer;color:var(--dp-text-color);border-radius:var(--dp-border-radius);justify-content:center;align-items:center;display:flex}.dp--time-display:hover:enabled{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--inc-dec-button-inline{cursor:pointer;align-items:center;width:100%;height:8px;padding:0;display:flex}.dp--pm-am-button{background:var(--dp-primary-color);color:var(--dp-primary-text-color);padding:var(--dp-common-padding);border-radius:var(--dp-border-radius);cursor:pointer;border:none}.dp--pm-am-button[data-compact~=true]{padding:7px}.dp--tp-inline-btn-bar{background-color:var(--dp-secondary-color);width:100%;height:4px;transition:var(--dp-common-transition);border-collapse:collapse}.dp--tp-inline-btn-top:hover .dp--tp-btn-in-r{background-color:var(--dp-primary-color);transform:rotate(12deg)scale(1.15)translateY(-2px)}.dp--tp-inline-btn-top:hover .dp--tp-btn-in-l,.dp--tp-inline-btn-bottom:hover .dp--tp-btn-in-r{background-color:var(--dp-primary-color);transform:rotate(-12deg)scale(1.15)translateY(-2px)}.dp--tp-inline-btn-bottom:hover .dp--tp-btn-in-l{background-color:var(--dp-primary-color);transform:rotate(12deg)scale(1.15)translateY(-2px)}.dp--time-overlay-btn{background:0 0}.dp--time-invalid{background-color:var(--dp-disabled-color)}:root{--dp-common-transition:all .1s ease-in;--dp-menu-padding:6px 8px;--dp-animation-duration:.1s;--dp-menu-appear-transition-timing:cubic-bezier(.4, 0, 1, 1);--dp-transition-timing:ease-out;--dp-action-row-transition:all .2s ease-in;--dp-font-family:-apple-system, blinkmacsystemfont, "Segoe UI", roboto, oxygen, ubuntu, cantarell, "Open Sans", "Helvetica Neue", sans-serif;--dp-border-radius:4px;--dp-cell-border-radius:4px;--dp-transition-length:22px;--dp-transition-timing-general:.1s;--dp-button-height:35px;--dp-month-year-row-height:35px;--dp-month-year-row-button-size:25px;--dp-button-icon-height:20px;--dp-calendar-wrap-padding:0 5px;--dp-cell-size:35px;--dp-cell-padding:5px;--dp-common-padding:10px;--dp-input-icon-padding:35px;--dp-input-padding:6px 30px 6px 12px;--dp-input-not-clearable-padding:12px;--dp-menu-min-width:260px;--dp-action-buttons-padding:1px 6px;--dp-row-margin:5px 0;--dp-calendar-header-cell-padding:8px;--dp-multi-calendars-spacing:10px;--dp-overlay-col-padding:3px;--dp-time-inc-dec-button-size:32px;--dp-font-size:1rem;--dp-preview-font-size:.8rem;--dp-time-font-size:2rem;--dp-action-button-height:22px;--dp-action-row-padding:8px;--dp-direction:ltr}.dp--theme-dark{--dp-background-color:#212121;--dp-text-color:#fff;--dp-hover-color:#484848;--dp-hover-text-color:#fff;--dp-hover-icon-color:#959595;--dp-primary-color:#005cb2;--dp-primary-disabled-color:#61a8ea;--dp-primary-text-color:#fff;--dp-secondary-color:#a9a9a9;--dp-border-color:#2d2d2d;--dp-menu-border-color:#2d2d2d;--dp-border-color-hover:#aaaeb7;--dp-border-color-focus:#aaaeb7;--dp-disabled-color:#737373;--dp-disabled-color-text:#d0d0d0;--dp-scroll-bar-background:#212121;--dp-scroll-bar-color:#484848;--dp-success-color:#00701a;--dp-success-color-disabled:#428f59;--dp-icon-color:#959595;--dp-danger-color:#e53935;--dp-marker-color:#e53935;--dp-tooltip-color:#3e3e3e;--dp-highlight-color:#005cb233;--dp-range-between-dates-background-color:var(--dp-hover-color,#484848);--dp-range-between-dates-text-color:var(--dp-hover-text-color,#fff);--dp-range-between-border-color:var(--dp-hover-color,#fff);--dp-loader:5px solid #005cb2}.dp--theme-light{--dp-background-color:#fff;--dp-text-color:#212121;--dp-hover-color:#f3f3f3;--dp-hover-text-color:#212121;--dp-hover-icon-color:#959595;--dp-primary-color:#1976d2;--dp-primary-disabled-color:#6bacea;--dp-primary-text-color:#fff;--dp-secondary-color:#c0c4cc;--dp-border-color:#ddd;--dp-menu-border-color:#ddd;--dp-border-color-hover:#aaaeb7;--dp-border-color-focus:#aaaeb7;--dp-disabled-color:#f6f6f6;--dp-scroll-bar-background:#f3f3f3;--dp-scroll-bar-color:#959595;--dp-success-color:#76d275;--dp-success-color-disabled:#a3d9b1;--dp-icon-color:#959595;--dp-danger-color:#ff6f60;--dp-marker-color:#ff6f60;--dp-tooltip-color:#fafafa;--dp-disabled-color-text:#8e8e8e;--dp-highlight-color:#1976d21a;--dp-range-between-dates-background-color:var(--dp-hover-color,#f3f3f3);--dp-range-between-dates-text-color:var(--dp-hover-text-color,#212121);--dp-range-between-border-color:var(--dp-hover-color,#f3f3f3);--dp-loader:5px solid #1976d2}.calendar-next-enter-active,.calendar-next-leave-active,.calendar-prev-enter-active,.calendar-prev-leave-active{transition:all var(--dp-transition-timing-general) ease-out}.calendar-next-enter-from{opacity:0;transform:translate(var(--dp-transition-length))}.calendar-next-leave-to,.calendar-prev-enter-from{opacity:0;transform:translate(calc(var(--dp-transition-length) * -1))}.calendar-prev-leave-to{opacity:0;transform:translate(var(--dp-transition-length))}.dp-menu-appear-bottom-enter-active,.dp-menu-appear-bottom-leave-active,.dp-menu-appear-top-enter-active,.dp-menu-appear-top-leave-active,.dp-slide-up-enter-active,.dp-slide-up-leave-active,.dp-slide-down-enter-active,.dp-slide-down-leave-active{transition:all var(--dp-animation-duration) var(--dp-transition-timing)}.dp-menu-appear-top-enter-from,.dp-menu-appear-top-leave-to,.dp-slide-down-leave-to,.dp-slide-up-enter-from{opacity:0;transform:translateY(var(--dp-transition-length))}.dp-menu-appear-bottom-enter-from,.dp-menu-appear-bottom-leave-to,.dp-slide-down-enter-from,.dp-slide-up-leave-to{opacity:0;transform:translateY(calc(var(--dp-transition-length) * -1))}.dp--flex-display-with-input{flex-direction:column;align-items:flex-start}
|