@qaecy/cue-sdk 0.0.27 → 0.0.29
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/README.md +97 -0
- package/{cue-CzxsQ6aP.js → cue-CnZyGMRG.js} +913 -841
- package/index.js +1 -1
- package/lib/documents.d.ts +50 -0
- package/lib/entities.d.ts +19 -0
- package/node.js +2 -2
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { getApps as
|
|
2
|
-
import { ref as _, getDownloadURL as
|
|
3
|
-
import { Writer as
|
|
4
|
-
import { getFirestore as
|
|
5
|
-
import { getAuth as
|
|
6
|
-
import { v5 as
|
|
1
|
+
import { getApps as be, initializeApp as ve } from "firebase/app";
|
|
2
|
+
import { ref as _, getDownloadURL as K, getMetadata as M, getBlob as re, updateMetadata as _e, uploadBytesResumable as ft, uploadBytes as st, StringFormat as ke, uploadString as Ee, listAll as z, getStorage as T, connectStorageEmulator as Q } from "firebase/storage";
|
|
3
|
+
import { Writer as xe, DataFactory as j } from "n3";
|
|
4
|
+
import { getFirestore as Ie, connectFirestoreEmulator as Ce, collection as yt, getDocs as Te, query as Se, where as Re, limit as Ae, doc as bt, getDoc as Pe, setDoc as Oe, serverTimestamp as De, increment as Le } from "firebase/firestore";
|
|
5
|
+
import { getAuth as qe, connectAuthEmulator as je, onIdTokenChanged as Ue, getIdTokenResult as at, signInWithEmailAndPassword as Me, GoogleAuthProvider as it, OAuthProvider as nt, signInWithPopup as ze, signInWithRedirect as Ne, getRedirectResult as $e, signInWithCustomToken as vt, signOut as Fe, onAuthStateChanged as Be, fetchSignInMethodsForEmail as Ge, linkWithPopup as He, unlink as We, reauthenticateWithCredential as _t, EmailAuthProvider as X, updatePassword as Ve, linkWithCredential as Ke, verifyBeforeUpdateEmail as Qe, sendEmailVerification as Xe } from "firebase/auth";
|
|
6
|
+
import { v5 as Ye } from "uuid";
|
|
7
7
|
import "spark-md5";
|
|
8
|
-
import { getFunctions as
|
|
9
|
-
class
|
|
8
|
+
import { getFunctions as se, connectFunctionsEmulator as ae, httpsCallable as F } from "firebase/functions";
|
|
9
|
+
class ht {
|
|
10
10
|
queryEndpoint;
|
|
11
11
|
updateEndpoint;
|
|
12
12
|
baseHeaders;
|
|
@@ -18,7 +18,7 @@ class lt {
|
|
|
18
18
|
constructor(t) {
|
|
19
19
|
this.queryEndpoint = t.queryEndpoint, this.updateEndpoint = t.updateEndpoint, this.baseHeaders = Object.fromEntries(
|
|
20
20
|
Object.entries(t.originalHeaders || {}).filter(
|
|
21
|
-
([e]) =>
|
|
21
|
+
([e]) => ht.RELEVANT_HEADER_KEYS.includes(e)
|
|
22
22
|
)
|
|
23
23
|
), t.authHeader !== void 0 && (this.baseHeaders.Authorization = t.authHeader);
|
|
24
24
|
}
|
|
@@ -81,7 +81,7 @@ class lt {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
class
|
|
84
|
+
class Y extends Error {
|
|
85
85
|
constructor(t) {
|
|
86
86
|
super(`QLever is locked (rebuild in progress): ${t}`), this.name = "QLeverLockedError";
|
|
87
87
|
}
|
|
@@ -119,7 +119,7 @@ class R {
|
|
|
119
119
|
try {
|
|
120
120
|
return await t();
|
|
121
121
|
} catch (a) {
|
|
122
|
-
if (r = a, a instanceof
|
|
122
|
+
if (r = a, a instanceof Y && s < e) {
|
|
123
123
|
const n = 0.5 + Math.random(), p = o * Math.pow(2, s) * n;
|
|
124
124
|
await new Promise((c) => setTimeout(c, p));
|
|
125
125
|
continue;
|
|
@@ -184,7 +184,7 @@ class R {
|
|
|
184
184
|
});
|
|
185
185
|
if (!e.ok) {
|
|
186
186
|
const o = await e.text();
|
|
187
|
-
throw e.status === 423 ? new
|
|
187
|
+
throw e.status === 423 ? new Y(o) : new Error(`SPARQL update failed (HTTP ${e.status}): ${o}`);
|
|
188
188
|
}
|
|
189
189
|
return await e.json();
|
|
190
190
|
});
|
|
@@ -204,7 +204,7 @@ class R {
|
|
|
204
204
|
await this._postToDataEndpoint(t, `${this.dataEndpoint}/delete`);
|
|
205
205
|
}
|
|
206
206
|
async _postToDataEndpoint(t, e) {
|
|
207
|
-
const o = await this._quadsToNQuads(t), r = await
|
|
207
|
+
const o = await this._quadsToNQuads(t), r = await Ze(Buffer.from(o, "utf-8"));
|
|
208
208
|
await R._retryOnLocked(async () => {
|
|
209
209
|
const s = await fetch(e, {
|
|
210
210
|
method: "POST",
|
|
@@ -217,18 +217,18 @@ class R {
|
|
|
217
217
|
});
|
|
218
218
|
if (!s.ok) {
|
|
219
219
|
const a = await s.text();
|
|
220
|
-
throw s.status === 423 ? new
|
|
220
|
+
throw s.status === 423 ? new Y(a) : new Error(`QLever data POST failed (HTTP ${s.status}): ${a}`);
|
|
221
221
|
}
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
224
|
_quadsToNQuads(t) {
|
|
225
225
|
return new Promise((e, o) => {
|
|
226
|
-
const r = new
|
|
226
|
+
const r = new xe({ format: "application/n-quads" });
|
|
227
227
|
r.addQuads(t), r.end((s, a) => s ? o(s) : e(a));
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
async function
|
|
231
|
+
async function Ze(i) {
|
|
232
232
|
const t = new CompressionStream("gzip"), e = t.writable.getWriter();
|
|
233
233
|
e.write(new Uint8Array(i)), e.close();
|
|
234
234
|
const o = [], r = t.readable.getReader();
|
|
@@ -243,14 +243,14 @@ async function Ye(i) {
|
|
|
243
243
|
a.set(p, n), n += p.byteLength;
|
|
244
244
|
return a.buffer;
|
|
245
245
|
}
|
|
246
|
-
class
|
|
246
|
+
class Je {
|
|
247
247
|
constructor(t) {
|
|
248
248
|
switch (this.options = t, this.options.graphType) {
|
|
249
249
|
case "qlever":
|
|
250
250
|
this._db = new R(this.options);
|
|
251
251
|
break;
|
|
252
252
|
case "fuseki":
|
|
253
|
-
this._db = new
|
|
253
|
+
this._db = new ht(this.options);
|
|
254
254
|
break;
|
|
255
255
|
default:
|
|
256
256
|
throw new Error(`Unsupported graph type: ${this.options.graphType}`);
|
|
@@ -298,7 +298,7 @@ class Ze {
|
|
|
298
298
|
return this.options.graphType === "qlever" ? this._db.deleteData(t) : Promise.reject(new Error("deleteData not supported for Fuseki — use update() with SPARQL DELETE DATA"));
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
class
|
|
301
|
+
class kt {
|
|
302
302
|
constructor(t) {
|
|
303
303
|
this.options = t;
|
|
304
304
|
}
|
|
@@ -327,7 +327,7 @@ class _t {
|
|
|
327
327
|
async getDownloadURL(t, e) {
|
|
328
328
|
const o = _(this._bucket(t), e);
|
|
329
329
|
try {
|
|
330
|
-
return await
|
|
330
|
+
return await K(o);
|
|
331
331
|
} catch (r) {
|
|
332
332
|
if (r?.code === "storage/object-not-found") return;
|
|
333
333
|
throw r;
|
|
@@ -343,7 +343,7 @@ class _t {
|
|
|
343
343
|
const r = _(this._bucket(t), e);
|
|
344
344
|
try {
|
|
345
345
|
const s = await M(r);
|
|
346
|
-
return `${await
|
|
346
|
+
return `${await K(r)}&t=${encodeURIComponent(s.updated)}`;
|
|
347
347
|
} catch (s) {
|
|
348
348
|
if (s?.code === "storage/object-not-found" || s?.status === 404) {
|
|
349
349
|
this._knownMissing.add(o), console.debug(`[CueBlobStorage] ${e} not found (404 OK — optional cache file)`);
|
|
@@ -356,7 +356,7 @@ class _t {
|
|
|
356
356
|
async getFile(t, e) {
|
|
357
357
|
const o = _(this._bucket(t), e);
|
|
358
358
|
try {
|
|
359
|
-
return await
|
|
359
|
+
return await re(o);
|
|
360
360
|
} catch (r) {
|
|
361
361
|
if (r?.code === "storage/object-not-found") return;
|
|
362
362
|
throw r;
|
|
@@ -382,7 +382,7 @@ class _t {
|
|
|
382
382
|
]);
|
|
383
383
|
try {
|
|
384
384
|
const [a, n] = await Promise.all([
|
|
385
|
-
s(
|
|
385
|
+
s(K(e)),
|
|
386
386
|
s(M(e))
|
|
387
387
|
]), p = `${a}&t=${encodeURIComponent(n.updated)}`, c = await fetch(p, { signal: o.signal });
|
|
388
388
|
if (!c.ok) throw new Error(`HTTP ${c.status}`);
|
|
@@ -414,7 +414,7 @@ class _t {
|
|
|
414
414
|
/** Update custom metadata on an existing file. */
|
|
415
415
|
async setMetadata(t, e, o) {
|
|
416
416
|
const r = _(this._bucket(t), e);
|
|
417
|
-
await
|
|
417
|
+
await _e(r, { customMetadata: o });
|
|
418
418
|
}
|
|
419
419
|
// ─── Uploads ──────────────────────────────────────────────────────────────
|
|
420
420
|
/**
|
|
@@ -423,7 +423,7 @@ class _t {
|
|
|
423
423
|
* upload progress needs to be surfaced in the UI.
|
|
424
424
|
*/
|
|
425
425
|
uploadResumable(t, e, o, r) {
|
|
426
|
-
const s = _(this._bucket(t), e), a =
|
|
426
|
+
const s = _(this._bucket(t), e), a = ft(s, o, r ? { customMetadata: r } : void 0);
|
|
427
427
|
return {
|
|
428
428
|
complete: () => new Promise((n, p) => a.then(() => n(), p)),
|
|
429
429
|
pause: () => a.pause(),
|
|
@@ -443,12 +443,12 @@ class _t {
|
|
|
443
443
|
*/
|
|
444
444
|
async uploadBytes(t, e, o, r) {
|
|
445
445
|
const s = _(this._bucket(t), e);
|
|
446
|
-
await
|
|
446
|
+
await st(s, o, r ? { customMetadata: r } : void 0);
|
|
447
447
|
}
|
|
448
448
|
/** Upload a string or base64-encoded value. */
|
|
449
|
-
async uploadString(t, e, o, r =
|
|
449
|
+
async uploadString(t, e, o, r = ke.RAW, s) {
|
|
450
450
|
const a = _(this._bucket(t), e);
|
|
451
|
-
await
|
|
451
|
+
await Ee(a, o, r, s ? { customMetadata: s } : void 0);
|
|
452
452
|
}
|
|
453
453
|
// ─── Listing ──────────────────────────────────────────────────────────────
|
|
454
454
|
/** List all item names directly under `prefix` in the given bucket. */
|
|
@@ -499,7 +499,7 @@ class _t {
|
|
|
499
499
|
d(new DOMException("Upload cancelled", "AbortError"));
|
|
500
500
|
return;
|
|
501
501
|
}
|
|
502
|
-
const g =
|
|
502
|
+
const g = ft(n, e, { customMetadata: o }), w = () => {
|
|
503
503
|
g.cancel(), d(new DOMException("Upload cancelled", "AbortError"));
|
|
504
504
|
};
|
|
505
505
|
s?.addEventListener("abort", w, { once: !0 }), g.on(
|
|
@@ -532,7 +532,7 @@ class _t {
|
|
|
532
532
|
*/
|
|
533
533
|
async uploadProcessed(t, e, o) {
|
|
534
534
|
const r = _(this.options.storageProcessed, t);
|
|
535
|
-
return await M(r).catch(() => null) ? !1 : (await
|
|
535
|
+
return await M(r).catch(() => null) ? !1 : (await st(r, e, { customMetadata: o }), !0);
|
|
536
536
|
}
|
|
537
537
|
/** List all blob names directly under `prefix` in the raw bucket. */
|
|
538
538
|
async listRaw(t) {
|
|
@@ -540,7 +540,7 @@ class _t {
|
|
|
540
540
|
return (await z(e)).items.map((r) => r.name);
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
|
-
const
|
|
543
|
+
const Et = {
|
|
544
544
|
ä: "ae",
|
|
545
545
|
ä: "ae",
|
|
546
546
|
Ä: "AE",
|
|
@@ -576,15 +576,15 @@ const kt = {
|
|
|
576
576
|
};
|
|
577
577
|
function D(i, t = !1) {
|
|
578
578
|
const e = "daca0510-72b5-48ba-9091-b918ca18136b";
|
|
579
|
-
return i =
|
|
579
|
+
return i = to(i, t), Ye(i, e);
|
|
580
580
|
}
|
|
581
|
-
function
|
|
581
|
+
function to(i, t = !1) {
|
|
582
582
|
let e = i;
|
|
583
|
-
for (const o in
|
|
584
|
-
e = e.replace(new RegExp(o, "g"),
|
|
583
|
+
for (const o in Et)
|
|
584
|
+
e = e.replace(new RegExp(o, "g"), Et[o]);
|
|
585
585
|
return t && e !== i && console.info(`${i} -> ${e}`), e;
|
|
586
586
|
}
|
|
587
|
-
function
|
|
587
|
+
function eo(i, t = "") {
|
|
588
588
|
return D(`${t}${i}`);
|
|
589
589
|
}
|
|
590
590
|
class k {
|
|
@@ -608,7 +608,7 @@ class k {
|
|
|
608
608
|
return this;
|
|
609
609
|
}
|
|
610
610
|
}
|
|
611
|
-
function
|
|
611
|
+
function dt(i, t) {
|
|
612
612
|
const e = /* @__PURE__ */ new Set();
|
|
613
613
|
let o = t(), r = !1;
|
|
614
614
|
const s = [], a = () => {
|
|
@@ -630,7 +630,7 @@ function ct(i, t) {
|
|
|
630
630
|
}
|
|
631
631
|
};
|
|
632
632
|
}
|
|
633
|
-
async function
|
|
633
|
+
async function gt(i, t, e, o) {
|
|
634
634
|
const r = D(i);
|
|
635
635
|
let s;
|
|
636
636
|
if (o) {
|
|
@@ -642,12 +642,12 @@ async function ht(i, t, e, o) {
|
|
|
642
642
|
(p) => console.error("[staleWhileRevalidate] Cache write failed:", p)
|
|
643
643
|
), a;
|
|
644
644
|
}
|
|
645
|
-
const
|
|
645
|
+
const Z = {
|
|
646
646
|
apiKey: "AIzaSyAiW42QBx9HS4Khu88pCW7MV66IhBAQul0",
|
|
647
647
|
appId: "1:151132927589:web:d2ffdb377dfadfd23ab88c",
|
|
648
648
|
measurementId: "G-YT4PK6HGZD"
|
|
649
|
-
},
|
|
650
|
-
class
|
|
649
|
+
}, xt = "qaecy-mvp-406413", oo = "734737865998", ie = "europe-west6", It = "projects", Ct = "spaces_chats_eu_west6", Tt = "spaces_raw_eu_west6", St = "spaces_processed_eu_west6", Rt = "spaces_logs_eu_west6", At = "cue_public_eu_west6", Pt = "db_persistence_eu_west6", ro = "/data-views/admin/consumption", so = "/data-views/admin/profile/organizations", Ot = "/data-views/admin/profile/api-keys", Dt = "/commands/admin/profile/api-keys", ao = "/commands/admin/profile/terms", io = (i) => `/data-views/admin/organizations/${i}/members`, no = "/commands/admin/project", po = (i) => `/commands/admin/project/${i}`, lo = "/assistant/search", ne = "/triplestore/query", co = "/triplestore/update", ho = "/triplestore/shacl", pe = "/qlever-server/qlever/query", go = "/qlever-server/qlever/update", uo = "/qlever-server/qlever/shacl", Lt = "/commands/file-system-structure/batch", qt = "microsoft.com", jt = "superadmin", ut = "https://cue.qaecy.com/r/";
|
|
650
|
+
class Ut {
|
|
651
651
|
_auth;
|
|
652
652
|
_endpoints;
|
|
653
653
|
_userSignal = new k(null);
|
|
@@ -664,19 +664,19 @@ class jt {
|
|
|
664
664
|
/** All unique UIDs for the current user (Firebase UID + linked provider UIDs). */
|
|
665
665
|
userIds;
|
|
666
666
|
constructor(t, e = !1, o) {
|
|
667
|
-
this._auth =
|
|
667
|
+
this._auth = qe(t), this._endpoints = o, e && je(this._auth, o.authEmulatorUrl, {
|
|
668
668
|
disableWarnings: !0
|
|
669
|
-
}), this.user = this._userSignal.asReadonly(), this.token = this._tokenSignal.asReadonly(), this.isSuperAdmin = this._isSuperAdminSignal.asReadonly(), this._userIdsSignal =
|
|
669
|
+
}), this.user = this._userSignal.asReadonly(), this.token = this._tokenSignal.asReadonly(), this.isSuperAdmin = this._isSuperAdminSignal.asReadonly(), this._userIdsSignal = dt([this._userSignal], () => {
|
|
670
670
|
const r = this._userSignal.get();
|
|
671
671
|
if (!r) return [];
|
|
672
672
|
const s = /* @__PURE__ */ new Set([r.uid]);
|
|
673
673
|
return r.providerData.forEach((a) => s.add(a.uid)), Array.from(s);
|
|
674
|
-
}), this.userIds = this._userIdsSignal, this._stopTokenListener =
|
|
674
|
+
}), this.userIds = this._userIdsSignal, this._stopTokenListener = Ue(this._auth, async (r) => {
|
|
675
675
|
if (this._userSignal.set(r), r) {
|
|
676
676
|
const s = await r.getIdToken();
|
|
677
677
|
this._tokenSignal.set(s);
|
|
678
|
-
const a = await
|
|
679
|
-
this._isSuperAdminSignal.set(a.claims.role ===
|
|
678
|
+
const a = await at(r);
|
|
679
|
+
this._isSuperAdminSignal.set(a.claims.role === jt);
|
|
680
680
|
} else
|
|
681
681
|
this._tokenSignal.set(null), this._isSuperAdminSignal.set(!1);
|
|
682
682
|
});
|
|
@@ -689,14 +689,14 @@ class jt {
|
|
|
689
689
|
if (t === "password") {
|
|
690
690
|
if (!e)
|
|
691
691
|
throw new Error("credentials are required for password sign-in");
|
|
692
|
-
return (await
|
|
692
|
+
return (await Me(
|
|
693
693
|
this._auth,
|
|
694
694
|
e.email,
|
|
695
695
|
e.password
|
|
696
696
|
)).user;
|
|
697
697
|
}
|
|
698
|
-
const o = t === "google" ? new
|
|
699
|
-
return (await
|
|
698
|
+
const o = t === "google" ? new it() : new nt(qt);
|
|
699
|
+
return (await ze(this._auth, o)).user;
|
|
700
700
|
}
|
|
701
701
|
/**
|
|
702
702
|
* Initiate a redirect-based sign-in (mobile / iframe contexts where popups
|
|
@@ -704,8 +704,8 @@ class jt {
|
|
|
704
704
|
* retrieve the result.
|
|
705
705
|
*/
|
|
706
706
|
async signInWithRedirect(t) {
|
|
707
|
-
const e = t === "google" ? new
|
|
708
|
-
await
|
|
707
|
+
const e = t === "google" ? new it() : new nt(qt);
|
|
708
|
+
await Ne(this._auth, e);
|
|
709
709
|
}
|
|
710
710
|
/**
|
|
711
711
|
* Retrieve the result of a redirect sign-in. Returns the signed-in `User`
|
|
@@ -713,7 +713,7 @@ class jt {
|
|
|
713
713
|
* Call this once on app startup before showing a sign-in UI.
|
|
714
714
|
*/
|
|
715
715
|
async checkRedirectResult() {
|
|
716
|
-
return (await
|
|
716
|
+
return (await $e(this._auth))?.user ?? null;
|
|
717
717
|
}
|
|
718
718
|
/**
|
|
719
719
|
* One-shot async check — returns `true` if the current user has the
|
|
@@ -722,7 +722,7 @@ class jt {
|
|
|
722
722
|
*/
|
|
723
723
|
async checkSuperAdmin() {
|
|
724
724
|
const t = this._auth.currentUser;
|
|
725
|
-
return t ? (await
|
|
725
|
+
return t ? (await at(t)).claims.role === jt : !1;
|
|
726
726
|
}
|
|
727
727
|
/** Sign in with a Cue API key. `projectId` is optional — omit it when no project context is available (e.g. admin flows). */
|
|
728
728
|
async signInWithApiKey(t, e) {
|
|
@@ -735,15 +735,15 @@ class jt {
|
|
|
735
735
|
if (!r.ok)
|
|
736
736
|
throw new Error(`Failed to fetch custom token: ${r.statusText}`);
|
|
737
737
|
const { token: s } = await r.json();
|
|
738
|
-
return (await
|
|
738
|
+
return (await vt(this._auth, s)).user;
|
|
739
739
|
}
|
|
740
740
|
/** Sign in with a Firebase custom token (e.g. minted server-side for MCP/OAuth flows). */
|
|
741
741
|
async signInWithCustomToken(t) {
|
|
742
|
-
return (await
|
|
742
|
+
return (await vt(this._auth, t)).user;
|
|
743
743
|
}
|
|
744
744
|
/** Sign out the current user */
|
|
745
745
|
async signOut() {
|
|
746
|
-
await
|
|
746
|
+
await Fe(this._auth);
|
|
747
747
|
}
|
|
748
748
|
/**
|
|
749
749
|
* Register a new user by name and email.
|
|
@@ -773,7 +773,7 @@ class jt {
|
|
|
773
773
|
}
|
|
774
774
|
/** Subscribe to authentication state changes. Returns an unsubscribe function. */
|
|
775
775
|
onAuthStateChanged(t) {
|
|
776
|
-
return
|
|
776
|
+
return Be(this._auth, t);
|
|
777
777
|
}
|
|
778
778
|
/** Get the Firebase ID token for the current user, or null if not authenticated */
|
|
779
779
|
async getToken(t = !1) {
|
|
@@ -805,7 +805,7 @@ class jt {
|
|
|
805
805
|
return this._auth;
|
|
806
806
|
}
|
|
807
807
|
}
|
|
808
|
-
class
|
|
808
|
+
class Mt {
|
|
809
809
|
constructor(t) {
|
|
810
810
|
this._blob = t;
|
|
811
811
|
}
|
|
@@ -841,8 +841,8 @@ class Ut {
|
|
|
841
841
|
return e;
|
|
842
842
|
}
|
|
843
843
|
}
|
|
844
|
-
const
|
|
845
|
-
class
|
|
844
|
+
const mo = "/data-views/tables", wo = "/commands/tables";
|
|
845
|
+
class fo {
|
|
846
846
|
constructor(t, e) {
|
|
847
847
|
this._auth = t, this._gatewayUrl = e;
|
|
848
848
|
}
|
|
@@ -850,7 +850,7 @@ class wo {
|
|
|
850
850
|
_gatewayUrl;
|
|
851
851
|
async listTables(t) {
|
|
852
852
|
const e = await this._auth.authenticatedFetch(
|
|
853
|
-
`${this._gatewayUrl}${
|
|
853
|
+
`${this._gatewayUrl}${mo}`,
|
|
854
854
|
{
|
|
855
855
|
headers: {
|
|
856
856
|
"Content-Type": "application/json",
|
|
@@ -865,7 +865,7 @@ class wo {
|
|
|
865
865
|
}
|
|
866
866
|
async saveTables(t, e) {
|
|
867
867
|
const o = await this._auth.authenticatedFetch(
|
|
868
|
-
`${this._gatewayUrl}${
|
|
868
|
+
`${this._gatewayUrl}${wo}`,
|
|
869
869
|
{
|
|
870
870
|
method: "PUT",
|
|
871
871
|
headers: {
|
|
@@ -880,8 +880,8 @@ class wo {
|
|
|
880
880
|
throw new Error(`Failed to save tables: ${o.status} ${o.statusText}`);
|
|
881
881
|
}
|
|
882
882
|
}
|
|
883
|
-
const
|
|
884
|
-
class
|
|
883
|
+
const yo = "/semantic-extraction/extract";
|
|
884
|
+
class bo {
|
|
885
885
|
constructor(t, e) {
|
|
886
886
|
this._auth = t, this._gatewayUrl = e;
|
|
887
887
|
}
|
|
@@ -898,7 +898,7 @@ class yo {
|
|
|
898
898
|
const e = t.rdfFormat ?? "json-ld", o = new FormData();
|
|
899
899
|
o.append("file", t.image, "page.png"), o.append("template", JSON.stringify(t.template)), o.append("space_id", t.projectId), o.append("rdf_format", e), t.category && o.append("category", t.category), t.text && o.append("text", t.text);
|
|
900
900
|
const r = await this._auth.authenticatedFetch(
|
|
901
|
-
`${this._gatewayUrl}${
|
|
901
|
+
`${this._gatewayUrl}${yo}`,
|
|
902
902
|
{
|
|
903
903
|
method: "POST",
|
|
904
904
|
// Do NOT set Content-Type; browser sets it with the correct boundary.
|
|
@@ -919,9 +919,9 @@ class yo {
|
|
|
919
919
|
return { jsonld: await r.json() };
|
|
920
920
|
}
|
|
921
921
|
}
|
|
922
|
-
class
|
|
922
|
+
class zt {
|
|
923
923
|
constructor(t, e, o, r) {
|
|
924
|
-
this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new
|
|
924
|
+
this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new fo(t, e), this.extraction = new bo(t, e);
|
|
925
925
|
}
|
|
926
926
|
_auth;
|
|
927
927
|
_gatewayUrl;
|
|
@@ -955,7 +955,7 @@ class Mt {
|
|
|
955
955
|
*/
|
|
956
956
|
async search(t) {
|
|
957
957
|
const e = await this._auth.authenticatedFetch(
|
|
958
|
-
`${this._gatewayUrl}${
|
|
958
|
+
`${this._gatewayUrl}${lo}`,
|
|
959
959
|
{
|
|
960
960
|
method: "POST",
|
|
961
961
|
headers: { "Content-Type": "application/json", "cue-project-id": t.projectId },
|
|
@@ -978,7 +978,7 @@ class Mt {
|
|
|
978
978
|
*/
|
|
979
979
|
async sparql(t, e, o) {
|
|
980
980
|
o || (o = (await this.projects.getProject(e))?.projectSettings?.graph?.type ?? "qlever");
|
|
981
|
-
const r = o === "fuseki" ?
|
|
981
|
+
const r = o === "fuseki" ? ne : pe;
|
|
982
982
|
console.log(`Executing SPARQL query against ${r} for project ${e} with graph type ${o}`);
|
|
983
983
|
const s = new URLSearchParams();
|
|
984
984
|
s.append("query", t);
|
|
@@ -1015,7 +1015,7 @@ class Mt {
|
|
|
1015
1015
|
const r = o?.format ?? "json-ld", s = r === "turtle" ? "text/turtle" : "application/ld+json";
|
|
1016
1016
|
if (o?.graphType === "fuseki") {
|
|
1017
1017
|
const c = await this._auth.authenticatedFetch(
|
|
1018
|
-
`${this._gatewayUrl}${
|
|
1018
|
+
`${this._gatewayUrl}${ho}`,
|
|
1019
1019
|
{
|
|
1020
1020
|
method: "POST",
|
|
1021
1021
|
headers: {
|
|
@@ -1033,7 +1033,7 @@ class Mt {
|
|
|
1033
1033
|
}
|
|
1034
1034
|
return r === "turtle" ? c.text() : c.json();
|
|
1035
1035
|
}
|
|
1036
|
-
const a = `${this._gatewayUrl}${
|
|
1036
|
+
const a = `${this._gatewayUrl}${uo}${o?.verbose ? "?verbose=true" : ""}`, n = new URLSearchParams({ shape: t }), p = await this._auth.authenticatedFetch(a, {
|
|
1037
1037
|
method: "POST",
|
|
1038
1038
|
headers: {
|
|
1039
1039
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
@@ -1051,7 +1051,7 @@ class Mt {
|
|
|
1051
1051
|
}
|
|
1052
1052
|
async getConsumption(t) {
|
|
1053
1053
|
const e = await this._auth.authenticatedFetch(
|
|
1054
|
-
`${this._gatewayUrl}${
|
|
1054
|
+
`${this._gatewayUrl}${ro}`,
|
|
1055
1055
|
{
|
|
1056
1056
|
headers: {
|
|
1057
1057
|
"Content-Type": "application/json",
|
|
@@ -1067,7 +1067,7 @@ class Mt {
|
|
|
1067
1067
|
return e.json();
|
|
1068
1068
|
}
|
|
1069
1069
|
}
|
|
1070
|
-
const
|
|
1070
|
+
const pt = [
|
|
1071
1071
|
"building",
|
|
1072
1072
|
"cadastre",
|
|
1073
1073
|
"zone",
|
|
@@ -1078,13 +1078,13 @@ const nt = [
|
|
|
1078
1078
|
"railway",
|
|
1079
1079
|
"natural",
|
|
1080
1080
|
"manmade"
|
|
1081
|
-
],
|
|
1081
|
+
], le = [
|
|
1082
1082
|
"address",
|
|
1083
1083
|
"poi",
|
|
1084
1084
|
"railway",
|
|
1085
1085
|
"natural",
|
|
1086
1086
|
"manmade"
|
|
1087
|
-
],
|
|
1087
|
+
], vo = {
|
|
1088
1088
|
address: {
|
|
1089
1089
|
category: "address",
|
|
1090
1090
|
label: "Address",
|
|
@@ -1147,9 +1147,9 @@ const nt = [
|
|
|
1147
1147
|
}
|
|
1148
1148
|
};
|
|
1149
1149
|
function S(i) {
|
|
1150
|
-
return
|
|
1150
|
+
return vo[i];
|
|
1151
1151
|
}
|
|
1152
|
-
const
|
|
1152
|
+
const _o = {
|
|
1153
1153
|
"land-use-plan": "#f59e0b",
|
|
1154
1154
|
// amber – primary zoning
|
|
1155
1155
|
"local-plan": "#ec4899",
|
|
@@ -1180,7 +1180,7 @@ const vo = {
|
|
|
1180
1180
|
function N(i, t) {
|
|
1181
1181
|
return i[0] < t[2] && i[2] > t[0] && i[1] < t[3] && i[3] > t[1];
|
|
1182
1182
|
}
|
|
1183
|
-
const
|
|
1183
|
+
const ko = "https://nominatim.openstreetmap.org", Eo = "cue-gis/0.0.1", xo = {
|
|
1184
1184
|
address: "street",
|
|
1185
1185
|
poi: "shop",
|
|
1186
1186
|
railway: "station",
|
|
@@ -1195,7 +1195,7 @@ const _o = "https://nominatim.openstreetmap.org", ko = "cue-gis/0.0.1", Eo = {
|
|
|
1195
1195
|
function B(i) {
|
|
1196
1196
|
return `${L}:${i}`;
|
|
1197
1197
|
}
|
|
1198
|
-
function
|
|
1198
|
+
function Io(i) {
|
|
1199
1199
|
const t = S(i);
|
|
1200
1200
|
return {
|
|
1201
1201
|
id: B(i),
|
|
@@ -1210,17 +1210,17 @@ function xo(i) {
|
|
|
1210
1210
|
descriptionKey: `gis.layer.${L}.${i}.description`
|
|
1211
1211
|
};
|
|
1212
1212
|
}
|
|
1213
|
-
class
|
|
1213
|
+
class Co {
|
|
1214
1214
|
baseUrl;
|
|
1215
1215
|
userAgent;
|
|
1216
1216
|
email;
|
|
1217
1217
|
limit;
|
|
1218
1218
|
constructor(t = {}) {
|
|
1219
|
-
this.baseUrl = t.baseUrl ??
|
|
1219
|
+
this.baseUrl = t.baseUrl ?? ko, this.userAgent = t.userAgent ?? Eo, this.email = t.email, this.limit = Math.min(t.limit ?? 40, 40);
|
|
1220
1220
|
}
|
|
1221
1221
|
async listFeatureCategoryDescriptors(t) {
|
|
1222
1222
|
return (await Promise.allSettled(
|
|
1223
|
-
|
|
1223
|
+
le.map(async (o) => {
|
|
1224
1224
|
const r = await this.search(t, o);
|
|
1225
1225
|
return { category: o, hasResults: r.length > 0 };
|
|
1226
1226
|
})
|
|
@@ -1229,10 +1229,10 @@ class Io {
|
|
|
1229
1229
|
).map((o) => S(o.value.category));
|
|
1230
1230
|
}
|
|
1231
1231
|
async listAvailableLayers(t) {
|
|
1232
|
-
return (await this.listFeatureCategoryDescriptors(t)).map((o) =>
|
|
1232
|
+
return (await this.listFeatureCategoryDescriptors(t)).map((o) => Io(o.category));
|
|
1233
1233
|
}
|
|
1234
1234
|
async getFeaturesForLayer(t, e) {
|
|
1235
|
-
const o =
|
|
1235
|
+
const o = pt.find((r) => B(r) === e);
|
|
1236
1236
|
return o ? this.search(t, o) : [];
|
|
1237
1237
|
}
|
|
1238
1238
|
async listFeatureCategories(t) {
|
|
@@ -1246,7 +1246,7 @@ class Io {
|
|
|
1246
1246
|
* so bounded viewbox searches return meaningful results.
|
|
1247
1247
|
*/
|
|
1248
1248
|
async search(t, e) {
|
|
1249
|
-
const [o, r, s, a] = t, n = e ?
|
|
1249
|
+
const [o, r, s, a] = t, n = e ? xo[e] : "place", p = new URLSearchParams({
|
|
1250
1250
|
q: n,
|
|
1251
1251
|
format: "jsonv2",
|
|
1252
1252
|
viewbox: `${o},${a},${s},${r}`,
|
|
@@ -1289,7 +1289,7 @@ class Io {
|
|
|
1289
1289
|
};
|
|
1290
1290
|
}
|
|
1291
1291
|
}
|
|
1292
|
-
const
|
|
1292
|
+
const Nt = {
|
|
1293
1293
|
// 100s – Residential
|
|
1294
1294
|
110: "residential",
|
|
1295
1295
|
120: "residential",
|
|
@@ -1368,7 +1368,7 @@ const zt = {
|
|
|
1368
1368
|
960: "agricultural",
|
|
1369
1369
|
970: "agricultural",
|
|
1370
1370
|
990: "other"
|
|
1371
|
-
},
|
|
1371
|
+
}, $t = {
|
|
1372
1372
|
1010: "residential",
|
|
1373
1373
|
1020: "mixed",
|
|
1374
1374
|
1030: "residential",
|
|
@@ -1398,7 +1398,7 @@ const zt = {
|
|
|
1398
1398
|
1281: "infrastructure",
|
|
1399
1399
|
1282: "infrastructure",
|
|
1400
1400
|
9999: "other"
|
|
1401
|
-
},
|
|
1401
|
+
}, To = {
|
|
1402
1402
|
// Residential
|
|
1403
1403
|
1110: "residential",
|
|
1404
1404
|
// Einfamilienhaus
|
|
@@ -1460,7 +1460,7 @@ const zt = {
|
|
|
1460
1460
|
// Empfangsgebäude Bahn/Bus
|
|
1461
1461
|
1282: "infrastructure"
|
|
1462
1462
|
// Parkhaus, Garage
|
|
1463
|
-
},
|
|
1463
|
+
}, So = [
|
|
1464
1464
|
// "Gebäude" is the Swiss AV BoFlaeche land-cover label for a building footprint.
|
|
1465
1465
|
// It does not encode the actual use type, so map it to 'other' as a safe fallback.
|
|
1466
1466
|
[/^geb[äa]ude$/i, "other"],
|
|
@@ -1474,22 +1474,22 @@ const zt = {
|
|
|
1474
1474
|
[/gemischt|mixed|blandet/i, "mixed"]
|
|
1475
1475
|
];
|
|
1476
1476
|
function O(i) {
|
|
1477
|
-
for (const [t, e] of
|
|
1477
|
+
for (const [t, e] of So)
|
|
1478
1478
|
if (t.test(i)) return e;
|
|
1479
1479
|
}
|
|
1480
|
-
function
|
|
1480
|
+
function Ro(i, t) {
|
|
1481
1481
|
if (i == null) return;
|
|
1482
1482
|
const e = String(i).trim();
|
|
1483
|
-
return t === "swiss-gwr" ?
|
|
1483
|
+
return t === "swiss-gwr" ? To[e] ?? O(e) : t === "danish-matrikel" ? Nt[e] ?? O(e) : t === "zurich-wfs" || t === "swiss-av-wfs" ? $t[e] ?? O(e) : $t[e] ?? Nt[e] ?? O(e);
|
|
1484
1484
|
}
|
|
1485
|
-
function
|
|
1485
|
+
function Ao(i, t) {
|
|
1486
1486
|
if (i != null)
|
|
1487
1487
|
return O(String(i).trim());
|
|
1488
1488
|
}
|
|
1489
|
-
function
|
|
1489
|
+
function ce(i) {
|
|
1490
1490
|
return i.trim().toLowerCase().replace(/[\s_\-]/g, "");
|
|
1491
1491
|
}
|
|
1492
|
-
const
|
|
1492
|
+
const Po = {
|
|
1493
1493
|
// Swiss ÖREB rechtsstatus
|
|
1494
1494
|
inkraft: "in-force",
|
|
1495
1495
|
laufendeanderung: "amendment-pending",
|
|
@@ -1508,11 +1508,11 @@ const Ao = {
|
|
|
1508
1508
|
forslag: "proposed",
|
|
1509
1509
|
aflyst: "repealed"
|
|
1510
1510
|
};
|
|
1511
|
-
function
|
|
1511
|
+
function he(i) {
|
|
1512
1512
|
if (i)
|
|
1513
|
-
return
|
|
1513
|
+
return Po[ce(i)];
|
|
1514
1514
|
}
|
|
1515
|
-
const
|
|
1515
|
+
const Ft = {
|
|
1516
1516
|
// Swiss Nutzungsplanung (typ_gde_bezeichnung and common variants)
|
|
1517
1517
|
grundnutzungszonenplan: "land-use-plan",
|
|
1518
1518
|
nutzungszonenplan: "land-use-plan",
|
|
@@ -1566,7 +1566,7 @@ const $t = {
|
|
|
1566
1566
|
// Danish plandata.dk
|
|
1567
1567
|
lokalplan: "local-plan",
|
|
1568
1568
|
kommuneplanramme: "municipal-plan-framework"
|
|
1569
|
-
},
|
|
1569
|
+
}, Oo = [
|
|
1570
1570
|
[/quartiererhalt/i, "neighbourhood-conservation-plan"],
|
|
1571
1571
|
[/lärmempfindlich|laermempfindlich/i, "noise-sensitivity-plan"],
|
|
1572
1572
|
[/gewässerschutz|grundwasserschutz/i, "water-protection-plan"],
|
|
@@ -1606,24 +1606,24 @@ const $t = {
|
|
|
1606
1606
|
// Catch-all: any remaining Xzone / Xareal designation from the Grundnutzungszonenplan
|
|
1607
1607
|
[/zone$|areal$/i, "land-use-plan"]
|
|
1608
1608
|
];
|
|
1609
|
-
function
|
|
1609
|
+
function de(i) {
|
|
1610
1610
|
if (!i) return;
|
|
1611
|
-
const t =
|
|
1612
|
-
if (t in
|
|
1613
|
-
for (const [e, o] of
|
|
1611
|
+
const t = ce(i);
|
|
1612
|
+
if (t in Ft) return Ft[t];
|
|
1613
|
+
for (const [e, o] of Oo)
|
|
1614
1614
|
if (e.test(i)) return o;
|
|
1615
1615
|
console.warn(
|
|
1616
1616
|
`[cue-gis] Unknown zone plan type — add "${i}" to classifyZonePlanType: no ZonePlanType mapping found.`
|
|
1617
1617
|
);
|
|
1618
1618
|
}
|
|
1619
|
-
const
|
|
1620
|
-
function
|
|
1619
|
+
const Do = "https://maps.zh.ch/wfs/OGDZHWFS", Lo = "zurich-wfs", qo = [8.35, 47.15, 8.95, 47.7], jo = [5.9, 45.7, 10.55, 47.85];
|
|
1620
|
+
function J(i) {
|
|
1621
1621
|
return typeof i == "string" ? i : i.typeName;
|
|
1622
1622
|
}
|
|
1623
|
-
function
|
|
1623
|
+
function tt(i) {
|
|
1624
1624
|
return typeof i == "string" ? void 0 : i.cqlFilter;
|
|
1625
1625
|
}
|
|
1626
|
-
function
|
|
1626
|
+
function Uo(i) {
|
|
1627
1627
|
if (!i) return [0, 0];
|
|
1628
1628
|
const t = i.coordinates;
|
|
1629
1629
|
switch (i.type) {
|
|
@@ -1641,20 +1641,20 @@ function jo(i) {
|
|
|
1641
1641
|
return [0, 0];
|
|
1642
1642
|
}
|
|
1643
1643
|
}
|
|
1644
|
-
function
|
|
1644
|
+
function Mo(i, t) {
|
|
1645
1645
|
if (!i) return t;
|
|
1646
1646
|
for (const e of ["plannavn", "bezeichnung", "name", "strassenname", "objektname", "title", "label"])
|
|
1647
1647
|
if (typeof i[e] == "string" && i[e]) return i[e];
|
|
1648
1648
|
return t;
|
|
1649
1649
|
}
|
|
1650
|
-
function
|
|
1650
|
+
function zo(i, t, e) {
|
|
1651
1651
|
return e ? `${i}:${t}[${e}]` : `${i}:${t}`;
|
|
1652
1652
|
}
|
|
1653
|
-
const
|
|
1654
|
-
function
|
|
1655
|
-
const r = e.replace(/^ms:/, ""), s = S(t), a =
|
|
1653
|
+
const No = /* @__PURE__ */ new Set(["building", "cadastre", "greenspace", "paved", "zone"]);
|
|
1654
|
+
function et(i, t, e, o) {
|
|
1655
|
+
const r = e.replace(/^ms:/, ""), s = S(t), a = No.has(t) ? "priority" : "raw";
|
|
1656
1656
|
return {
|
|
1657
|
-
id:
|
|
1657
|
+
id: zo(i, e, o),
|
|
1658
1658
|
sourceId: i,
|
|
1659
1659
|
sourceLayerId: e,
|
|
1660
1660
|
category: t,
|
|
@@ -1666,32 +1666,32 @@ function tt(i, t, e, o) {
|
|
|
1666
1666
|
descriptionKey: `gis.layer.${i}.${r}.description`
|
|
1667
1667
|
};
|
|
1668
1668
|
}
|
|
1669
|
-
function
|
|
1669
|
+
function $o(i, t) {
|
|
1670
1670
|
if (!i) return { featureType: "building" };
|
|
1671
1671
|
const e = i.grundflaeche ?? i.gbf ?? i.gebaeudegrundrissflaeche ?? i.flaeche ?? void 0, o = i.vollgeschosse ?? i.geschossanzahl ?? i.anzahl_geschosse ?? void 0, r = i.gebaeudefunktion ?? i.gfkode ?? i.art ?? i.objektart ?? void 0, s = i.baujahr ?? i.bauperiode ?? void 0, a = String(i.egid ?? i.gwr_egid ?? i.egris_egid ?? "").trim() || void 0;
|
|
1672
1672
|
return {
|
|
1673
1673
|
featureType: "building",
|
|
1674
1674
|
areaM2: typeof e == "number" ? e : void 0,
|
|
1675
1675
|
buildingUse: r ? String(r) : void 0,
|
|
1676
|
-
buildingUseGeneric:
|
|
1676
|
+
buildingUseGeneric: Ro(r, t),
|
|
1677
1677
|
floors: typeof o == "number" ? o : void 0,
|
|
1678
1678
|
yearBuilt: typeof s == "number" ? s : void 0,
|
|
1679
1679
|
registryId: a
|
|
1680
1680
|
};
|
|
1681
1681
|
}
|
|
1682
|
-
function
|
|
1682
|
+
function Fo(i, t) {
|
|
1683
1683
|
if (!i) return { featureType: "plot" };
|
|
1684
1684
|
const e = i.egris_egrid ?? i.egrid ?? void 0, o = i.nummer ?? void 0, r = i.nbident ?? void 0, s = o && r ? `${o}, ${r}` : o ?? void 0, a = i.flaechenmass ?? i.flaeche ?? void 0, n = i.art ?? i.nutzungsart ?? void 0;
|
|
1685
1685
|
return {
|
|
1686
1686
|
featureType: "plot",
|
|
1687
1687
|
areaM2: typeof a == "number" ? a : void 0,
|
|
1688
1688
|
plotUse: n ? String(n) : void 0,
|
|
1689
|
-
plotUseGeneric:
|
|
1689
|
+
plotUseGeneric: Ao(n),
|
|
1690
1690
|
plotId: s,
|
|
1691
1691
|
registryId: e
|
|
1692
1692
|
};
|
|
1693
1693
|
}
|
|
1694
|
-
function
|
|
1694
|
+
function Bo(i) {
|
|
1695
1695
|
if (!i) return { featureType: "greenspace" };
|
|
1696
1696
|
const t = i.flaeche ?? void 0, e = i.art ?? void 0;
|
|
1697
1697
|
return {
|
|
@@ -1700,7 +1700,7 @@ function Fo(i) {
|
|
|
1700
1700
|
surfaceType: e ? String(e) : void 0
|
|
1701
1701
|
};
|
|
1702
1702
|
}
|
|
1703
|
-
function
|
|
1703
|
+
function Go(i) {
|
|
1704
1704
|
if (!i) return { featureType: "paved" };
|
|
1705
1705
|
const t = i.flaeche ?? void 0, e = i.art ?? void 0;
|
|
1706
1706
|
return {
|
|
@@ -1709,9 +1709,9 @@ function Bo(i) {
|
|
|
1709
1709
|
surfaceType: e ? String(e) : void 0
|
|
1710
1710
|
};
|
|
1711
1711
|
}
|
|
1712
|
-
function
|
|
1712
|
+
function Ho(i) {
|
|
1713
1713
|
if (!i) return { featureType: "zone" };
|
|
1714
|
-
const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s =
|
|
1714
|
+
const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s = he(r), a = i.typ_gde_bezeichnung ?? void 0, n = de(a), p = i.dagsordenpunkt_url ?? i.dokument_url ?? i.link ?? void 0, c = i.auflagedatum ?? void 0, h = i.festsetzungsdatum ?? void 0, d = i.genehmigungsdatum ?? void 0, g = i.inkraftsetzungsdatum ?? void 0, w = i.flaeche ?? i.flaeche_m2 ?? void 0;
|
|
1715
1715
|
return {
|
|
1716
1716
|
featureType: "zone",
|
|
1717
1717
|
zoneType: t ? String(t) : void 0,
|
|
@@ -1727,7 +1727,7 @@ function Go(i) {
|
|
|
1727
1727
|
areaM2: typeof w == "number" ? w : void 0
|
|
1728
1728
|
};
|
|
1729
1729
|
}
|
|
1730
|
-
function
|
|
1730
|
+
function Wo(i) {
|
|
1731
1731
|
const t = i.match(/^(\w+)\s*=\s*'([^']+)'$/);
|
|
1732
1732
|
if (t) {
|
|
1733
1733
|
const [, o, r] = t;
|
|
@@ -1742,13 +1742,13 @@ function Ho(i) {
|
|
|
1742
1742
|
}
|
|
1743
1743
|
return () => !0;
|
|
1744
1744
|
}
|
|
1745
|
-
class
|
|
1745
|
+
class ot {
|
|
1746
1746
|
categoryMap;
|
|
1747
1747
|
baseUrl;
|
|
1748
1748
|
sourceId;
|
|
1749
1749
|
outputFormat;
|
|
1750
1750
|
constructor(t) {
|
|
1751
|
-
this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ??
|
|
1751
|
+
this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ?? Do, this.sourceId = t.sourceId ?? Lo, this.outputFormat = t.outputFormat ?? "application/json; subtype=geojson";
|
|
1752
1752
|
}
|
|
1753
1753
|
async listFeatureCategoryDescriptors(t) {
|
|
1754
1754
|
const e = await this.listAvailableLayers(t);
|
|
@@ -1759,20 +1759,20 @@ class et {
|
|
|
1759
1759
|
return (await Promise.allSettled(
|
|
1760
1760
|
e.flatMap(
|
|
1761
1761
|
([r, s]) => s.map(async (a) => {
|
|
1762
|
-
const n =
|
|
1762
|
+
const n = J(a), p = tt(a), c = await this._fetchFeatures(t, n, 1, p);
|
|
1763
1763
|
return { category: r, typeName: n, cqlFilter: p, hasResults: c.features.length > 0 };
|
|
1764
1764
|
})
|
|
1765
1765
|
)
|
|
1766
1766
|
)).filter(
|
|
1767
1767
|
(r) => r.status === "fulfilled" && r.value.hasResults
|
|
1768
|
-
).map((r) =>
|
|
1768
|
+
).map((r) => et(this.sourceId, r.value.category, r.value.typeName, r.value.cqlFilter));
|
|
1769
1769
|
}
|
|
1770
1770
|
async getFeaturesForLayer(t, e) {
|
|
1771
1771
|
const o = this._findLayerById(e);
|
|
1772
1772
|
return o ? this._fetchAndConvert(t, o.descriptor, o.cqlFilter) : [];
|
|
1773
1773
|
}
|
|
1774
1774
|
async _fetchAndConvert(t, e, o) {
|
|
1775
|
-
const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ?
|
|
1775
|
+
const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ? Wo(o) : void 0;
|
|
1776
1776
|
return (s ? r.features.filter((n) => s(n.properties)) : r.features).map((n, p) => this.toGisFeature(n, e, p));
|
|
1777
1777
|
}
|
|
1778
1778
|
/**
|
|
@@ -1787,7 +1787,7 @@ class et {
|
|
|
1787
1787
|
const o = this.categoryMap[e] ?? [];
|
|
1788
1788
|
return (await Promise.all(
|
|
1789
1789
|
o.map((s) => {
|
|
1790
|
-
const a =
|
|
1790
|
+
const a = J(s), n = tt(s), p = et(this.sourceId, e, a);
|
|
1791
1791
|
return this._fetchAndConvert(t, p, n);
|
|
1792
1792
|
})
|
|
1793
1793
|
)).flat();
|
|
@@ -1797,7 +1797,7 @@ class et {
|
|
|
1797
1797
|
const e = Object.entries(this.categoryMap);
|
|
1798
1798
|
for (const [o, r] of e)
|
|
1799
1799
|
for (const s of r) {
|
|
1800
|
-
const a =
|
|
1800
|
+
const a = J(s), n = tt(s), p = et(this.sourceId, o, a, n);
|
|
1801
1801
|
if (p.id === t)
|
|
1802
1802
|
return { descriptor: p, cqlFilter: n };
|
|
1803
1803
|
}
|
|
@@ -1821,7 +1821,7 @@ class et {
|
|
|
1821
1821
|
return g.json();
|
|
1822
1822
|
}
|
|
1823
1823
|
toGisFeature(t, e, o) {
|
|
1824
|
-
const [r, s] =
|
|
1824
|
+
const [r, s] = Uo(t.geometry), a = Mo(t.properties, `${e.sourceLayerId}[${o}]`), n = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, p = e.tier, c = p === "priority" ? this._extractNormalisedProperties(t, e) : void 0;
|
|
1825
1825
|
return {
|
|
1826
1826
|
id: t.id ?? `${e.sourceLayerId}/${o}`,
|
|
1827
1827
|
preferredColor: e.preferredColor,
|
|
@@ -1842,10 +1842,10 @@ class et {
|
|
|
1842
1842
|
};
|
|
1843
1843
|
}
|
|
1844
1844
|
_extractNormalisedProperties(t, e) {
|
|
1845
|
-
return e.category === "building" ?
|
|
1845
|
+
return e.category === "building" ? $o(t.properties, this.sourceId) : e.category === "greenspace" ? Bo(t.properties) : e.category === "paved" ? Go(t.properties) : e.category === "zone" ? Ho(t.properties) : Fo(t.properties, this.sourceId);
|
|
1846
1846
|
}
|
|
1847
1847
|
}
|
|
1848
|
-
const
|
|
1848
|
+
const ge = [8, 54.5, 15.2, 57.8], ue = {
|
|
1849
1849
|
building: [
|
|
1850
1850
|
{ source: "danish-matrikel", typename: "bbr_v001:bygning_current" }
|
|
1851
1851
|
],
|
|
@@ -1854,7 +1854,7 @@ const de = [8, 54.5, 15.2, 57.8], ge = {
|
|
|
1854
1854
|
{ source: "danish-matrikel", typename: "mat_v001:samletfastejendom_current" }
|
|
1855
1855
|
]
|
|
1856
1856
|
};
|
|
1857
|
-
function
|
|
1857
|
+
function Vo(i) {
|
|
1858
1858
|
if (!i) return [0, 0];
|
|
1859
1859
|
const t = i.coordinates;
|
|
1860
1860
|
switch (i.type) {
|
|
@@ -1872,7 +1872,7 @@ function Wo(i) {
|
|
|
1872
1872
|
return [0, 0];
|
|
1873
1873
|
}
|
|
1874
1874
|
}
|
|
1875
|
-
function
|
|
1875
|
+
function Ko(i, t) {
|
|
1876
1876
|
if (!i) return t;
|
|
1877
1877
|
for (const e of [
|
|
1878
1878
|
"mat:matrikelnummer",
|
|
@@ -1888,14 +1888,14 @@ function Vo(i, t) {
|
|
|
1888
1888
|
if (typeof i[e] == "string" && i[e]) return i[e];
|
|
1889
1889
|
return t;
|
|
1890
1890
|
}
|
|
1891
|
-
function
|
|
1891
|
+
function Qo(i, t, e) {
|
|
1892
1892
|
return `${i}:${t}:${e}`;
|
|
1893
1893
|
}
|
|
1894
|
-
const
|
|
1895
|
-
function
|
|
1896
|
-
const o = e.typename.replace(/^[^:]+:/, ""), r = S(t), s =
|
|
1894
|
+
const Xo = /* @__PURE__ */ new Set(["building", "cadastre", "zone"]);
|
|
1895
|
+
function rt(i, t, e) {
|
|
1896
|
+
const o = e.typename.replace(/^[^:]+:/, ""), r = S(t), s = Xo.has(t) ? "priority" : "raw";
|
|
1897
1897
|
return {
|
|
1898
|
-
id:
|
|
1898
|
+
id: Qo(i, e.source, e.typename),
|
|
1899
1899
|
sourceId: i,
|
|
1900
1900
|
sourceLayerId: e.typename,
|
|
1901
1901
|
category: t,
|
|
@@ -1907,7 +1907,7 @@ function ot(i, t, e) {
|
|
|
1907
1907
|
descriptionKey: `gis.layer.${i}.${e.source}.${o}.description`
|
|
1908
1908
|
};
|
|
1909
1909
|
}
|
|
1910
|
-
function
|
|
1910
|
+
function Yo(i, t) {
|
|
1911
1911
|
if (t === "building") {
|
|
1912
1912
|
const a = i?.byg041BebyggetAreal ?? i?.byg038SamletBygningsareal, n = i?.byg021BygningensAnvendelse, p = i?.id_lokalId, c = i?.byg026Opførelsesår;
|
|
1913
1913
|
return {
|
|
@@ -1924,8 +1924,8 @@ function Xo(i, t) {
|
|
|
1924
1924
|
featureType: "zone",
|
|
1925
1925
|
zoneType: a ?? void 0,
|
|
1926
1926
|
zoneCode: p ?? void 0,
|
|
1927
|
-
legalStatus:
|
|
1928
|
-
planType:
|
|
1927
|
+
legalStatus: he(c),
|
|
1928
|
+
planType: de(i?.typ_gde_bezeichnung),
|
|
1929
1929
|
planId: n ?? void 0,
|
|
1930
1930
|
planDocumentLink: h ?? void 0,
|
|
1931
1931
|
publicationDate: i?.auflagedatum ?? void 0,
|
|
@@ -1943,13 +1943,13 @@ function Xo(i, t) {
|
|
|
1943
1943
|
registryId: s ?? void 0
|
|
1944
1944
|
};
|
|
1945
1945
|
}
|
|
1946
|
-
class
|
|
1946
|
+
class Zo {
|
|
1947
1947
|
categoryMap;
|
|
1948
1948
|
dataViewsBaseUrl;
|
|
1949
1949
|
getHeaders;
|
|
1950
1950
|
sourceId;
|
|
1951
1951
|
constructor(t) {
|
|
1952
|
-
this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ??
|
|
1952
|
+
this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ?? ue, this.sourceId = t.sourceId ?? "cue-sdk-gis";
|
|
1953
1953
|
}
|
|
1954
1954
|
async listFeatureCategoryDescriptors(t) {
|
|
1955
1955
|
const e = await this.listAvailableLayers(t);
|
|
@@ -1970,7 +1970,7 @@ class Yo {
|
|
|
1970
1970
|
)
|
|
1971
1971
|
)).filter(
|
|
1972
1972
|
(r) => r.status === "fulfilled" && r.value.hasResults
|
|
1973
|
-
).map((r) =>
|
|
1973
|
+
).map((r) => rt(this.sourceId, r.value.category, r.value.entry));
|
|
1974
1974
|
}
|
|
1975
1975
|
async getFeaturesForLayer(t, e) {
|
|
1976
1976
|
const o = this._findLayerById(e);
|
|
@@ -1984,7 +1984,7 @@ class Yo {
|
|
|
1984
1984
|
const o = this.categoryMap[e] ?? [];
|
|
1985
1985
|
return (await Promise.all(
|
|
1986
1986
|
o.map((s) => {
|
|
1987
|
-
const a =
|
|
1987
|
+
const a = rt(this.sourceId, e, s);
|
|
1988
1988
|
return this.getFeaturesForLayer(t, a.id);
|
|
1989
1989
|
})
|
|
1990
1990
|
)).flat();
|
|
@@ -1993,7 +1993,7 @@ class Yo {
|
|
|
1993
1993
|
_findLayerById(t) {
|
|
1994
1994
|
for (const [e, o] of Object.entries(this.categoryMap))
|
|
1995
1995
|
for (const r of o) {
|
|
1996
|
-
const s =
|
|
1996
|
+
const s = rt(this.sourceId, e, r);
|
|
1997
1997
|
if (s.id === t) return { entry: r, descriptor: s };
|
|
1998
1998
|
}
|
|
1999
1999
|
}
|
|
@@ -2012,7 +2012,7 @@ class Yo {
|
|
|
2012
2012
|
return d.json();
|
|
2013
2013
|
}
|
|
2014
2014
|
_toGisFeature(t, e, o) {
|
|
2015
|
-
const [r, s] =
|
|
2015
|
+
const [r, s] = Vo(t.geometry), a = t.id ?? `${e.sourceLayerId}/${o}`, n = Ko(t.properties, a), p = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, c = e.tier, h = c === "priority" ? Yo(t.properties, e.category) : void 0;
|
|
2016
2016
|
return {
|
|
2017
2017
|
id: a,
|
|
2018
2018
|
sourceId: this.sourceId,
|
|
@@ -2033,7 +2033,7 @@ class Yo {
|
|
|
2033
2033
|
};
|
|
2034
2034
|
}
|
|
2035
2035
|
}
|
|
2036
|
-
const
|
|
2036
|
+
const Jo = {
|
|
2037
2037
|
address: [
|
|
2038
2038
|
"ms:ogd-0406_arv_basis_avzh_hausnummer_pos_p",
|
|
2039
2039
|
"ms:ogd-0571_afv_gv_strat_strassennetz_l"
|
|
@@ -2081,23 +2081,23 @@ const Zo = {
|
|
|
2081
2081
|
// ÖREB Überlagernde Festlegungen (Flächen) – overlaying planning constraints
|
|
2082
2082
|
"ms:ogd-0155_arv_basis_np_ul_flaeche_f"
|
|
2083
2083
|
]
|
|
2084
|
-
},
|
|
2084
|
+
}, me = [
|
|
2085
2085
|
{
|
|
2086
2086
|
name: "Canton of Zürich",
|
|
2087
|
-
coverageBBox:
|
|
2087
|
+
coverageBBox: qo,
|
|
2088
2088
|
supportedCategories: ["address", "poi", "railway", "natural", "manmade", "building", "cadastre", "greenspace", "paved", "zone"],
|
|
2089
2089
|
priority: 10,
|
|
2090
|
-
adapter: new
|
|
2091
|
-
categoryMap:
|
|
2090
|
+
adapter: new ot({
|
|
2091
|
+
categoryMap: Jo
|
|
2092
2092
|
})
|
|
2093
2093
|
},
|
|
2094
2094
|
{
|
|
2095
2095
|
name: "Switzerland (national AV cadastre)",
|
|
2096
|
-
coverageBBox:
|
|
2096
|
+
coverageBBox: jo,
|
|
2097
2097
|
supportedCategories: ["cadastre"],
|
|
2098
2098
|
priority: 5,
|
|
2099
2099
|
// Lower priority than canton-specific adapters. For ZH, the canton adapter (priority 10) wins.
|
|
2100
|
-
adapter: new
|
|
2100
|
+
adapter: new ot({
|
|
2101
2101
|
sourceId: "swiss-av-wfs",
|
|
2102
2102
|
baseUrl: "https://wfs.geodienste.ch/av_0/deu",
|
|
2103
2103
|
categoryMap: {
|
|
@@ -2121,10 +2121,10 @@ const Zo = {
|
|
|
2121
2121
|
* - `pdk:kommuneplanramme_vedtaget` – adopted municipal plan frameworks
|
|
2122
2122
|
*/
|
|
2123
2123
|
name: "Denmark (Plandata.dk – planning zones)",
|
|
2124
|
-
coverageBBox:
|
|
2124
|
+
coverageBBox: ge,
|
|
2125
2125
|
supportedCategories: ["zone"],
|
|
2126
2126
|
priority: 10,
|
|
2127
|
-
adapter: new
|
|
2127
|
+
adapter: new ot({
|
|
2128
2128
|
sourceId: "danish-plandata",
|
|
2129
2129
|
baseUrl: "https://wfs.plandata.dk/geoserver/pdk/wfs",
|
|
2130
2130
|
outputFormat: "application/json",
|
|
@@ -2139,12 +2139,12 @@ const Zo = {
|
|
|
2139
2139
|
})
|
|
2140
2140
|
}
|
|
2141
2141
|
];
|
|
2142
|
-
function
|
|
2142
|
+
function Bt(i) {
|
|
2143
2143
|
return [...i].sort(
|
|
2144
|
-
(t, e) =>
|
|
2144
|
+
(t, e) => pt.indexOf(t.category) - pt.indexOf(e.category)
|
|
2145
2145
|
);
|
|
2146
2146
|
}
|
|
2147
|
-
class
|
|
2147
|
+
class tr {
|
|
2148
2148
|
nominatim;
|
|
2149
2149
|
regions;
|
|
2150
2150
|
/**
|
|
@@ -2159,9 +2159,9 @@ class Jo {
|
|
|
2159
2159
|
zonePlanTypeColors: r,
|
|
2160
2160
|
...s
|
|
2161
2161
|
} = t;
|
|
2162
|
-
this.nominatim = new
|
|
2163
|
-
const a = o ?
|
|
2164
|
-
this.regions = e ?? a, this.zonePlanTypeColors = { ...
|
|
2162
|
+
this.nominatim = new Co(s);
|
|
2163
|
+
const a = o ? me : [];
|
|
2164
|
+
this.regions = e ?? a, this.zonePlanTypeColors = { ..._o, ...r };
|
|
2165
2165
|
}
|
|
2166
2166
|
/**
|
|
2167
2167
|
* Return the available feature categories together with UI metadata such as
|
|
@@ -2180,12 +2180,12 @@ class Jo {
|
|
|
2180
2180
|
for (const a of e)
|
|
2181
2181
|
for (const n of a.supportedCategories ?? [])
|
|
2182
2182
|
r.has(n) || (r.add(n), s.push(S(n)));
|
|
2183
|
-
for (const a of
|
|
2183
|
+
for (const a of le)
|
|
2184
2184
|
r.has(a) || s.push(S(a));
|
|
2185
|
-
return
|
|
2185
|
+
return Bt(s);
|
|
2186
2186
|
}
|
|
2187
2187
|
const o = await this._adapterFor(t).listFeatureCategoryDescriptors(t);
|
|
2188
|
-
return
|
|
2188
|
+
return Bt(o);
|
|
2189
2189
|
}
|
|
2190
2190
|
/**
|
|
2191
2191
|
* Return the feature categories that have at least one result within the
|
|
@@ -2258,7 +2258,7 @@ class Jo {
|
|
|
2258
2258
|
const { features: n, idx: p } = await Promise.race(a.values());
|
|
2259
2259
|
a.delete(p);
|
|
2260
2260
|
for (const c of n) {
|
|
2261
|
-
const h =
|
|
2261
|
+
const h = Gt(c), d = W(c), g = s.get(h);
|
|
2262
2262
|
(g === void 0 || d > g) && (s.set(h, d), yield c);
|
|
2263
2263
|
}
|
|
2264
2264
|
}
|
|
@@ -2292,9 +2292,9 @@ class Jo {
|
|
|
2292
2292
|
), a = [], n = [];
|
|
2293
2293
|
for (const d of s)
|
|
2294
2294
|
d.status === "fulfilled" && (d.value.isNominatim ? n.push(...d.value.features) : a.push(...d.value.features));
|
|
2295
|
-
const p =
|
|
2295
|
+
const p = rr(a, n), c = /* @__PURE__ */ new Map(), h = [];
|
|
2296
2296
|
for (const d of p) {
|
|
2297
|
-
const g =
|
|
2297
|
+
const g = Gt(d), w = W(d), u = c.get(g);
|
|
2298
2298
|
(u === void 0 || w > u) && (c.set(g, w), h.push(d));
|
|
2299
2299
|
}
|
|
2300
2300
|
return h;
|
|
@@ -2312,22 +2312,22 @@ function W(i) {
|
|
|
2312
2312
|
const t = i.geometry?.type;
|
|
2313
2313
|
return t === "Polygon" || t === "MultiPolygon" ? 3 : t === "LineString" || t === "MultiLineString" ? 2 : 1;
|
|
2314
2314
|
}
|
|
2315
|
-
function
|
|
2315
|
+
function Gt(i) {
|
|
2316
2316
|
const t = Math.round(i.lat * 1e3) / 1e3, e = Math.round(i.lon * 1e3) / 1e3;
|
|
2317
2317
|
return `${(i.name ?? i.id ?? "").toLowerCase().trim()}|${t}|${e}`;
|
|
2318
2318
|
}
|
|
2319
|
-
const
|
|
2320
|
-
function
|
|
2319
|
+
const er = 1e-3;
|
|
2320
|
+
function or(i, t) {
|
|
2321
2321
|
const e = i.lat - t.lat, o = i.lon - t.lon;
|
|
2322
2322
|
return Math.sqrt(e * e + o * o);
|
|
2323
2323
|
}
|
|
2324
|
-
function
|
|
2324
|
+
function rr(i, t) {
|
|
2325
2325
|
if (t.length === 0) return i;
|
|
2326
2326
|
const e = i.filter((a) => W(a) === 3), o = i.filter((a) => W(a) !== 3), r = e.map((a) => ({ feature: { ...a, originalData: { ...a.originalData } }, matched: !1 })), s = [];
|
|
2327
2327
|
for (const a of t) {
|
|
2328
|
-
let n = -1, p =
|
|
2328
|
+
let n = -1, p = er;
|
|
2329
2329
|
for (let c = 0; c < r.length; c++) {
|
|
2330
|
-
const h =
|
|
2330
|
+
const h = or(a, r[c].feature);
|
|
2331
2331
|
h < p && (p = h, n = c);
|
|
2332
2332
|
}
|
|
2333
2333
|
n >= 0 ? (r[n].feature.originalData = {
|
|
@@ -2341,8 +2341,8 @@ function or(i, t) {
|
|
|
2341
2341
|
...s
|
|
2342
2342
|
];
|
|
2343
2343
|
}
|
|
2344
|
-
const
|
|
2345
|
-
class
|
|
2344
|
+
const sr = "/data-views", ar = 1500;
|
|
2345
|
+
class ir {
|
|
2346
2346
|
// undefined = not yet built
|
|
2347
2347
|
/** @internal — construct via `cue.gis`, not directly. */
|
|
2348
2348
|
constructor(t, e) {
|
|
@@ -2425,25 +2425,25 @@ class ar {
|
|
|
2425
2425
|
}
|
|
2426
2426
|
// ── Private ───────────────────────────────────────────────────────────────
|
|
2427
2427
|
_scheduleDebouncedQuery() {
|
|
2428
|
-
this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(),
|
|
2428
|
+
this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(), ar);
|
|
2429
2429
|
}
|
|
2430
2430
|
_getGateway() {
|
|
2431
2431
|
if (this._gatewayCache !== null && this._gatewayProjectId === this._projectId)
|
|
2432
2432
|
return this._gatewayCache;
|
|
2433
|
-
const t = this._projectId, e = [...
|
|
2433
|
+
const t = this._projectId, e = [...me];
|
|
2434
2434
|
return t && e.unshift({
|
|
2435
2435
|
name: "Cue SDK (authenticated)",
|
|
2436
|
-
coverageBBox:
|
|
2437
|
-
supportedCategories: Object.keys(
|
|
2436
|
+
coverageBBox: ge,
|
|
2437
|
+
supportedCategories: Object.keys(ue),
|
|
2438
2438
|
priority: 10,
|
|
2439
|
-
adapter: new
|
|
2440
|
-
dataViewsBaseUrl: `${this._gatewayUrl}${
|
|
2439
|
+
adapter: new Zo({
|
|
2440
|
+
dataViewsBaseUrl: `${this._gatewayUrl}${sr}`,
|
|
2441
2441
|
getHeaders: async () => ({
|
|
2442
2442
|
...await this._getAuthHeaders(),
|
|
2443
2443
|
"x-project-id": t
|
|
2444
2444
|
})
|
|
2445
2445
|
})
|
|
2446
|
-
}), this._gatewayCache = new
|
|
2446
|
+
}), this._gatewayCache = new tr({ regions: e }), this._gatewayProjectId = t, this._gatewayCache;
|
|
2447
2447
|
}
|
|
2448
2448
|
async _queryLayers() {
|
|
2449
2449
|
const t = this._bbox;
|
|
@@ -2487,11 +2487,11 @@ class ar {
|
|
|
2487
2487
|
this._loadListeners.forEach((e) => e(t));
|
|
2488
2488
|
}
|
|
2489
2489
|
}
|
|
2490
|
-
class
|
|
2490
|
+
class Ht {
|
|
2491
2491
|
constructor(t, e, o = !1, r) {
|
|
2492
|
-
if (this._auth = t, this._db =
|
|
2492
|
+
if (this._auth = t, this._db = Ie(e), this._functions = se(e, ie), this._gatewayUrl = r?.gatewayUrl ?? "", o) {
|
|
2493
2493
|
const s = r?.firestoreEmulatorHost ?? "localhost", a = r?.firestoreEmulatorPort ?? 8080;
|
|
2494
|
-
|
|
2494
|
+
Ce(this._db, s, a), ae(this._functions, "localhost", 5001);
|
|
2495
2495
|
}
|
|
2496
2496
|
}
|
|
2497
2497
|
_auth;
|
|
@@ -2508,7 +2508,7 @@ class Gt {
|
|
|
2508
2508
|
* Throws if a project with the given ID already exists.
|
|
2509
2509
|
*/
|
|
2510
2510
|
async createProject(t) {
|
|
2511
|
-
const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${
|
|
2511
|
+
const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${no}`, {
|
|
2512
2512
|
method: "POST",
|
|
2513
2513
|
headers: { "Content-Type": "application/json" },
|
|
2514
2514
|
body: JSON.stringify(t)
|
|
@@ -2524,12 +2524,12 @@ class Gt {
|
|
|
2524
2524
|
* Access is gated by Firestore rules which check membership.
|
|
2525
2525
|
*/
|
|
2526
2526
|
async listProjects() {
|
|
2527
|
-
const t = this._requireUser(), e =
|
|
2528
|
-
return (await
|
|
2527
|
+
const t = this._requireUser(), e = yt(this._db, It);
|
|
2528
|
+
return (await Te(Se(e, Re("members", "array-contains", t), Ae(100)))).docs.map((r) => r.data());
|
|
2529
2529
|
}
|
|
2530
2530
|
/** Fetch a single project by ID. Returns null if not found. */
|
|
2531
2531
|
async getProject(t) {
|
|
2532
|
-
const e = yt(
|
|
2532
|
+
const e = bt(yt(this._db, It), t), o = await Pe(e);
|
|
2533
2533
|
return o.exists() ? o.data() : null;
|
|
2534
2534
|
}
|
|
2535
2535
|
/**
|
|
@@ -2538,10 +2538,10 @@ class Gt {
|
|
|
2538
2538
|
*/
|
|
2539
2539
|
async incrementUnitsConsumed(t, e, o) {
|
|
2540
2540
|
if (e <= 0) return;
|
|
2541
|
-
const r =
|
|
2542
|
-
await
|
|
2543
|
-
unitsConsumed:
|
|
2544
|
-
lastUpdated:
|
|
2541
|
+
const r = bt(this._db, "clientSync", t);
|
|
2542
|
+
await Oe(r, {
|
|
2543
|
+
unitsConsumed: Le(e),
|
|
2544
|
+
lastUpdated: De(),
|
|
2545
2545
|
lastUserId: o
|
|
2546
2546
|
}, { merge: !0 });
|
|
2547
2547
|
}
|
|
@@ -2564,7 +2564,7 @@ class Gt {
|
|
|
2564
2564
|
*/
|
|
2565
2565
|
async deleteProject(t) {
|
|
2566
2566
|
const e = await this._auth.authenticatedFetch(
|
|
2567
|
-
`${this._gatewayUrl}${
|
|
2567
|
+
`${this._gatewayUrl}${po(t)}`,
|
|
2568
2568
|
{ method: "DELETE" }
|
|
2569
2569
|
);
|
|
2570
2570
|
if (!e.ok) {
|
|
@@ -2573,9 +2573,9 @@ class Gt {
|
|
|
2573
2573
|
}
|
|
2574
2574
|
}
|
|
2575
2575
|
}
|
|
2576
|
-
class
|
|
2576
|
+
class Wt {
|
|
2577
2577
|
constructor(t, e, o, r) {
|
|
2578
|
-
this._auth = t, this._gatewayUrl = r, this._functions =
|
|
2578
|
+
this._auth = t, this._gatewayUrl = r, this._functions = se(e, ie), o && ae(this._functions, "localhost", 5001);
|
|
2579
2579
|
}
|
|
2580
2580
|
_auth;
|
|
2581
2581
|
_gatewayUrl;
|
|
@@ -2592,13 +2592,13 @@ class Ht {
|
|
|
2592
2592
|
}
|
|
2593
2593
|
/** Whether the current user has an active API key. */
|
|
2594
2594
|
async hasAPIKey() {
|
|
2595
|
-
return await this._fetch(
|
|
2595
|
+
return await this._fetch(Ot) !== null;
|
|
2596
2596
|
}
|
|
2597
2597
|
/** Returns the sign-in methods registered for the current user's email. */
|
|
2598
2598
|
async getSignInMethods() {
|
|
2599
2599
|
const t = this._auth.currentUser;
|
|
2600
2600
|
if (!t?.email) throw new Error("User has no e-mail");
|
|
2601
|
-
return
|
|
2601
|
+
return Ge(this._auth.firebaseAuth, t.email);
|
|
2602
2602
|
}
|
|
2603
2603
|
/** Builds a human-readable label from a Firebase UserInfo provider entry. */
|
|
2604
2604
|
buildProviderLabel(t) {
|
|
@@ -2611,42 +2611,42 @@ class Ht {
|
|
|
2611
2611
|
}
|
|
2612
2612
|
/** Links a Google or Microsoft provider to the current account via popup. Returns the new provider label. */
|
|
2613
2613
|
async linkProvider(t) {
|
|
2614
|
-
const e = this._requireUser(), o = t === "google.com" ? new
|
|
2614
|
+
const e = this._requireUser(), o = t === "google.com" ? new it() : new nt(t), s = (await He(e, o)).user.providerData.find(
|
|
2615
2615
|
(a) => a.providerId === t
|
|
2616
2616
|
);
|
|
2617
2617
|
return s ? this.buildProviderLabel(s) : "-";
|
|
2618
2618
|
}
|
|
2619
2619
|
/** Unlinks a provider from the current account. */
|
|
2620
2620
|
async unlinkProvider(t) {
|
|
2621
|
-
await
|
|
2621
|
+
await We(this._requireUser(), t);
|
|
2622
2622
|
}
|
|
2623
2623
|
/** Changes the password. Reauthenticates first. */
|
|
2624
2624
|
async updatePassword(t, e) {
|
|
2625
2625
|
const o = this._requireUser();
|
|
2626
2626
|
if (!o.email) throw new Error("User has no e-mail");
|
|
2627
|
-
await
|
|
2627
|
+
await _t(
|
|
2628
2628
|
o,
|
|
2629
|
-
|
|
2630
|
-
), await
|
|
2629
|
+
X.credential(o.email, t)
|
|
2630
|
+
), await Ve(o, e);
|
|
2631
2631
|
}
|
|
2632
2632
|
/** Adds (sets) a password for an account that currently only uses SSO. */
|
|
2633
2633
|
async addPassword(t) {
|
|
2634
2634
|
const e = this._requireUser();
|
|
2635
2635
|
if (!e.email) throw new Error("User has no e-mail");
|
|
2636
|
-
await
|
|
2636
|
+
await Ke(e, X.credential(e.email, t));
|
|
2637
2637
|
}
|
|
2638
2638
|
/** Requests an e-mail change. Sends a verification e-mail to the new address. */
|
|
2639
2639
|
async updateEmail(t, e) {
|
|
2640
2640
|
const o = this._requireUser();
|
|
2641
2641
|
if (!o.email) throw new Error("User e-mail not available");
|
|
2642
|
-
await
|
|
2642
|
+
await _t(
|
|
2643
2643
|
o,
|
|
2644
|
-
|
|
2645
|
-
), await
|
|
2644
|
+
X.credential(o.email, e)
|
|
2645
|
+
), await Qe(o, t), await Xe(o);
|
|
2646
2646
|
}
|
|
2647
2647
|
/** Creates a new API key for the current user. */
|
|
2648
2648
|
async createAPIKey(t) {
|
|
2649
|
-
return this._fetch(
|
|
2649
|
+
return this._fetch(Dt, {
|
|
2650
2650
|
method: "POST",
|
|
2651
2651
|
headers: { "Content-Type": "application/json" },
|
|
2652
2652
|
body: JSON.stringify({ expiration: t })
|
|
@@ -2655,7 +2655,7 @@ class Ht {
|
|
|
2655
2655
|
/** Revokes the current user's API key. */
|
|
2656
2656
|
async revokeAPIKey() {
|
|
2657
2657
|
const t = await this._auth.authenticatedFetch(
|
|
2658
|
-
this._url(
|
|
2658
|
+
this._url(Dt),
|
|
2659
2659
|
{ method: "DELETE" }
|
|
2660
2660
|
);
|
|
2661
2661
|
if (!t.ok)
|
|
@@ -2663,17 +2663,17 @@ class Ht {
|
|
|
2663
2663
|
}
|
|
2664
2664
|
/** Fetches the current user's existing API key. */
|
|
2665
2665
|
async requestAPIKey() {
|
|
2666
|
-
const t = await this._fetch(
|
|
2666
|
+
const t = await this._fetch(Ot);
|
|
2667
2667
|
if (!t) throw new Error("No API key found");
|
|
2668
2668
|
return t;
|
|
2669
2669
|
}
|
|
2670
2670
|
/** Returns organizations the current user is a member of. */
|
|
2671
2671
|
async listOrganizations() {
|
|
2672
|
-
return this._fetch(
|
|
2672
|
+
return this._fetch(so);
|
|
2673
2673
|
}
|
|
2674
2674
|
/** Returns all members of the given organisation. Caller must be an org admin or superadmin. */
|
|
2675
2675
|
async getOrgMembers(t) {
|
|
2676
|
-
return this._fetch(
|
|
2676
|
+
return this._fetch(io(t));
|
|
2677
2677
|
}
|
|
2678
2678
|
_requireUser() {
|
|
2679
2679
|
const t = this._auth.currentUser;
|
|
@@ -2689,7 +2689,7 @@ class Ht {
|
|
|
2689
2689
|
}
|
|
2690
2690
|
/** Record that the current user has accepted the terms of service. Sets a `terms` custom claim on the token. */
|
|
2691
2691
|
async acceptTerms(t) {
|
|
2692
|
-
await this._fetch(
|
|
2692
|
+
await this._fetch(ao, {
|
|
2693
2693
|
method: "POST",
|
|
2694
2694
|
headers: { "Content-Type": "application/json" },
|
|
2695
2695
|
body: JSON.stringify({ version: t })
|
|
@@ -2703,10 +2703,10 @@ class Ht {
|
|
|
2703
2703
|
*/
|
|
2704
2704
|
async latestTermsAccepted() {
|
|
2705
2705
|
const t = this._auth.currentUser;
|
|
2706
|
-
return t ? (await
|
|
2706
|
+
return t ? (await at(t)).claims.terms ?? null : null;
|
|
2707
2707
|
}
|
|
2708
2708
|
}
|
|
2709
|
-
const
|
|
2709
|
+
const Vt = ["superadmin", "admin", "syncer", "member"], Kt = {
|
|
2710
2710
|
createEntities: "admin",
|
|
2711
2711
|
createProvider: "superadmin",
|
|
2712
2712
|
changeContentCategories: "syncer",
|
|
@@ -2722,7 +2722,7 @@ const Wt = ["superadmin", "admin", "syncer", "member"], Vt = {
|
|
|
2722
2722
|
uploadDocuments: "syncer",
|
|
2723
2723
|
viewEntities: "member"
|
|
2724
2724
|
};
|
|
2725
|
-
function
|
|
2725
|
+
function nr() {
|
|
2726
2726
|
return {
|
|
2727
2727
|
changeContentCategories: !1,
|
|
2728
2728
|
createEntities: !1,
|
|
@@ -2741,9 +2741,9 @@ function ir() {
|
|
|
2741
2741
|
viewEntities: !1
|
|
2742
2742
|
};
|
|
2743
2743
|
}
|
|
2744
|
-
class
|
|
2744
|
+
class Qt {
|
|
2745
2745
|
constructor(t) {
|
|
2746
|
-
this._isSuperAdmin = t, this._projectRoles = new k([]), this._orgRole = new k(null), this.privileges =
|
|
2746
|
+
this._isSuperAdmin = t, this._projectRoles = new k([]), this._orgRole = new k(null), this.privileges = dt(
|
|
2747
2747
|
[this._projectRoles, this._orgRole, t],
|
|
2748
2748
|
() => this._compute()
|
|
2749
2749
|
);
|
|
@@ -2780,17 +2780,17 @@ class Kt {
|
|
|
2780
2780
|
_expand(t) {
|
|
2781
2781
|
if (this._isSuperAdmin.get())
|
|
2782
2782
|
return ["superadmin", "admin", "syncer", "member"];
|
|
2783
|
-
const e =
|
|
2784
|
-
return e === -1 ? [] : Array.from(
|
|
2783
|
+
const e = Vt.findIndex((o) => t.includes(o));
|
|
2784
|
+
return e === -1 ? [] : Array.from(Vt.slice(e));
|
|
2785
2785
|
}
|
|
2786
2786
|
_compute() {
|
|
2787
|
-
const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o =
|
|
2788
|
-
for (const r of Object.keys(
|
|
2789
|
-
o[r] = t.includes(
|
|
2787
|
+
const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o = nr();
|
|
2788
|
+
for (const r of Object.keys(Kt))
|
|
2789
|
+
o[r] = t.includes(Kt[r]);
|
|
2790
2790
|
return o.createProject = e || this._orgRole.get() === "admin", o;
|
|
2791
2791
|
}
|
|
2792
2792
|
}
|
|
2793
|
-
class
|
|
2793
|
+
class Xt {
|
|
2794
2794
|
constructor(t) {
|
|
2795
2795
|
this._storage = t;
|
|
2796
2796
|
}
|
|
@@ -2823,7 +2823,7 @@ class Qt {
|
|
|
2823
2823
|
// ── Internal helpers ───────────────────────────────────────────────────────
|
|
2824
2824
|
async _get(t, e) {
|
|
2825
2825
|
try {
|
|
2826
|
-
const r = await (await
|
|
2826
|
+
const r = await (await re(_(this._storage, `${t}/${e}.json.gz`))).arrayBuffer(), s = new DecompressionStream("gzip"), a = s.writable.getWriter(), n = s.readable.getReader();
|
|
2827
2827
|
a.write(new Uint8Array(r)), a.close();
|
|
2828
2828
|
const p = [];
|
|
2829
2829
|
let c = await n.read();
|
|
@@ -2835,7 +2835,7 @@ class Qt {
|
|
|
2835
2835
|
d.set(w, g), g += w.length;
|
|
2836
2836
|
return JSON.parse(new TextDecoder().decode(d));
|
|
2837
2837
|
} catch (o) {
|
|
2838
|
-
if (
|
|
2838
|
+
if (pr(o)) return;
|
|
2839
2839
|
throw o;
|
|
2840
2840
|
}
|
|
2841
2841
|
}
|
|
@@ -2850,17 +2850,17 @@ class Qt {
|
|
|
2850
2850
|
let g = 0;
|
|
2851
2851
|
for (const w of p)
|
|
2852
2852
|
d.set(w, g), g += w.length;
|
|
2853
|
-
await
|
|
2853
|
+
await st(
|
|
2854
2854
|
_(this._storage, `${t}/${e}.json.gz`),
|
|
2855
2855
|
d,
|
|
2856
2856
|
{ contentType: "application/gzip" }
|
|
2857
2857
|
);
|
|
2858
2858
|
}
|
|
2859
2859
|
}
|
|
2860
|
-
function
|
|
2860
|
+
function pr(i) {
|
|
2861
2861
|
return typeof i == "object" && i !== null && "code" in i && i.code === "storage/object-not-found";
|
|
2862
2862
|
}
|
|
2863
|
-
const
|
|
2863
|
+
const y = {
|
|
2864
2864
|
qcy: "https://dev.qaecy.com/ont#",
|
|
2865
2865
|
"qcy-e": "https://dev.qaecy.com/enum#",
|
|
2866
2866
|
"qcy-l": "https://dev.qaecy.com/logs#",
|
|
@@ -6108,12 +6108,12 @@ const b = {
|
|
|
6108
6108
|
fbsp: "http://purl.obolibrary.org/obo/FBSP_",
|
|
6109
6109
|
rex: "http://purl.obolibrary.org/obo/REX_"
|
|
6110
6110
|
};
|
|
6111
|
-
class
|
|
6111
|
+
class V {
|
|
6112
6112
|
static _instance;
|
|
6113
6113
|
// Opposite map is built once
|
|
6114
6114
|
_nsMap;
|
|
6115
6115
|
static getInstance() {
|
|
6116
|
-
return this._instance ? this._instance : (this._instance = new
|
|
6116
|
+
return this._instance ? this._instance : (this._instance = new V(), this._instance);
|
|
6117
6117
|
}
|
|
6118
6118
|
compactIRI(t) {
|
|
6119
6119
|
let e = this._nsMap;
|
|
@@ -6129,17 +6129,17 @@ class gt {
|
|
|
6129
6129
|
return r === void 0 ? t : t.replace(o, `${r}:`);
|
|
6130
6130
|
}
|
|
6131
6131
|
expandIRI(t) {
|
|
6132
|
-
const e = t.split(":")[0], o = A[e] ??
|
|
6132
|
+
const e = t.split(":")[0], o = A[e] ?? y[e];
|
|
6133
6133
|
return t.replace(`${e}:`, o);
|
|
6134
6134
|
}
|
|
6135
6135
|
_buildNSMap() {
|
|
6136
6136
|
const t = {};
|
|
6137
|
-
return Object.keys(A).forEach((e) => t[A[e]] = e), Object.keys(
|
|
6138
|
-
(e) => t[
|
|
6137
|
+
return Object.keys(A).forEach((e) => t[A[e]] = e), Object.keys(y).forEach(
|
|
6138
|
+
(e) => t[y[e]] = e
|
|
6139
6139
|
), this._nsMap = t, t;
|
|
6140
6140
|
}
|
|
6141
6141
|
}
|
|
6142
|
-
class
|
|
6142
|
+
class lr {
|
|
6143
6143
|
constructor(t, e, o, r, s) {
|
|
6144
6144
|
this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._currentLang = o, this._api.setLanguage(o), this._contentCategories = new k([]), this._entityCategories = new k([]), this._relationships = new k([]), this.availableContentCategories = this._contentCategories.asReadonly(), this.availableEntityCategories = this._entityCategories.asReadonly(), this.availableEntityRelationships = this._relationships.asReadonly(), this.ready = this._load(o).catch(
|
|
6145
6145
|
(a) => console.error("[CueProjectSchema] Initial load failed:", a)
|
|
@@ -6195,7 +6195,7 @@ class pr {
|
|
|
6195
6195
|
return;
|
|
6196
6196
|
}
|
|
6197
6197
|
const o = this._buildCategoriesQuery(t, "ContentCategory"), r = this._buildCategoriesQuery(t, "EntityCategory"), s = this._buildRelationshipsQuery(t);
|
|
6198
|
-
await
|
|
6198
|
+
await gt(
|
|
6199
6199
|
o + r + s,
|
|
6200
6200
|
async () => {
|
|
6201
6201
|
const [a, n, p] = await Promise.all([
|
|
@@ -6218,7 +6218,7 @@ class pr {
|
|
|
6218
6218
|
return this._runCategoriesQuery(this._buildCategoriesQuery(t, e));
|
|
6219
6219
|
}
|
|
6220
6220
|
_buildCategoriesQuery(t, e) {
|
|
6221
|
-
return `PREFIX qcy: <${
|
|
6221
|
+
return `PREFIX qcy: <${y.qcy}>
|
|
6222
6222
|
PREFIX skos: <${A.skos}>
|
|
6223
6223
|
SELECT ?iri ?parent (SAMPLE(?l) AS ?label)
|
|
6224
6224
|
WHERE {
|
|
@@ -6244,7 +6244,7 @@ GROUP BY ?iri ?parent`;
|
|
|
6244
6244
|
return this._runRelationshipsQuery(this._buildRelationshipsQuery(t));
|
|
6245
6245
|
}
|
|
6246
6246
|
_buildRelationshipsQuery(t) {
|
|
6247
|
-
return `PREFIX qcy: <${
|
|
6247
|
+
return `PREFIX qcy: <${y.qcy}>
|
|
6248
6248
|
PREFIX rdfs: <${A.rdfs}>
|
|
6249
6249
|
SELECT ?iri ?parent (SAMPLE(?l) AS ?label)
|
|
6250
6250
|
WHERE {
|
|
@@ -6268,9 +6268,9 @@ GROUP BY ?iri ?parent`;
|
|
|
6268
6268
|
});
|
|
6269
6269
|
}
|
|
6270
6270
|
}
|
|
6271
|
-
const
|
|
6272
|
-
class
|
|
6273
|
-
constructor(t, e, o =
|
|
6271
|
+
const cr = "https://qlever.dev/api/osm-planet";
|
|
6272
|
+
class we {
|
|
6273
|
+
constructor(t, e, o = ut, r, s) {
|
|
6274
6274
|
this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this.baseURL = `${o}${e}/`, this.entityInfoMap = this._entityInfoMapComputed, this.entityGraph = this._entityGraph.asReadonly(), this._entityOSMMap.subscribe(() => this._checkPendingOSMFetches()), this._fetchEntityGraph().catch(
|
|
6275
6275
|
(a) => console.error("[CueProjectEntities] Entity graph fetch failed:", a)
|
|
6276
6276
|
);
|
|
@@ -6292,7 +6292,7 @@ class me {
|
|
|
6292
6292
|
_fetchingOSMIds = /* @__PURE__ */ new Set();
|
|
6293
6293
|
_entityGraph = new k(void 0);
|
|
6294
6294
|
// ── Derived signals ────────────────────────────────────────────────────────
|
|
6295
|
-
_entityInfoMapComputed =
|
|
6295
|
+
_entityInfoMapComputed = dt(
|
|
6296
6296
|
[
|
|
6297
6297
|
this._entityDetails,
|
|
6298
6298
|
this._entityDocuments,
|
|
@@ -6338,7 +6338,7 @@ class me {
|
|
|
6338
6338
|
(a) => this._entityDetails.get()[a] === void 0
|
|
6339
6339
|
);
|
|
6340
6340
|
if (o.length === 0) return;
|
|
6341
|
-
const r = o.map((a) => `r:${a}`).join(" "), s = `PREFIX qcy: <${
|
|
6341
|
+
const r = o.map((a) => `r:${a}`).join(" "), s = `PREFIX qcy: <${y.qcy}>
|
|
6342
6342
|
PREFIX r: <${this.baseURL}>
|
|
6343
6343
|
SELECT ?id (SAMPLE(?val) AS ?value) (GROUP_CONCAT(DISTINCT STR(?cat); SEPARATOR=";") AS ?categories) ?mentionCount
|
|
6344
6344
|
WHERE {
|
|
@@ -6382,7 +6382,7 @@ GROUP BY ?id ?mentionCount`;
|
|
|
6382
6382
|
const o = { ...this._entityOSMMap.get() };
|
|
6383
6383
|
for (const p of e) o[p] = { direct: [], indirect: [] };
|
|
6384
6384
|
this._entityOSMMap.set(o);
|
|
6385
|
-
const r = e.map((p) => `r:${p}`).join(" "), s = `PREFIX qcy: <${
|
|
6385
|
+
const r = e.map((p) => `r:${p}`).join(" "), s = `PREFIX qcy: <${y.qcy}>
|
|
6386
6386
|
PREFIX r: <${this.baseURL}>
|
|
6387
6387
|
SELECT ?id ?osm ?direct ?rels ?entityUUID
|
|
6388
6388
|
WHERE {
|
|
@@ -6453,7 +6453,7 @@ WHERE {
|
|
|
6453
6453
|
async fetchEntityDocuments(t) {
|
|
6454
6454
|
const e = t.replace(/^.*\/([^/]*)$/, "$1");
|
|
6455
6455
|
this._entityDocuments.set({ ...this._entityDocuments.get(), [e]: [] }), this._entityDetails.get()[e] === void 0 && this.requestEntityData([e]);
|
|
6456
|
-
const o = `PREFIX qcy: <${
|
|
6456
|
+
const o = `PREFIX qcy: <${y.qcy}>
|
|
6457
6457
|
SELECT DISTINCT ?id
|
|
6458
6458
|
WHERE {
|
|
6459
6459
|
BIND(<${t}> AS ?iri)
|
|
@@ -6473,7 +6473,7 @@ WHERE {
|
|
|
6473
6473
|
* falls back to an untagged label when no match is found.
|
|
6474
6474
|
*/
|
|
6475
6475
|
async contentCategoriesInProject(t = !0) {
|
|
6476
|
-
const e = this._api.language, o = `PREFIX qcy: <${
|
|
6476
|
+
const e = this._api.language, o = `PREFIX qcy: <${y.qcy}>
|
|
6477
6477
|
PREFIX skos: <${A.skos}>
|
|
6478
6478
|
SELECT ?iri (SAMPLE(?l) AS ?label) ?count
|
|
6479
6479
|
WHERE {
|
|
@@ -6497,8 +6497,39 @@ ORDER BY ${t ? "DESC(?count)" : "ASC(?label)"}`;
|
|
|
6497
6497
|
};
|
|
6498
6498
|
});
|
|
6499
6499
|
}
|
|
6500
|
+
async entitiesByCategory(t, e = !1) {
|
|
6501
|
+
if (t.length === 0) return [];
|
|
6502
|
+
const o = V.getInstance(), r = (p) => p.startsWith("http://") || p.startsWith("https://") ? p : o.expandIRI(p), s = t.map((p) => `<${r(p)}>`).join(" "), a = e ? `PREFIX qcy: <${y.qcy}>
|
|
6503
|
+
SELECT ?iri ?id (SAMPLE(?val) AS ?value) (GROUP_CONCAT(DISTINCT STR(?allCat); SEPARATOR=";") AS ?categories)
|
|
6504
|
+
WHERE {
|
|
6505
|
+
VALUES ?filterCat { ${s} }
|
|
6506
|
+
?iri a qcy:CanonicalEntity ;
|
|
6507
|
+
qcy:hasEntityCategory ?filterCat ;
|
|
6508
|
+
qcy:value ?val ;
|
|
6509
|
+
qcy:hasEntityCategory ?allCat .
|
|
6510
|
+
BIND(REPLACE(STR(?iri), "^.*/", "") AS ?id)
|
|
6511
|
+
}
|
|
6512
|
+
GROUP BY ?iri ?id` : `PREFIX qcy: <${y.qcy}>
|
|
6513
|
+
SELECT DISTINCT ?id
|
|
6514
|
+
WHERE {
|
|
6515
|
+
VALUES ?filterCat { ${s} }
|
|
6516
|
+
?iri a qcy:CanonicalEntity ;
|
|
6517
|
+
qcy:hasEntityCategory ?filterCat .
|
|
6518
|
+
BIND(REPLACE(STR(?iri), "^.*/", "") AS ?id)
|
|
6519
|
+
}`, n = await this._api.sparql(
|
|
6520
|
+
a,
|
|
6521
|
+
this._projectId,
|
|
6522
|
+
this._graphType
|
|
6523
|
+
);
|
|
6524
|
+
return e ? n.results.bindings.filter((p) => p.iri && p.id).map((p) => ({
|
|
6525
|
+
iri: p.iri.value,
|
|
6526
|
+
uuid: p.id.value,
|
|
6527
|
+
value: p.value?.value ?? "",
|
|
6528
|
+
categories: p.categories?.value?.split(";").filter(Boolean) ?? []
|
|
6529
|
+
})) : n.results.bindings.filter((p) => p.id).map((p) => p.id.value);
|
|
6530
|
+
}
|
|
6500
6531
|
async buildSummaryGraph(t) {
|
|
6501
|
-
const e = `PREFIX qcy: <${
|
|
6532
|
+
const e = `PREFIX qcy: <${y.qcy}>
|
|
6502
6533
|
SELECT
|
|
6503
6534
|
?sourceCat
|
|
6504
6535
|
?predicate
|
|
@@ -6533,7 +6564,7 @@ ORDER BY DESC(?weight)`, o = await this._api.sparql(
|
|
|
6533
6564
|
};
|
|
6534
6565
|
}
|
|
6535
6566
|
if (t === "md") {
|
|
6536
|
-
const s =
|
|
6567
|
+
const s = V.getInstance(), a = r.map((h) => ({
|
|
6537
6568
|
src: s.compactIRI(h.sourceCat.value),
|
|
6538
6569
|
pred: s.compactIRI(h.predicate.value),
|
|
6539
6570
|
tgt: s.compactIRI(h.targetCat.value),
|
|
@@ -6570,8 +6601,8 @@ ORDER BY DESC(?weight)`, o = await this._api.sparql(
|
|
|
6570
6601
|
const x = s[f];
|
|
6571
6602
|
if (x)
|
|
6572
6603
|
for (const I of E) {
|
|
6573
|
-
const v = `${I}:${m}`,
|
|
6574
|
-
|
|
6604
|
+
const v = `${I}:${m}`, b = u.get(v) ?? { geometries: [], entityUUID: m };
|
|
6605
|
+
b.geometries.some((C) => C.osmIRI === f) || (b.geometries.push({ osmIRI: f, wkt: x }), u.set(v, b));
|
|
6575
6606
|
}
|
|
6576
6607
|
}
|
|
6577
6608
|
u.size > 0 && (g = Array.from(u.entries()).map(
|
|
@@ -6595,7 +6626,7 @@ ORDER BY DESC(?weight)`, o = await this._api.sparql(
|
|
|
6595
6626
|
return n;
|
|
6596
6627
|
}
|
|
6597
6628
|
async _fetchOutgoingRelationships(t) {
|
|
6598
|
-
const e = `PREFIX qcy: <${
|
|
6629
|
+
const e = `PREFIX qcy: <${y.qcy}>
|
|
6599
6630
|
SELECT ?rel ?related (SAMPLE(?val) AS ?nodeValue) (GROUP_CONCAT(STR(?cat); SEPARATOR=";") AS ?categories)
|
|
6600
6631
|
WHERE {
|
|
6601
6632
|
BIND(<${t}> AS ?s)
|
|
@@ -6627,7 +6658,7 @@ GROUP BY ?rel ?related`, o = await this._api.sparql(
|
|
|
6627
6658
|
}), this._entityDetails.set(s), r;
|
|
6628
6659
|
}
|
|
6629
6660
|
async _fetchIncomingRelationships(t) {
|
|
6630
|
-
const e = `PREFIX qcy: <${
|
|
6661
|
+
const e = `PREFIX qcy: <${y.qcy}>
|
|
6631
6662
|
SELECT ?rel ?relating (SAMPLE(?val) AS ?nodeValue) (GROUP_CONCAT(STR(?cat); SEPARATOR=";") AS ?categories)
|
|
6632
6663
|
WHERE {
|
|
6633
6664
|
BIND(<${t}> AS ?s)
|
|
@@ -6659,7 +6690,7 @@ GROUP BY ?rel ?relating`, o = await this._api.sparql(
|
|
|
6659
6690
|
}), this._entityDetails.set(s), r;
|
|
6660
6691
|
}
|
|
6661
6692
|
async _fetchEntityGraph() {
|
|
6662
|
-
const t = `PREFIX qcy: <${
|
|
6693
|
+
const t = `PREFIX qcy: <${y.qcy}>
|
|
6663
6694
|
SELECT ?e1Cat ?e2Cat (COUNT(?e1) AS ?e1Count) (COUNT(?e2) AS ?e2Count)
|
|
6664
6695
|
WHERE {
|
|
6665
6696
|
?e1 a qcy:CanonicalEntity ;
|
|
@@ -6668,7 +6699,7 @@ WHERE {
|
|
|
6668
6699
|
?e2 qcy:hasEntityCategory ?e2Cat
|
|
6669
6700
|
}
|
|
6670
6701
|
GROUP BY ?e1Cat ?e2Cat`;
|
|
6671
|
-
await
|
|
6702
|
+
await gt(
|
|
6672
6703
|
t,
|
|
6673
6704
|
async () => {
|
|
6674
6705
|
const e = await this._api.sparql(
|
|
@@ -6708,7 +6739,7 @@ GROUP BY ?e1Cat ?e2Cat`;
|
|
|
6708
6739
|
const o = e.map((n) => `<${n}>`).join(" "), r = `PREFIX geo: <${A.geo}>
|
|
6709
6740
|
SELECT * WHERE {
|
|
6710
6741
|
VALUES ?s { ${o} }
|
|
6711
|
-
SERVICE <${
|
|
6742
|
+
SERVICE <${cr}> {
|
|
6712
6743
|
?s geo:hasGeometry/geo:asWKT ?wkt
|
|
6713
6744
|
}
|
|
6714
6745
|
}`, s = await this._api.sparql(
|
|
@@ -6721,500 +6752,8 @@ SELECT * WHERE {
|
|
|
6721
6752
|
}), this._osmWKTMap.set(a);
|
|
6722
6753
|
}
|
|
6723
6754
|
}
|
|
6724
|
-
class pt {
|
|
6725
|
-
constructor(t, e, o, r = dt, s, a) {
|
|
6726
|
-
this._api = t, this._projectId = e, this._queryCache = s, this._graphType = a, this.baseURL = `${r}${e}/`, this._currentLang = o ?? this._api.language, this.documentInfoMap = this._documentInfoMap.asReadonly(), this.projectDocumentsData = this._projectDocumentsData.asReadonly();
|
|
6727
|
-
}
|
|
6728
|
-
_api;
|
|
6729
|
-
_projectId;
|
|
6730
|
-
_queryCache;
|
|
6731
|
-
_graphType;
|
|
6732
|
-
/** Full RDF base URL for this project, e.g. `https://cue.qaecy.com/r/{pid}/` */
|
|
6733
|
-
baseURL;
|
|
6734
|
-
/** Tracks the language for which `_documentInfoMap` is currently populated. */
|
|
6735
|
-
_currentLang;
|
|
6736
|
-
_documentInfoMap = new k({});
|
|
6737
|
-
_projectDocumentsData = new k({
|
|
6738
|
-
duplicateCount: 0,
|
|
6739
|
-
documentsBySuffix: {},
|
|
6740
|
-
documentsByContentCategory: {}
|
|
6741
|
-
});
|
|
6742
|
-
/** Lazily populated per-document detail map. */
|
|
6743
|
-
documentInfoMap;
|
|
6744
|
-
/** Project-level document overview (grouped counts + sizes). */
|
|
6745
|
-
projectDocumentsData;
|
|
6746
|
-
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
6747
|
-
/**
|
|
6748
|
-
* Resets all document state. Call when the active project changes.
|
|
6749
|
-
* Follow with `fetchOverview()` once the triplestore is ready.
|
|
6750
|
-
*/
|
|
6751
|
-
reset() {
|
|
6752
|
-
this._documentInfoMap.set({}), this._projectDocumentsData.set({
|
|
6753
|
-
duplicateCount: 0,
|
|
6754
|
-
documentsBySuffix: {},
|
|
6755
|
-
documentsByContentCategory: {}
|
|
6756
|
-
});
|
|
6757
|
-
}
|
|
6758
|
-
/**
|
|
6759
|
-
* Updates the active language and clears the document info map so that
|
|
6760
|
-
* language-sensitive fields (subject, summary) are re-fetched on the next
|
|
6761
|
-
* `requestDocumentData()` call.
|
|
6762
|
-
*/
|
|
6763
|
-
setLanguage(t) {
|
|
6764
|
-
this._currentLang !== t && (this._currentLang = t, this._api.setLanguage(t), this._documentInfoMap.set({}));
|
|
6765
|
-
}
|
|
6766
|
-
// ── Public API ─────────────────────────────────────────────────────────────
|
|
6767
|
-
/**
|
|
6768
|
-
* Fetches the three-part project overview (by suffix, by content category,
|
|
6769
|
-
* duplicate count) in parallel and writes them as a single atomic update to
|
|
6770
|
-
* `projectDocumentsData`. Safe to call again to refresh.
|
|
6771
|
-
*/
|
|
6772
|
-
async fetchOverview() {
|
|
6773
|
-
this._projectDocumentsData.set({
|
|
6774
|
-
duplicateCount: 0,
|
|
6775
|
-
documentsBySuffix: {},
|
|
6776
|
-
documentsByContentCategory: {}
|
|
6777
|
-
});
|
|
6778
|
-
const t = this._buildDocumentsBySuffixQuery(), e = this._buildDocumentsByContentCategoryQuery(), o = this._buildDuplicateCountQuery();
|
|
6779
|
-
await ht(
|
|
6780
|
-
t + e + o,
|
|
6781
|
-
async () => {
|
|
6782
|
-
const [r, s, a] = await Promise.all([
|
|
6783
|
-
this._runDocumentsBySuffixQuery(t),
|
|
6784
|
-
this._runDocumentsByContentCategoryQuery(e),
|
|
6785
|
-
this._runDuplicateCountQuery(o)
|
|
6786
|
-
]);
|
|
6787
|
-
return { duplicateCount: a, documentsBySuffix: r, documentsByContentCategory: s };
|
|
6788
|
-
},
|
|
6789
|
-
(r) => this._projectDocumentsData.set(r),
|
|
6790
|
-
this._queryCache
|
|
6791
|
-
);
|
|
6792
|
-
}
|
|
6793
|
-
/**
|
|
6794
|
-
* Lazily batch-fetches core metadata for the given document UUIDs.
|
|
6795
|
-
* Already-cached UUIDs are skipped. Data is merged into `documentInfoMap`
|
|
6796
|
-
* once the SPARQL response arrives.
|
|
6797
|
-
*/
|
|
6798
|
-
requestDocumentData(t) {
|
|
6799
|
-
const e = t.filter((o) => this._documentInfoMap.get()[o] === void 0);
|
|
6800
|
-
e.length !== 0 && this._fetchDocumentInfoBatch(e).catch(
|
|
6801
|
-
(o) => console.error("[CueProjectDocuments] requestDocumentData failed:", o)
|
|
6802
|
-
);
|
|
6803
|
-
}
|
|
6804
|
-
/**
|
|
6805
|
-
* Promise-based alternative to {@link requestDocumentData} for non-reactive contexts.
|
|
6806
|
-
*
|
|
6807
|
-
* Resolves with the `DocumentInfo` entries for every requested UUID once the
|
|
6808
|
-
* SPARQL response arrives. UUIDs already present in the cache are returned
|
|
6809
|
-
* immediately without a network request. The result is also written into
|
|
6810
|
-
* `documentInfoMap` so reactive consumers stay in sync.
|
|
6811
|
-
*
|
|
6812
|
-
* UUIDs not found in the triplestore are omitted from the returned map.
|
|
6813
|
-
*
|
|
6814
|
-
* @example
|
|
6815
|
-
* ```ts
|
|
6816
|
-
* const docs = await cueProjectDocs.fetchDocumentData(['uuid1', 'uuid2']);
|
|
6817
|
-
* console.log(docs['uuid1'].subject);
|
|
6818
|
-
* ```
|
|
6819
|
-
*/
|
|
6820
|
-
async fetchDocumentData(t) {
|
|
6821
|
-
const e = this._documentInfoMap.get(), o = t.filter((s) => e[s] === void 0);
|
|
6822
|
-
o.length > 0 && await this._fetchDocumentInfoBatch(o);
|
|
6823
|
-
const r = this._documentInfoMap.get();
|
|
6824
|
-
return Object.fromEntries(
|
|
6825
|
-
t.filter((s) => r[s] !== void 0).map((s) => [s, r[s]])
|
|
6826
|
-
);
|
|
6827
|
-
}
|
|
6828
|
-
/**
|
|
6829
|
-
* Fetches a lightweight document metadata shape (id/path/suffix/size) for
|
|
6830
|
-
* the given UUIDs and merges the results into `documentInfoMap`.
|
|
6831
|
-
*
|
|
6832
|
-
* This is useful for list/table contexts that do not need language-tagged
|
|
6833
|
-
* fields (`subject`, `summary`) or category/tag enrichment.
|
|
6834
|
-
*
|
|
6835
|
-
* UUIDs already present in `documentInfoMap` are skipped.
|
|
6836
|
-
*/
|
|
6837
|
-
async fetchDocumentDataSimple(t) {
|
|
6838
|
-
const e = this._documentInfoMap.get(), o = t.filter((s) => e[s] === void 0);
|
|
6839
|
-
o.length > 0 && await this._fetchSimpleDocumentInfoBatch(o);
|
|
6840
|
-
const r = this._documentInfoMap.get();
|
|
6841
|
-
return Object.fromEntries(
|
|
6842
|
-
t.filter((s) => r[s] !== void 0).map((s) => [s, r[s]])
|
|
6843
|
-
);
|
|
6844
|
-
}
|
|
6845
|
-
/**
|
|
6846
|
-
* Returns the alternative representations of the given document UUID.
|
|
6847
|
-
*
|
|
6848
|
-
* Alternative representations are derived artefacts stored under
|
|
6849
|
-
* `qcy:alternativeRepresentation` in the triplestore — for example a
|
|
6850
|
-
* `.fragments` BIM tile derived from an `.ifc` source file.
|
|
6851
|
-
*
|
|
6852
|
-
* The returned `DocumentInfo` entries are also merged into
|
|
6853
|
-
* `documentInfoMap` so reactive consumers stay in sync.
|
|
6854
|
-
*
|
|
6855
|
-
* @example
|
|
6856
|
-
* ```ts
|
|
6857
|
-
* const alts = await docs.fetchAlternativeRepresentations('abc-123');
|
|
6858
|
-
* // alts[0].suffix => '.fragments'
|
|
6859
|
-
* ```
|
|
6860
|
-
*/
|
|
6861
|
-
async fetchAlternativeRepresentations(t) {
|
|
6862
|
-
const e = `PREFIX qcy: <${b.qcy}>
|
|
6863
|
-
PREFIX r: <${this.baseURL}>
|
|
6864
|
-
SELECT ?altId ?contentIRI ?suffix ?rrp
|
|
6865
|
-
WHERE {
|
|
6866
|
-
r:${t} qcy:alternativeRepresentation ?contentIRI .
|
|
6867
|
-
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?altId)
|
|
6868
|
-
?contentIRI qcy:hasFileLocation ?loc .
|
|
6869
|
-
?loc qcy:suffix ?suffix .
|
|
6870
|
-
OPTIONAL { ?loc qcy:remoteRelativePath ?rrp }
|
|
6871
|
-
}`, o = await this._api.sparql(e, this._projectId, this._graphType), r = { ...this._documentInfoMap.get() }, s = [];
|
|
6872
|
-
return o.results.bindings.forEach((a) => {
|
|
6873
|
-
if (!a.altId || !a.contentIRI) return;
|
|
6874
|
-
const n = a.altId.value, p = {
|
|
6875
|
-
id: n,
|
|
6876
|
-
contentIRI: a.contentIRI.value,
|
|
6877
|
-
path: "",
|
|
6878
|
-
suffix: a.suffix?.value ?? "",
|
|
6879
|
-
size: 0,
|
|
6880
|
-
tags: [],
|
|
6881
|
-
categories: [],
|
|
6882
|
-
remoteRelativePath: a.rrp?.value
|
|
6883
|
-
};
|
|
6884
|
-
r[n] = p, s.push(p);
|
|
6885
|
-
}), this._documentInfoMap.set(r), s;
|
|
6886
|
-
}
|
|
6887
|
-
/**
|
|
6888
|
-
* Returns a single arbitrary file path from the project's triplestore.
|
|
6889
|
-
* Useful for pre-filling path-based query inputs with a realistic example.
|
|
6890
|
-
*/
|
|
6891
|
-
async randomFilePath() {
|
|
6892
|
-
const t = `PREFIX qcy: <${b.qcy}>
|
|
6893
|
-
SELECT ?path
|
|
6894
|
-
WHERE {
|
|
6895
|
-
?fl a qcy:FileLocation ;
|
|
6896
|
-
qcy:filePath ?path .
|
|
6897
|
-
}
|
|
6898
|
-
LIMIT 1`;
|
|
6899
|
-
return (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings[0]?.path?.value ?? null;
|
|
6900
|
-
}
|
|
6901
|
-
// ── Private helpers ────────────────────────────────────────────────────────
|
|
6902
|
-
/** Executes the document-info SPARQL query for the given UUIDs, merges results
|
|
6903
|
-
* into `documentInfoMap`, and returns the newly fetched entries. */
|
|
6904
|
-
async _fetchDocumentInfoBatch(t) {
|
|
6905
|
-
const e = t.map((p) => `r:${p}`).join(" "), o = this._api.language, r = `PREFIX qcy: <${b.qcy}>
|
|
6906
|
-
PREFIX r: <${this.baseURL}>
|
|
6907
|
-
SELECT ?id ?contentIRI ?suffix ?size ?subject ?summary
|
|
6908
|
-
(SAMPLE(?fp) AS ?path)
|
|
6909
|
-
(GROUP_CONCAT(DISTINCT ?tag; SEPARATOR=";") AS ?tags)
|
|
6910
|
-
(GROUP_CONCAT(DISTINCT STR(?cat); SEPARATOR=";") AS ?categories)
|
|
6911
|
-
WHERE {
|
|
6912
|
-
VALUES ?contentIRI { ${e} }
|
|
6913
|
-
?contentIRI qcy:sizeBytes ?size ;
|
|
6914
|
-
qcy:hasFileLocation ?loc .
|
|
6915
|
-
?loc qcy:filePath ?fp ;
|
|
6916
|
-
qcy:suffix ?suffix .
|
|
6917
|
-
OPTIONAL { ?contentIRI qcy:hasContentCategory ?cat }
|
|
6918
|
-
OPTIONAL { ?contentIRI qcy:tag ?tag }
|
|
6919
|
-
OPTIONAL { ?loc qcy:remoteProviderId ?pid }
|
|
6920
|
-
|
|
6921
|
-
OPTIONAL { ?contentIRI qcy:subject ?lang_subj FILTER(LANG(?lang_subj) = "${o}") }
|
|
6922
|
-
OPTIONAL { ?contentIRI qcy:subject ?no_lang_subj }
|
|
6923
|
-
BIND(COALESCE(?lang_subj, ?no_lang_subj) AS ?subject)
|
|
6924
|
-
|
|
6925
|
-
OPTIONAL { ?contentIRI qcy:textSummary ?lang_summary FILTER(LANG(?lang_summary) = "${o}") }
|
|
6926
|
-
OPTIONAL { ?contentIRI qcy:textSummary ?no_lang_summary }
|
|
6927
|
-
BIND(COALESCE(?lang_summary, ?no_lang_summary) AS ?summary)
|
|
6928
|
-
|
|
6929
|
-
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?id)
|
|
6930
|
-
}
|
|
6931
|
-
GROUP BY ?id ?contentIRI ?suffix ?size ?subject ?summary`, s = await this._api.sparql(r, this._projectId), a = { ...this._documentInfoMap.get() }, n = {};
|
|
6932
|
-
return s.results.bindings.forEach((p) => {
|
|
6933
|
-
if (!p.id || !p.contentIRI) return;
|
|
6934
|
-
const c = p.id.value, h = {
|
|
6935
|
-
id: c,
|
|
6936
|
-
contentIRI: p.contentIRI.value,
|
|
6937
|
-
path: p.path?.value ?? "",
|
|
6938
|
-
suffix: p.suffix?.value ?? "",
|
|
6939
|
-
size: p.size ? parseInt(p.size.value, 10) : 0,
|
|
6940
|
-
tags: p.tags?.value?.split(";").filter(Boolean) ?? [],
|
|
6941
|
-
categories: p.categories?.value?.split(";").filter(Boolean) ?? [],
|
|
6942
|
-
subject: p.subject?.value,
|
|
6943
|
-
summary: p.summary?.value,
|
|
6944
|
-
providerId: p.pid?.value
|
|
6945
|
-
};
|
|
6946
|
-
a[c] = h, n[c] = h;
|
|
6947
|
-
}), this._documentInfoMap.set(a), n;
|
|
6948
|
-
}
|
|
6949
|
-
/** Executes a reduced document-info query (id/path/suffix/size only), merges
|
|
6950
|
-
* into `documentInfoMap`, and returns newly fetched entries. */
|
|
6951
|
-
async _fetchSimpleDocumentInfoBatch(t) {
|
|
6952
|
-
const e = t.map((n) => `r:${n}`).join(" "), o = `PREFIX qcy: <${b.qcy}>
|
|
6953
|
-
PREFIX r: <${this.baseURL}>
|
|
6954
|
-
SELECT ?id ?contentIRI ?suffix ?size (SAMPLE(?fp) AS ?path)
|
|
6955
|
-
WHERE {
|
|
6956
|
-
VALUES ?contentIRI { ${e} }
|
|
6957
|
-
?contentIRI qcy:sizeBytes ?size ;
|
|
6958
|
-
qcy:hasFileLocation ?loc .
|
|
6959
|
-
?loc qcy:filePath ?fp ;
|
|
6960
|
-
qcy:suffix ?suffix .
|
|
6961
|
-
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?id)
|
|
6962
|
-
}
|
|
6963
|
-
GROUP BY ?id ?contentIRI ?suffix ?size`, r = await this._api.sparql(o, this._projectId, this._graphType), s = { ...this._documentInfoMap.get() }, a = {};
|
|
6964
|
-
return r.results.bindings.forEach((n) => {
|
|
6965
|
-
if (!n.id) return;
|
|
6966
|
-
const p = n.id.value, c = s[p], h = {
|
|
6967
|
-
id: p,
|
|
6968
|
-
contentIRI: n.contentIRI?.value ?? c?.contentIRI ?? p,
|
|
6969
|
-
path: n.path?.value ?? c?.path ?? p,
|
|
6970
|
-
suffix: n.suffix?.value ?? c?.suffix ?? "",
|
|
6971
|
-
size: n.size ? parseInt(n.size.value, 10) : c?.size ?? 0,
|
|
6972
|
-
tags: c?.tags ?? [],
|
|
6973
|
-
categories: c?.categories ?? [],
|
|
6974
|
-
subject: c?.subject,
|
|
6975
|
-
summary: c?.summary,
|
|
6976
|
-
providerId: c?.providerId
|
|
6977
|
-
};
|
|
6978
|
-
s[p] = h, a[p] = h;
|
|
6979
|
-
}), this._documentInfoMap.set(s), a;
|
|
6980
|
-
}
|
|
6981
|
-
async _fetchDocumentsBySuffix() {
|
|
6982
|
-
return this._runDocumentsBySuffixQuery(this._buildDocumentsBySuffixQuery());
|
|
6983
|
-
}
|
|
6984
|
-
_buildDocumentsBySuffixQuery() {
|
|
6985
|
-
return `PREFIX qcy: <${b.qcy}>
|
|
6986
|
-
SELECT ?ext (SUM(?size) AS ?totalSize) (COUNT(*) AS ?docCount)
|
|
6987
|
-
WHERE {
|
|
6988
|
-
{
|
|
6989
|
-
SELECT DISTINCT ?fc ?ext ?size
|
|
6990
|
-
WHERE {
|
|
6991
|
-
?fc a qcy:FileContent ;
|
|
6992
|
-
qcy:sizeBytes ?size ;
|
|
6993
|
-
qcy:hasFileLocation/qcy:suffix ?ext .
|
|
6994
|
-
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
6995
|
-
}
|
|
6996
|
-
}
|
|
6997
|
-
}
|
|
6998
|
-
GROUP BY ?ext
|
|
6999
|
-
ORDER BY DESC(?docCount)`;
|
|
7000
|
-
}
|
|
7001
|
-
async _runDocumentsBySuffixQuery(t) {
|
|
7002
|
-
const e = await this._api.sparql(t, this._projectId, this._graphType), o = {};
|
|
7003
|
-
return e.results.bindings.forEach((r) => {
|
|
7004
|
-
r.ext && (o[r.ext.value] = {
|
|
7005
|
-
size: r.totalSize ? parseInt(r.totalSize.value, 10) : 0,
|
|
7006
|
-
count: r.docCount ? parseInt(r.docCount.value, 10) : 0
|
|
7007
|
-
});
|
|
7008
|
-
}), o;
|
|
7009
|
-
}
|
|
7010
|
-
async _fetchDocumentsByContentCategory() {
|
|
7011
|
-
return this._runDocumentsByContentCategoryQuery(this._buildDocumentsByContentCategoryQuery());
|
|
7012
|
-
}
|
|
7013
|
-
_buildDocumentsByContentCategoryQuery() {
|
|
7014
|
-
return `PREFIX qcy: <${b.qcy}>
|
|
7015
|
-
SELECT ?cat (SUM(?size) AS ?totalSize) (COUNT(*) AS ?docCount)
|
|
7016
|
-
WHERE {
|
|
7017
|
-
{
|
|
7018
|
-
SELECT DISTINCT ?fc ?cat ?size
|
|
7019
|
-
WHERE {
|
|
7020
|
-
?fc a qcy:FileContent ;
|
|
7021
|
-
qcy:hasContentCategory ?cat ;
|
|
7022
|
-
qcy:sizeBytes ?size .
|
|
7023
|
-
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
7024
|
-
}
|
|
7025
|
-
}
|
|
7026
|
-
}
|
|
7027
|
-
GROUP BY ?cat
|
|
7028
|
-
ORDER BY DESC(?docCount)`;
|
|
7029
|
-
}
|
|
7030
|
-
async _runDocumentsByContentCategoryQuery(t) {
|
|
7031
|
-
const e = await this._api.sparql(t, this._projectId, this._graphType), o = {};
|
|
7032
|
-
return e.results.bindings.forEach((r) => {
|
|
7033
|
-
r.cat && (o[r.cat.value] = {
|
|
7034
|
-
size: r.totalSize ? parseInt(r.totalSize.value, 10) : 0,
|
|
7035
|
-
count: r.docCount ? parseInt(r.docCount.value, 10) : 0
|
|
7036
|
-
});
|
|
7037
|
-
}), o;
|
|
7038
|
-
}
|
|
7039
|
-
async _fetchDuplicateCount() {
|
|
7040
|
-
return this._runDuplicateCountQuery(this._buildDuplicateCountQuery());
|
|
7041
|
-
}
|
|
7042
|
-
_buildDuplicateCountQuery() {
|
|
7043
|
-
return `PREFIX qcy: <${b.qcy}>
|
|
7044
|
-
SELECT (COUNT(*) AS ?count)
|
|
7045
|
-
WHERE {
|
|
7046
|
-
SELECT ?fc
|
|
7047
|
-
WHERE {
|
|
7048
|
-
?fc a qcy:FileContent ;
|
|
7049
|
-
qcy:hasFileLocation ?fl .
|
|
7050
|
-
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
7051
|
-
}
|
|
7052
|
-
GROUP BY ?fc
|
|
7053
|
-
HAVING (COUNT(?fl) > 1)
|
|
7054
|
-
}`;
|
|
7055
|
-
}
|
|
7056
|
-
async _runDuplicateCountQuery(t) {
|
|
7057
|
-
const o = (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings[0];
|
|
7058
|
-
return o?.count ? parseInt(o.count.value, 10) : 0;
|
|
7059
|
-
}
|
|
7060
|
-
}
|
|
7061
|
-
class cr {
|
|
7062
|
-
constructor(t, e, { language: o, queryCache: r, rdfBase: s = dt, graphType: a }) {
|
|
7063
|
-
this._api = t, this._projectId = e, this.schema = new pr(t, e, o, r, a), this.entities = new me(t, e, s, r, a), this.documents = new pt(t, e, o, s, r, a), this.availableContentCategories = this.schema.availableContentCategories, this.availableEntityCategories = this.schema.availableEntityCategories, this.availableEntityRelationships = this.schema.availableEntityRelationships, this.schemaReady = this.schema.ready, this.entityInfoMap = this.entities.entityInfoMap, this.entityGraph = this.entities.entityGraph, this.documentInfoMap = this.documents.documentInfoMap, this.projectDocumentsData = this.documents.projectDocumentsData, this.searchResults = this._searchResults.asReadonly(), this.documents.fetchOverview().catch((n) => console.error("[CueProjectView] fetchOverview failed:", n));
|
|
7064
|
-
}
|
|
7065
|
-
_api;
|
|
7066
|
-
_projectId;
|
|
7067
|
-
/** Direct access to the schema data class (available categories / relationships). */
|
|
7068
|
-
schema;
|
|
7069
|
-
/** Direct access to the entity data class. */
|
|
7070
|
-
entities;
|
|
7071
|
-
/** Direct access to the document data class. */
|
|
7072
|
-
documents;
|
|
7073
|
-
// ── Proxied signals ────────────────────────────────────────────────────────
|
|
7074
|
-
/** Available content category definitions for this project. Auto-fetched on init. */
|
|
7075
|
-
availableContentCategories;
|
|
7076
|
-
/** Available entity category definitions for this project. Auto-fetched on init. */
|
|
7077
|
-
availableEntityCategories;
|
|
7078
|
-
/** Available entity relationship types. Auto-fetched on init. */
|
|
7079
|
-
availableEntityRelationships;
|
|
7080
|
-
/**
|
|
7081
|
-
* Resolves when the initial schema load has completed. Await before reading
|
|
7082
|
-
* schema signal values imperatively.
|
|
7083
|
-
*/
|
|
7084
|
-
schemaReady;
|
|
7085
|
-
/** Merged per-entity detail map. Populated lazily via `requestEntityData()` etc. */
|
|
7086
|
-
entityInfoMap;
|
|
7087
|
-
/** Project-level entity co-occurrence graph. Fetched once on init. */
|
|
7088
|
-
entityGraph;
|
|
7089
|
-
/** Per-document info map. Populated lazily via `requestDocumentData()`. */
|
|
7090
|
-
documentInfoMap;
|
|
7091
|
-
/** Project document overview (counts by suffix and category). Fetched on init. */
|
|
7092
|
-
projectDocumentsData;
|
|
7093
|
-
// ── Search state ───────────────────────────────────────────────────────────
|
|
7094
|
-
_searchResults = new k(void 0);
|
|
7095
|
-
/** The result of the most recent `search()` call. `undefined` before first search. */
|
|
7096
|
-
searchResults;
|
|
7097
|
-
_destroyed = !1;
|
|
7098
|
-
// ── Entity methods ─────────────────────────────────────────────────────────
|
|
7099
|
-
/**
|
|
7100
|
-
* Lazily batch-fetch core data (label + categories) for the given entity UUIDs.
|
|
7101
|
-
* Already-fetched UUIDs are skipped. Populates `entityInfoMap`.
|
|
7102
|
-
*/
|
|
7103
|
-
requestEntityData(t, e = !1) {
|
|
7104
|
-
this._destroyed || this.entities.requestEntityData(t, e);
|
|
7105
|
-
}
|
|
7106
|
-
/**
|
|
7107
|
-
* Lazily fetch OSM location data for the given entity UUIDs.
|
|
7108
|
-
* Already-fetched UUIDs are skipped. Populates `entityInfoMap` geometry fields.
|
|
7109
|
-
*/
|
|
7110
|
-
async requestEntityLocations(t) {
|
|
7111
|
-
if (!this._destroyed)
|
|
7112
|
-
return this.entities.requestEntityLocations(t);
|
|
7113
|
-
}
|
|
7114
|
-
/**
|
|
7115
|
-
* Fetch incoming and outgoing relationships for a single entity IRI.
|
|
7116
|
-
* Result is stored in `entityInfoMap[uuid].relationshipData`.
|
|
7117
|
-
*/
|
|
7118
|
-
async fetchEntityRelationships(t) {
|
|
7119
|
-
if (this._destroyed) throw new Error("CueProjectView is destroyed");
|
|
7120
|
-
return this.entities.fetchEntityRelationships(t);
|
|
7121
|
-
}
|
|
7122
|
-
/**
|
|
7123
|
-
* Fetch UUIDs of documents that reference the given entity IRI.
|
|
7124
|
-
* Result is stored in `entityInfoMap[uuid].documentRefs`.
|
|
7125
|
-
*/
|
|
7126
|
-
async fetchEntityDocuments(t) {
|
|
7127
|
-
if (this._destroyed) throw new Error("CueProjectView is destroyed");
|
|
7128
|
-
return this.entities.fetchEntityDocuments(t);
|
|
7129
|
-
}
|
|
7130
|
-
/** Constructs the full RDF IRI for an entity UUID. */
|
|
7131
|
-
entityIri(t) {
|
|
7132
|
-
return this.entities.entityIri(t);
|
|
7133
|
-
}
|
|
7134
|
-
// ── Document methods ───────────────────────────────────────────────────────
|
|
7135
|
-
/**
|
|
7136
|
-
* Lazily batch-fetch document info for the given UUIDs.
|
|
7137
|
-
* Already-fetched UUIDs are skipped. Populates `documentInfoMap`.
|
|
7138
|
-
*/
|
|
7139
|
-
requestDocumentData(t) {
|
|
7140
|
-
this._destroyed || this.documents.requestDocumentData(t);
|
|
7141
|
-
}
|
|
7142
|
-
// ── Search ─────────────────────────────────────────────────────────────────
|
|
7143
|
-
/**
|
|
7144
|
-
* Run a natural-language search against the project.
|
|
7145
|
-
* The result is stored in `searchResults` and replaces any previous result.
|
|
7146
|
-
*/
|
|
7147
|
-
async search(t, e) {
|
|
7148
|
-
if (this._destroyed) return;
|
|
7149
|
-
const o = await this._api.search({
|
|
7150
|
-
term: t,
|
|
7151
|
-
projectId: this._projectId,
|
|
7152
|
-
categories: e?.categories
|
|
7153
|
-
});
|
|
7154
|
-
this._destroyed || this._searchResults.set(o);
|
|
7155
|
-
}
|
|
7156
|
-
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
7157
|
-
/**
|
|
7158
|
-
* Switch the active language for schema labels and document text fields.
|
|
7159
|
-
* Schema responses are cached per language (instant if previously loaded).
|
|
7160
|
-
* The document info map is cleared and lazily re-populated on next access.
|
|
7161
|
-
*/
|
|
7162
|
-
setLanguage(t) {
|
|
7163
|
-
this._destroyed || (this.schema.setLanguage(t), this.documents.setLanguage(t));
|
|
7164
|
-
}
|
|
7165
|
-
/**
|
|
7166
|
-
* Reset all entity and document state and re-fetch the project overview.
|
|
7167
|
-
* Prefer creating a fresh `CueProjectView` when switching projects.
|
|
7168
|
-
* Use `reset()` only when the same project's data needs to be invalidated.
|
|
7169
|
-
*/
|
|
7170
|
-
reset() {
|
|
7171
|
-
this._destroyed || (this.entities.reset(), this.documents.reset(), this._searchResults.set(void 0), this.documents.fetchOverview().catch((t) => console.error("[CueProjectView] fetchOverview failed after reset:", t)));
|
|
7172
|
-
}
|
|
7173
|
-
/**
|
|
7174
|
-
* Tear down this view instance. Clears all reactive state and blocks further
|
|
7175
|
-
* updates. Call from the Angular adapter's `ngOnDestroy` or equivalent.
|
|
7176
|
-
*/
|
|
7177
|
-
destroy() {
|
|
7178
|
-
this._destroyed = !0, this._searchResults.set(void 0);
|
|
7179
|
-
}
|
|
7180
|
-
}
|
|
7181
|
-
function Xt(i, t) {
|
|
7182
|
-
return new Promise((e) => {
|
|
7183
|
-
const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
7184
|
-
for (const m of i)
|
|
7185
|
-
o.has(m.contentUUID) || o.set(m.contentUUID, []), o.get(m.contentUUID)?.push(m), r.set(m.locationUUID, m);
|
|
7186
|
-
const s = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map();
|
|
7187
|
-
for (const m of t)
|
|
7188
|
-
s.has(m.contentUUID) || s.set(m.contentUUID, []), s.get(m.contentUUID)?.push(m), m.locationUUID && a.set(m.locationUUID, m);
|
|
7189
|
-
const n = [], p = [];
|
|
7190
|
-
for (const m of i)
|
|
7191
|
-
s.has(m.contentUUID) ? (s.get(m.contentUUID) || []).some((v) => v.locationUUID === m.locationUUID) || p.push(m) : n.push(m);
|
|
7192
|
-
const c = [], h = [];
|
|
7193
|
-
for (const m of t) {
|
|
7194
|
-
const x = o.get(m.contentUUID);
|
|
7195
|
-
x ? x.some((v) => v.locationUUID === m.locationUUID) || h.push(m) : c.push(m);
|
|
7196
|
-
}
|
|
7197
|
-
const d = i.length - n.length - p.length, g = i.length, w = g > 0 ? d / g : 1;
|
|
7198
|
-
let u = 0, f = 0;
|
|
7199
|
-
for (const m of i)
|
|
7200
|
-
f += m.size || 0, (s.get(m.contentUUID) || []).some((v) => v.locationUUID === m.locationUUID) && (u += m.size || 0);
|
|
7201
|
-
const E = f > 0 ? u / f : 1;
|
|
7202
|
-
e({
|
|
7203
|
-
localNotOnRemote: n,
|
|
7204
|
-
localNotOnRemotePathOnly: p,
|
|
7205
|
-
remoteNotOnLocal: c,
|
|
7206
|
-
remoteNotOnLocalPathOnly: h,
|
|
7207
|
-
syncCount: d,
|
|
7208
|
-
totalCount: g,
|
|
7209
|
-
syncSize: u,
|
|
7210
|
-
totalSize: f,
|
|
7211
|
-
synctPctSize: E,
|
|
7212
|
-
synctPctCount: w
|
|
7213
|
-
});
|
|
7214
|
-
});
|
|
7215
|
-
}
|
|
7216
6755
|
var l = /* @__PURE__ */ ((i) => (i.AUTOMATION = "automation", i.ARCHIVE = "archive", i.AUDIO = "audio", i.BACKUP = "backup", i.BINARY = "binary", i.BIM = "bim", i.CAD = "cad", i.DATA = "data", i.EMAIL = "email", i.FONT = "font", i.GEOSPATIAL = "geospatial", i.IMAGE = "image", i.INSTALLER = "installer", i.MARKUP = "markup", i.MULTIMEDIA = "multimedia", i.PLANNING = "planning", i.PRESENTATION = "presentation", i.SCRIPT = "script", i.SPREADSHEET = "spreadsheet", i.TEXT = "text", i.THREE_D = "3d", i.UNKNOWN = "unknown", i.VIDEO = "video", i))(l || {});
|
|
7217
|
-
const
|
|
6756
|
+
const lt = {
|
|
7218
6757
|
".aac": {
|
|
7219
6758
|
type: l.AUDIO,
|
|
7220
6759
|
open: !0,
|
|
@@ -8073,8 +7612,541 @@ const hr = {
|
|
|
8073
7612
|
suffix: ".fragments",
|
|
8074
7613
|
mime: "application/octet-stream"
|
|
8075
7614
|
}
|
|
8076
|
-
};
|
|
8077
|
-
l.AUDIO + "", l.VIDEO + "", l.IMAGE + "", l.TEXT + "", l.MARKUP + "", l.SCRIPT + "", l.DATA + "", l.ARCHIVE + "", l.INSTALLER + "", l.BINARY + "", l.BACKUP + "", l.AUTOMATION + "", l.PRESENTATION + "", l.SPREADSHEET + "", l.FONT + "", l.GEOSPATIAL + "", l.THREE_D + "", l.CAD + "", l.BIM + "", l.PLANNING + "", l.EMAIL + "", l.MULTIMEDIA + "", l.UNKNOWN + "";
|
|
7615
|
+
};
|
|
7616
|
+
l.AUDIO + "", l.VIDEO + "", l.IMAGE + "", l.TEXT + "", l.MARKUP + "", l.SCRIPT + "", l.DATA + "", l.ARCHIVE + "", l.INSTALLER + "", l.BINARY + "", l.BACKUP + "", l.AUTOMATION + "", l.PRESENTATION + "", l.SPREADSHEET + "", l.FONT + "", l.GEOSPATIAL + "", l.THREE_D + "", l.CAD + "", l.BIM + "", l.PLANNING + "", l.EMAIL + "", l.MULTIMEDIA + "", l.UNKNOWN + "";
|
|
7617
|
+
class ct {
|
|
7618
|
+
constructor(t, e, o, r = ut, s, a) {
|
|
7619
|
+
this._api = t, this._projectId = e, this._queryCache = s, this._graphType = a, this.baseURL = `${r}${e}/`, this._currentLang = o ?? this._api.language, this.documentInfoMap = this._documentInfoMap.asReadonly(), this.projectDocumentsData = this._projectDocumentsData.asReadonly();
|
|
7620
|
+
}
|
|
7621
|
+
_api;
|
|
7622
|
+
_projectId;
|
|
7623
|
+
_queryCache;
|
|
7624
|
+
_graphType;
|
|
7625
|
+
/** Full RDF base URL for this project, e.g. `https://cue.qaecy.com/r/{pid}/` */
|
|
7626
|
+
baseURL;
|
|
7627
|
+
/** Tracks the language for which `_documentInfoMap` is currently populated. */
|
|
7628
|
+
_currentLang;
|
|
7629
|
+
_documentInfoMap = new k({});
|
|
7630
|
+
_projectDocumentsData = new k({
|
|
7631
|
+
duplicateCount: 0,
|
|
7632
|
+
documentsBySuffix: {},
|
|
7633
|
+
documentsByContentCategory: {}
|
|
7634
|
+
});
|
|
7635
|
+
/** Lazily populated per-document detail map. */
|
|
7636
|
+
documentInfoMap;
|
|
7637
|
+
/** Project-level document overview (grouped counts + sizes). */
|
|
7638
|
+
projectDocumentsData;
|
|
7639
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
7640
|
+
/**
|
|
7641
|
+
* Resets all document state. Call when the active project changes.
|
|
7642
|
+
* Follow with `fetchOverview()` once the triplestore is ready.
|
|
7643
|
+
*/
|
|
7644
|
+
reset() {
|
|
7645
|
+
this._documentInfoMap.set({}), this._projectDocumentsData.set({
|
|
7646
|
+
duplicateCount: 0,
|
|
7647
|
+
documentsBySuffix: {},
|
|
7648
|
+
documentsByContentCategory: {}
|
|
7649
|
+
});
|
|
7650
|
+
}
|
|
7651
|
+
/**
|
|
7652
|
+
* Updates the active language and clears the document info map so that
|
|
7653
|
+
* language-sensitive fields (subject, summary) are re-fetched on the next
|
|
7654
|
+
* `requestDocumentData()` call.
|
|
7655
|
+
*/
|
|
7656
|
+
setLanguage(t) {
|
|
7657
|
+
this._currentLang !== t && (this._currentLang = t, this._api.setLanguage(t), this._documentInfoMap.set({}));
|
|
7658
|
+
}
|
|
7659
|
+
// ── Public API ─────────────────────────────────────────────────────────────
|
|
7660
|
+
/**
|
|
7661
|
+
* Fetches the three-part project overview (by suffix, by content category,
|
|
7662
|
+
* duplicate count) in parallel and writes them as a single atomic update to
|
|
7663
|
+
* `projectDocumentsData`. Safe to call again to refresh.
|
|
7664
|
+
*/
|
|
7665
|
+
async fetchOverview() {
|
|
7666
|
+
this._projectDocumentsData.set({
|
|
7667
|
+
duplicateCount: 0,
|
|
7668
|
+
documentsBySuffix: {},
|
|
7669
|
+
documentsByContentCategory: {}
|
|
7670
|
+
});
|
|
7671
|
+
const t = this._buildDocumentsBySuffixQuery(), e = this._buildDocumentsByContentCategoryQuery(), o = this._buildDuplicateCountQuery();
|
|
7672
|
+
await gt(
|
|
7673
|
+
t + e + o,
|
|
7674
|
+
async () => {
|
|
7675
|
+
const [r, s, a] = await Promise.all([
|
|
7676
|
+
this._runDocumentsBySuffixQuery(t),
|
|
7677
|
+
this._runDocumentsByContentCategoryQuery(e),
|
|
7678
|
+
this._runDuplicateCountQuery(o)
|
|
7679
|
+
]);
|
|
7680
|
+
return { duplicateCount: a, documentsBySuffix: r, documentsByContentCategory: s };
|
|
7681
|
+
},
|
|
7682
|
+
(r) => this._projectDocumentsData.set(r),
|
|
7683
|
+
this._queryCache
|
|
7684
|
+
);
|
|
7685
|
+
}
|
|
7686
|
+
/**
|
|
7687
|
+
* Lazily batch-fetches core metadata for the given document UUIDs.
|
|
7688
|
+
* Already-cached UUIDs are skipped. Data is merged into `documentInfoMap`
|
|
7689
|
+
* once the SPARQL response arrives.
|
|
7690
|
+
*/
|
|
7691
|
+
requestDocumentData(t) {
|
|
7692
|
+
const e = t.filter((o) => this._documentInfoMap.get()[o] === void 0);
|
|
7693
|
+
e.length !== 0 && this._fetchDocumentInfoBatch(e).catch(
|
|
7694
|
+
(o) => console.error("[CueProjectDocuments] requestDocumentData failed:", o)
|
|
7695
|
+
);
|
|
7696
|
+
}
|
|
7697
|
+
/**
|
|
7698
|
+
* Promise-based alternative to {@link requestDocumentData} for non-reactive contexts.
|
|
7699
|
+
*
|
|
7700
|
+
* Resolves with the `DocumentInfo` entries for every requested UUID once the
|
|
7701
|
+
* SPARQL response arrives. UUIDs already present in the cache are returned
|
|
7702
|
+
* immediately without a network request. The result is also written into
|
|
7703
|
+
* `documentInfoMap` so reactive consumers stay in sync.
|
|
7704
|
+
*
|
|
7705
|
+
* UUIDs not found in the triplestore are omitted from the returned map.
|
|
7706
|
+
*
|
|
7707
|
+
* @example
|
|
7708
|
+
* ```ts
|
|
7709
|
+
* const docs = await cueProjectDocs.fetchDocumentData(['uuid1', 'uuid2']);
|
|
7710
|
+
* console.log(docs['uuid1'].subject);
|
|
7711
|
+
* ```
|
|
7712
|
+
*/
|
|
7713
|
+
async fetchDocumentData(t) {
|
|
7714
|
+
const e = this._documentInfoMap.get(), o = t.filter((s) => e[s] === void 0);
|
|
7715
|
+
o.length > 0 && await this._fetchDocumentInfoBatch(o);
|
|
7716
|
+
const r = this._documentInfoMap.get();
|
|
7717
|
+
return Object.fromEntries(
|
|
7718
|
+
t.filter((s) => r[s] !== void 0).map((s) => [s, r[s]])
|
|
7719
|
+
);
|
|
7720
|
+
}
|
|
7721
|
+
/**
|
|
7722
|
+
* Fetches a lightweight document metadata shape (id/path/suffix/size) for
|
|
7723
|
+
* the given UUIDs and merges the results into `documentInfoMap`.
|
|
7724
|
+
*
|
|
7725
|
+
* This is useful for list/table contexts that do not need language-tagged
|
|
7726
|
+
* fields (`subject`, `summary`) or category/tag enrichment.
|
|
7727
|
+
*
|
|
7728
|
+
* UUIDs already present in `documentInfoMap` are skipped.
|
|
7729
|
+
*/
|
|
7730
|
+
async fetchDocumentDataSimple(t) {
|
|
7731
|
+
const e = this._documentInfoMap.get(), o = t.filter((s) => e[s] === void 0);
|
|
7732
|
+
o.length > 0 && await this._fetchSimpleDocumentInfoBatch(o);
|
|
7733
|
+
const r = this._documentInfoMap.get();
|
|
7734
|
+
return Object.fromEntries(
|
|
7735
|
+
t.filter((s) => r[s] !== void 0).map((s) => [s, r[s]])
|
|
7736
|
+
);
|
|
7737
|
+
}
|
|
7738
|
+
/**
|
|
7739
|
+
* Returns the alternative representations of the given document UUID.
|
|
7740
|
+
*
|
|
7741
|
+
* Alternative representations are derived artefacts stored under
|
|
7742
|
+
* `qcy:alternativeRepresentation` in the triplestore — for example a
|
|
7743
|
+
* `.fragments` BIM tile derived from an `.ifc` source file.
|
|
7744
|
+
*
|
|
7745
|
+
* The returned `DocumentInfo` entries are also merged into
|
|
7746
|
+
* `documentInfoMap` so reactive consumers stay in sync.
|
|
7747
|
+
*
|
|
7748
|
+
* @example
|
|
7749
|
+
* ```ts
|
|
7750
|
+
* const alts = await docs.fetchAlternativeRepresentations('abc-123');
|
|
7751
|
+
* // alts[0].suffix => '.fragments'
|
|
7752
|
+
* ```
|
|
7753
|
+
*/
|
|
7754
|
+
async fetchAlternativeRepresentations(t) {
|
|
7755
|
+
const e = `PREFIX qcy: <${y.qcy}>
|
|
7756
|
+
PREFIX r: <${this.baseURL}>
|
|
7757
|
+
SELECT ?altId ?contentIRI ?suffix ?rrp
|
|
7758
|
+
WHERE {
|
|
7759
|
+
r:${t} qcy:alternativeRepresentation ?contentIRI .
|
|
7760
|
+
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?altId)
|
|
7761
|
+
?contentIRI qcy:hasFileLocation ?loc .
|
|
7762
|
+
?loc qcy:suffix ?suffix .
|
|
7763
|
+
OPTIONAL { ?loc qcy:remoteRelativePath ?rrp }
|
|
7764
|
+
}`, o = await this._api.sparql(e, this._projectId, this._graphType), r = { ...this._documentInfoMap.get() }, s = [];
|
|
7765
|
+
return o.results.bindings.forEach((a) => {
|
|
7766
|
+
if (!a.altId || !a.contentIRI) return;
|
|
7767
|
+
const n = a.altId.value, p = {
|
|
7768
|
+
id: n,
|
|
7769
|
+
contentIRI: a.contentIRI.value,
|
|
7770
|
+
path: "",
|
|
7771
|
+
suffix: a.suffix?.value ?? "",
|
|
7772
|
+
size: 0,
|
|
7773
|
+
tags: [],
|
|
7774
|
+
categories: [],
|
|
7775
|
+
remoteRelativePath: a.rrp?.value
|
|
7776
|
+
};
|
|
7777
|
+
r[n] = p, s.push(p);
|
|
7778
|
+
}), this._documentInfoMap.set(r), s;
|
|
7779
|
+
}
|
|
7780
|
+
/**
|
|
7781
|
+
* Returns a single arbitrary file path from the project's triplestore.
|
|
7782
|
+
* Useful for pre-filling path-based query inputs with a realistic example.
|
|
7783
|
+
*/
|
|
7784
|
+
async randomFilePath() {
|
|
7785
|
+
const t = `PREFIX qcy: <${y.qcy}>
|
|
7786
|
+
SELECT ?path
|
|
7787
|
+
WHERE {
|
|
7788
|
+
?fl a qcy:FileLocation ;
|
|
7789
|
+
qcy:filePath ?path .
|
|
7790
|
+
}
|
|
7791
|
+
LIMIT 1`;
|
|
7792
|
+
return (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings[0]?.path?.value ?? null;
|
|
7793
|
+
}
|
|
7794
|
+
async documentsBySuffix(t, e = !1) {
|
|
7795
|
+
if (t.length === 0) return [];
|
|
7796
|
+
const r = t.map(
|
|
7797
|
+
(n) => (n.startsWith(".") ? n : `.${n}`).toLowerCase()
|
|
7798
|
+
).map((n) => `"${n}"`).join(" "), s = e ? `PREFIX qcy: <${y.qcy}>
|
|
7799
|
+
SELECT ?iri ?id (SAMPLE(?fp) AS ?path) ?suffix (MAX(?sz) AS ?size)
|
|
7800
|
+
WHERE {
|
|
7801
|
+
VALUES ?suffix { ${r} }
|
|
7802
|
+
?iri a qcy:FileContent ;
|
|
7803
|
+
qcy:sizeBytes ?sz ;
|
|
7804
|
+
qcy:hasFileLocation ?loc .
|
|
7805
|
+
?loc qcy:suffix ?suffix ;
|
|
7806
|
+
qcy:filePath ?fp .
|
|
7807
|
+
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?iri }
|
|
7808
|
+
BIND(REPLACE(STR(?iri), "^.*/", "") AS ?id)
|
|
7809
|
+
}
|
|
7810
|
+
GROUP BY ?iri ?id ?suffix` : `PREFIX qcy: <${y.qcy}>
|
|
7811
|
+
SELECT DISTINCT ?id
|
|
7812
|
+
WHERE {
|
|
7813
|
+
VALUES ?suffix { ${r} }
|
|
7814
|
+
?iri a qcy:FileContent ;
|
|
7815
|
+
qcy:hasFileLocation/qcy:suffix ?suffix .
|
|
7816
|
+
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?iri }
|
|
7817
|
+
BIND(REPLACE(STR(?iri), "^.*/", "") AS ?id)
|
|
7818
|
+
}`, a = await this._api.sparql(s, this._projectId, this._graphType);
|
|
7819
|
+
return e ? a.results.bindings.filter((n) => n.iri && n.id).map((n) => ({
|
|
7820
|
+
iri: n.iri.value,
|
|
7821
|
+
uuid: n.id.value,
|
|
7822
|
+
path: n.path?.value ?? "",
|
|
7823
|
+
suffix: n.suffix?.value ?? "",
|
|
7824
|
+
size: n.size ? parseInt(n.size.value, 10) : 0
|
|
7825
|
+
})) : a.results.bindings.filter((n) => n.id).map((n) => n.id.value);
|
|
7826
|
+
}
|
|
7827
|
+
documentsByFileType(t, e = !1) {
|
|
7828
|
+
const o = new Set(t), r = Object.values(lt).filter((s) => o.has(s.type)).map((s) => s.suffix);
|
|
7829
|
+
return this.documentsBySuffix(r, e);
|
|
7830
|
+
}
|
|
7831
|
+
documentsByMime(t, e = !1) {
|
|
7832
|
+
const o = new Set(t), r = Object.values(lt).filter((s) => o.has(s.mime)).map((s) => s.suffix);
|
|
7833
|
+
return this.documentsBySuffix(r, e);
|
|
7834
|
+
}
|
|
7835
|
+
// ── Private helpers ────────────────────────────────────────────────────────
|
|
7836
|
+
/** Executes the document-info SPARQL query for the given UUIDs, merges results
|
|
7837
|
+
* into `documentInfoMap`, and returns the newly fetched entries. */
|
|
7838
|
+
async _fetchDocumentInfoBatch(t) {
|
|
7839
|
+
const e = t.map((p) => `r:${p}`).join(" "), o = this._api.language, r = `PREFIX qcy: <${y.qcy}>
|
|
7840
|
+
PREFIX r: <${this.baseURL}>
|
|
7841
|
+
SELECT ?id ?contentIRI ?suffix ?size ?subject ?summary
|
|
7842
|
+
(SAMPLE(?fp) AS ?path)
|
|
7843
|
+
(GROUP_CONCAT(DISTINCT ?tag; SEPARATOR=";") AS ?tags)
|
|
7844
|
+
(GROUP_CONCAT(DISTINCT STR(?cat); SEPARATOR=";") AS ?categories)
|
|
7845
|
+
WHERE {
|
|
7846
|
+
VALUES ?contentIRI { ${e} }
|
|
7847
|
+
?contentIRI qcy:sizeBytes ?size ;
|
|
7848
|
+
qcy:hasFileLocation ?loc .
|
|
7849
|
+
?loc qcy:filePath ?fp ;
|
|
7850
|
+
qcy:suffix ?suffix .
|
|
7851
|
+
OPTIONAL { ?contentIRI qcy:hasContentCategory ?cat }
|
|
7852
|
+
OPTIONAL { ?contentIRI qcy:tag ?tag }
|
|
7853
|
+
OPTIONAL { ?loc qcy:remoteProviderId ?pid }
|
|
7854
|
+
|
|
7855
|
+
OPTIONAL { ?contentIRI qcy:subject ?lang_subj FILTER(LANG(?lang_subj) = "${o}") }
|
|
7856
|
+
OPTIONAL { ?contentIRI qcy:subject ?no_lang_subj }
|
|
7857
|
+
BIND(COALESCE(?lang_subj, ?no_lang_subj) AS ?subject)
|
|
7858
|
+
|
|
7859
|
+
OPTIONAL { ?contentIRI qcy:textSummary ?lang_summary FILTER(LANG(?lang_summary) = "${o}") }
|
|
7860
|
+
OPTIONAL { ?contentIRI qcy:textSummary ?no_lang_summary }
|
|
7861
|
+
BIND(COALESCE(?lang_summary, ?no_lang_summary) AS ?summary)
|
|
7862
|
+
|
|
7863
|
+
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?id)
|
|
7864
|
+
}
|
|
7865
|
+
GROUP BY ?id ?contentIRI ?suffix ?size ?subject ?summary`, s = await this._api.sparql(r, this._projectId), a = { ...this._documentInfoMap.get() }, n = {};
|
|
7866
|
+
return s.results.bindings.forEach((p) => {
|
|
7867
|
+
if (!p.id || !p.contentIRI) return;
|
|
7868
|
+
const c = p.id.value, h = {
|
|
7869
|
+
id: c,
|
|
7870
|
+
contentIRI: p.contentIRI.value,
|
|
7871
|
+
path: p.path?.value ?? "",
|
|
7872
|
+
suffix: p.suffix?.value ?? "",
|
|
7873
|
+
size: p.size ? parseInt(p.size.value, 10) : 0,
|
|
7874
|
+
tags: p.tags?.value?.split(";").filter(Boolean) ?? [],
|
|
7875
|
+
categories: p.categories?.value?.split(";").filter(Boolean) ?? [],
|
|
7876
|
+
subject: p.subject?.value,
|
|
7877
|
+
summary: p.summary?.value,
|
|
7878
|
+
providerId: p.pid?.value
|
|
7879
|
+
};
|
|
7880
|
+
a[c] = h, n[c] = h;
|
|
7881
|
+
}), this._documentInfoMap.set(a), n;
|
|
7882
|
+
}
|
|
7883
|
+
/** Executes a reduced document-info query (id/path/suffix/size only), merges
|
|
7884
|
+
* into `documentInfoMap`, and returns newly fetched entries. */
|
|
7885
|
+
async _fetchSimpleDocumentInfoBatch(t) {
|
|
7886
|
+
const e = t.map((n) => `r:${n}`).join(" "), o = `PREFIX qcy: <${y.qcy}>
|
|
7887
|
+
PREFIX r: <${this.baseURL}>
|
|
7888
|
+
SELECT ?id ?contentIRI ?suffix ?size (SAMPLE(?fp) AS ?path)
|
|
7889
|
+
WHERE {
|
|
7890
|
+
VALUES ?contentIRI { ${e} }
|
|
7891
|
+
?contentIRI qcy:sizeBytes ?size ;
|
|
7892
|
+
qcy:hasFileLocation ?loc .
|
|
7893
|
+
?loc qcy:filePath ?fp ;
|
|
7894
|
+
qcy:suffix ?suffix .
|
|
7895
|
+
BIND(REPLACE(STR(?contentIRI), "^.*/([^/]*)$", "$1") AS ?id)
|
|
7896
|
+
}
|
|
7897
|
+
GROUP BY ?id ?contentIRI ?suffix ?size`, r = await this._api.sparql(o, this._projectId, this._graphType), s = { ...this._documentInfoMap.get() }, a = {};
|
|
7898
|
+
return r.results.bindings.forEach((n) => {
|
|
7899
|
+
if (!n.id) return;
|
|
7900
|
+
const p = n.id.value, c = s[p], h = {
|
|
7901
|
+
id: p,
|
|
7902
|
+
contentIRI: n.contentIRI?.value ?? c?.contentIRI ?? p,
|
|
7903
|
+
path: n.path?.value ?? c?.path ?? p,
|
|
7904
|
+
suffix: n.suffix?.value ?? c?.suffix ?? "",
|
|
7905
|
+
size: n.size ? parseInt(n.size.value, 10) : c?.size ?? 0,
|
|
7906
|
+
tags: c?.tags ?? [],
|
|
7907
|
+
categories: c?.categories ?? [],
|
|
7908
|
+
subject: c?.subject,
|
|
7909
|
+
summary: c?.summary,
|
|
7910
|
+
providerId: c?.providerId
|
|
7911
|
+
};
|
|
7912
|
+
s[p] = h, a[p] = h;
|
|
7913
|
+
}), this._documentInfoMap.set(s), a;
|
|
7914
|
+
}
|
|
7915
|
+
async _fetchDocumentsBySuffix() {
|
|
7916
|
+
return this._runDocumentsBySuffixQuery(this._buildDocumentsBySuffixQuery());
|
|
7917
|
+
}
|
|
7918
|
+
_buildDocumentsBySuffixQuery() {
|
|
7919
|
+
return `PREFIX qcy: <${y.qcy}>
|
|
7920
|
+
SELECT ?ext (SUM(?size) AS ?totalSize) (COUNT(*) AS ?docCount)
|
|
7921
|
+
WHERE {
|
|
7922
|
+
{
|
|
7923
|
+
SELECT DISTINCT ?fc ?ext ?size
|
|
7924
|
+
WHERE {
|
|
7925
|
+
?fc a qcy:FileContent ;
|
|
7926
|
+
qcy:sizeBytes ?size ;
|
|
7927
|
+
qcy:hasFileLocation/qcy:suffix ?ext .
|
|
7928
|
+
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
7929
|
+
}
|
|
7930
|
+
}
|
|
7931
|
+
}
|
|
7932
|
+
GROUP BY ?ext
|
|
7933
|
+
ORDER BY DESC(?docCount)`;
|
|
7934
|
+
}
|
|
7935
|
+
async _runDocumentsBySuffixQuery(t) {
|
|
7936
|
+
const e = await this._api.sparql(t, this._projectId, this._graphType), o = {};
|
|
7937
|
+
return e.results.bindings.forEach((r) => {
|
|
7938
|
+
r.ext && (o[r.ext.value] = {
|
|
7939
|
+
size: r.totalSize ? parseInt(r.totalSize.value, 10) : 0,
|
|
7940
|
+
count: r.docCount ? parseInt(r.docCount.value, 10) : 0
|
|
7941
|
+
});
|
|
7942
|
+
}), o;
|
|
7943
|
+
}
|
|
7944
|
+
async _fetchDocumentsByContentCategory() {
|
|
7945
|
+
return this._runDocumentsByContentCategoryQuery(this._buildDocumentsByContentCategoryQuery());
|
|
7946
|
+
}
|
|
7947
|
+
_buildDocumentsByContentCategoryQuery() {
|
|
7948
|
+
return `PREFIX qcy: <${y.qcy}>
|
|
7949
|
+
SELECT ?cat (SUM(?size) AS ?totalSize) (COUNT(*) AS ?docCount)
|
|
7950
|
+
WHERE {
|
|
7951
|
+
{
|
|
7952
|
+
SELECT DISTINCT ?fc ?cat ?size
|
|
7953
|
+
WHERE {
|
|
7954
|
+
?fc a qcy:FileContent ;
|
|
7955
|
+
qcy:hasContentCategory ?cat ;
|
|
7956
|
+
qcy:sizeBytes ?size .
|
|
7957
|
+
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
7958
|
+
}
|
|
7959
|
+
}
|
|
7960
|
+
}
|
|
7961
|
+
GROUP BY ?cat
|
|
7962
|
+
ORDER BY DESC(?docCount)`;
|
|
7963
|
+
}
|
|
7964
|
+
async _runDocumentsByContentCategoryQuery(t) {
|
|
7965
|
+
const e = await this._api.sparql(t, this._projectId, this._graphType), o = {};
|
|
7966
|
+
return e.results.bindings.forEach((r) => {
|
|
7967
|
+
r.cat && (o[r.cat.value] = {
|
|
7968
|
+
size: r.totalSize ? parseInt(r.totalSize.value, 10) : 0,
|
|
7969
|
+
count: r.docCount ? parseInt(r.docCount.value, 10) : 0
|
|
7970
|
+
});
|
|
7971
|
+
}), o;
|
|
7972
|
+
}
|
|
7973
|
+
async _fetchDuplicateCount() {
|
|
7974
|
+
return this._runDuplicateCountQuery(this._buildDuplicateCountQuery());
|
|
7975
|
+
}
|
|
7976
|
+
_buildDuplicateCountQuery() {
|
|
7977
|
+
return `PREFIX qcy: <${y.qcy}>
|
|
7978
|
+
SELECT (COUNT(*) AS ?count)
|
|
7979
|
+
WHERE {
|
|
7980
|
+
SELECT ?fc
|
|
7981
|
+
WHERE {
|
|
7982
|
+
?fc a qcy:FileContent ;
|
|
7983
|
+
qcy:hasFileLocation ?fl .
|
|
7984
|
+
FILTER NOT EXISTS { ?x qcy:alternativeRepresentation ?fc }
|
|
7985
|
+
}
|
|
7986
|
+
GROUP BY ?fc
|
|
7987
|
+
HAVING (COUNT(?fl) > 1)
|
|
7988
|
+
}`;
|
|
7989
|
+
}
|
|
7990
|
+
async _runDuplicateCountQuery(t) {
|
|
7991
|
+
const o = (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings[0];
|
|
7992
|
+
return o?.count ? parseInt(o.count.value, 10) : 0;
|
|
7993
|
+
}
|
|
7994
|
+
}
|
|
7995
|
+
class hr {
|
|
7996
|
+
constructor(t, e, { language: o, queryCache: r, rdfBase: s = ut, graphType: a }) {
|
|
7997
|
+
this._api = t, this._projectId = e, this.schema = new lr(t, e, o, r, a), this.entities = new we(t, e, s, r, a), this.documents = new ct(t, e, o, s, r, a), this.availableContentCategories = this.schema.availableContentCategories, this.availableEntityCategories = this.schema.availableEntityCategories, this.availableEntityRelationships = this.schema.availableEntityRelationships, this.schemaReady = this.schema.ready, this.entityInfoMap = this.entities.entityInfoMap, this.entityGraph = this.entities.entityGraph, this.documentInfoMap = this.documents.documentInfoMap, this.projectDocumentsData = this.documents.projectDocumentsData, this.searchResults = this._searchResults.asReadonly(), this.documents.fetchOverview().catch((n) => console.error("[CueProjectView] fetchOverview failed:", n));
|
|
7998
|
+
}
|
|
7999
|
+
_api;
|
|
8000
|
+
_projectId;
|
|
8001
|
+
/** Direct access to the schema data class (available categories / relationships). */
|
|
8002
|
+
schema;
|
|
8003
|
+
/** Direct access to the entity data class. */
|
|
8004
|
+
entities;
|
|
8005
|
+
/** Direct access to the document data class. */
|
|
8006
|
+
documents;
|
|
8007
|
+
// ── Proxied signals ────────────────────────────────────────────────────────
|
|
8008
|
+
/** Available content category definitions for this project. Auto-fetched on init. */
|
|
8009
|
+
availableContentCategories;
|
|
8010
|
+
/** Available entity category definitions for this project. Auto-fetched on init. */
|
|
8011
|
+
availableEntityCategories;
|
|
8012
|
+
/** Available entity relationship types. Auto-fetched on init. */
|
|
8013
|
+
availableEntityRelationships;
|
|
8014
|
+
/**
|
|
8015
|
+
* Resolves when the initial schema load has completed. Await before reading
|
|
8016
|
+
* schema signal values imperatively.
|
|
8017
|
+
*/
|
|
8018
|
+
schemaReady;
|
|
8019
|
+
/** Merged per-entity detail map. Populated lazily via `requestEntityData()` etc. */
|
|
8020
|
+
entityInfoMap;
|
|
8021
|
+
/** Project-level entity co-occurrence graph. Fetched once on init. */
|
|
8022
|
+
entityGraph;
|
|
8023
|
+
/** Per-document info map. Populated lazily via `requestDocumentData()`. */
|
|
8024
|
+
documentInfoMap;
|
|
8025
|
+
/** Project document overview (counts by suffix and category). Fetched on init. */
|
|
8026
|
+
projectDocumentsData;
|
|
8027
|
+
// ── Search state ───────────────────────────────────────────────────────────
|
|
8028
|
+
_searchResults = new k(void 0);
|
|
8029
|
+
/** The result of the most recent `search()` call. `undefined` before first search. */
|
|
8030
|
+
searchResults;
|
|
8031
|
+
_destroyed = !1;
|
|
8032
|
+
// ── Entity methods ─────────────────────────────────────────────────────────
|
|
8033
|
+
/**
|
|
8034
|
+
* Lazily batch-fetch core data (label + categories) for the given entity UUIDs.
|
|
8035
|
+
* Already-fetched UUIDs are skipped. Populates `entityInfoMap`.
|
|
8036
|
+
*/
|
|
8037
|
+
requestEntityData(t, e = !1) {
|
|
8038
|
+
this._destroyed || this.entities.requestEntityData(t, e);
|
|
8039
|
+
}
|
|
8040
|
+
/**
|
|
8041
|
+
* Lazily fetch OSM location data for the given entity UUIDs.
|
|
8042
|
+
* Already-fetched UUIDs are skipped. Populates `entityInfoMap` geometry fields.
|
|
8043
|
+
*/
|
|
8044
|
+
async requestEntityLocations(t) {
|
|
8045
|
+
if (!this._destroyed)
|
|
8046
|
+
return this.entities.requestEntityLocations(t);
|
|
8047
|
+
}
|
|
8048
|
+
/**
|
|
8049
|
+
* Fetch incoming and outgoing relationships for a single entity IRI.
|
|
8050
|
+
* Result is stored in `entityInfoMap[uuid].relationshipData`.
|
|
8051
|
+
*/
|
|
8052
|
+
async fetchEntityRelationships(t) {
|
|
8053
|
+
if (this._destroyed) throw new Error("CueProjectView is destroyed");
|
|
8054
|
+
return this.entities.fetchEntityRelationships(t);
|
|
8055
|
+
}
|
|
8056
|
+
/**
|
|
8057
|
+
* Fetch UUIDs of documents that reference the given entity IRI.
|
|
8058
|
+
* Result is stored in `entityInfoMap[uuid].documentRefs`.
|
|
8059
|
+
*/
|
|
8060
|
+
async fetchEntityDocuments(t) {
|
|
8061
|
+
if (this._destroyed) throw new Error("CueProjectView is destroyed");
|
|
8062
|
+
return this.entities.fetchEntityDocuments(t);
|
|
8063
|
+
}
|
|
8064
|
+
/** Constructs the full RDF IRI for an entity UUID. */
|
|
8065
|
+
entityIri(t) {
|
|
8066
|
+
return this.entities.entityIri(t);
|
|
8067
|
+
}
|
|
8068
|
+
// ── Document methods ───────────────────────────────────────────────────────
|
|
8069
|
+
/**
|
|
8070
|
+
* Lazily batch-fetch document info for the given UUIDs.
|
|
8071
|
+
* Already-fetched UUIDs are skipped. Populates `documentInfoMap`.
|
|
8072
|
+
*/
|
|
8073
|
+
requestDocumentData(t) {
|
|
8074
|
+
this._destroyed || this.documents.requestDocumentData(t);
|
|
8075
|
+
}
|
|
8076
|
+
// ── Search ─────────────────────────────────────────────────────────────────
|
|
8077
|
+
/**
|
|
8078
|
+
* Run a natural-language search against the project.
|
|
8079
|
+
* The result is stored in `searchResults` and replaces any previous result.
|
|
8080
|
+
*/
|
|
8081
|
+
async search(t, e) {
|
|
8082
|
+
if (this._destroyed) return;
|
|
8083
|
+
const o = await this._api.search({
|
|
8084
|
+
term: t,
|
|
8085
|
+
projectId: this._projectId,
|
|
8086
|
+
categories: e?.categories
|
|
8087
|
+
});
|
|
8088
|
+
this._destroyed || this._searchResults.set(o);
|
|
8089
|
+
}
|
|
8090
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
8091
|
+
/**
|
|
8092
|
+
* Switch the active language for schema labels and document text fields.
|
|
8093
|
+
* Schema responses are cached per language (instant if previously loaded).
|
|
8094
|
+
* The document info map is cleared and lazily re-populated on next access.
|
|
8095
|
+
*/
|
|
8096
|
+
setLanguage(t) {
|
|
8097
|
+
this._destroyed || (this.schema.setLanguage(t), this.documents.setLanguage(t));
|
|
8098
|
+
}
|
|
8099
|
+
/**
|
|
8100
|
+
* Reset all entity and document state and re-fetch the project overview.
|
|
8101
|
+
* Prefer creating a fresh `CueProjectView` when switching projects.
|
|
8102
|
+
* Use `reset()` only when the same project's data needs to be invalidated.
|
|
8103
|
+
*/
|
|
8104
|
+
reset() {
|
|
8105
|
+
this._destroyed || (this.entities.reset(), this.documents.reset(), this._searchResults.set(void 0), this.documents.fetchOverview().catch((t) => console.error("[CueProjectView] fetchOverview failed after reset:", t)));
|
|
8106
|
+
}
|
|
8107
|
+
/**
|
|
8108
|
+
* Tear down this view instance. Clears all reactive state and blocks further
|
|
8109
|
+
* updates. Call from the Angular adapter's `ngOnDestroy` or equivalent.
|
|
8110
|
+
*/
|
|
8111
|
+
destroy() {
|
|
8112
|
+
this._destroyed = !0, this._searchResults.set(void 0);
|
|
8113
|
+
}
|
|
8114
|
+
}
|
|
8115
|
+
function Yt(i, t) {
|
|
8116
|
+
return new Promise((e) => {
|
|
8117
|
+
const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
8118
|
+
for (const m of i)
|
|
8119
|
+
o.has(m.contentUUID) || o.set(m.contentUUID, []), o.get(m.contentUUID)?.push(m), r.set(m.locationUUID, m);
|
|
8120
|
+
const s = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map();
|
|
8121
|
+
for (const m of t)
|
|
8122
|
+
s.has(m.contentUUID) || s.set(m.contentUUID, []), s.get(m.contentUUID)?.push(m), m.locationUUID && a.set(m.locationUUID, m);
|
|
8123
|
+
const n = [], p = [];
|
|
8124
|
+
for (const m of i)
|
|
8125
|
+
s.has(m.contentUUID) ? (s.get(m.contentUUID) || []).some((v) => v.locationUUID === m.locationUUID) || p.push(m) : n.push(m);
|
|
8126
|
+
const c = [], h = [];
|
|
8127
|
+
for (const m of t) {
|
|
8128
|
+
const x = o.get(m.contentUUID);
|
|
8129
|
+
x ? x.some((v) => v.locationUUID === m.locationUUID) || h.push(m) : c.push(m);
|
|
8130
|
+
}
|
|
8131
|
+
const d = i.length - n.length - p.length, g = i.length, w = g > 0 ? d / g : 1;
|
|
8132
|
+
let u = 0, f = 0;
|
|
8133
|
+
for (const m of i)
|
|
8134
|
+
f += m.size || 0, (s.get(m.contentUUID) || []).some((v) => v.locationUUID === m.locationUUID) && (u += m.size || 0);
|
|
8135
|
+
const E = f > 0 ? u / f : 1;
|
|
8136
|
+
e({
|
|
8137
|
+
localNotOnRemote: n,
|
|
8138
|
+
localNotOnRemotePathOnly: p,
|
|
8139
|
+
remoteNotOnLocal: c,
|
|
8140
|
+
remoteNotOnLocalPathOnly: h,
|
|
8141
|
+
syncCount: d,
|
|
8142
|
+
totalCount: g,
|
|
8143
|
+
syncSize: u,
|
|
8144
|
+
totalSize: f,
|
|
8145
|
+
synctPctSize: E,
|
|
8146
|
+
synctPctCount: w
|
|
8147
|
+
});
|
|
8148
|
+
});
|
|
8149
|
+
}
|
|
8078
8150
|
const { namedNode: dr, literal: Rr } = j;
|
|
8079
8151
|
dr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8080
8152
|
const { namedNode: Ar } = j, { namedNode: gr, literal: Pr } = j;
|
|
@@ -8087,10 +8159,10 @@ const { namedNode: mr, literal: Or } = j;
|
|
|
8087
8159
|
mr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8088
8160
|
const { namedNode: wr, literal: Dr } = j;
|
|
8089
8161
|
wr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8090
|
-
function
|
|
8162
|
+
function Zt(i, t, e, o, r, s, a, n = !1, p = !1) {
|
|
8091
8163
|
const c = ur(i), h = D(o), d = `${t}/${h}${c}`;
|
|
8092
|
-
a === void 0 && (a =
|
|
8093
|
-
const g =
|
|
8164
|
+
a === void 0 && (a = lt[c]?.mime ?? "application/octet-stream");
|
|
8165
|
+
const g = eo(i, r);
|
|
8094
8166
|
return {
|
|
8095
8167
|
name: i,
|
|
8096
8168
|
blob_name: d,
|
|
@@ -8116,7 +8188,7 @@ async function U() {
|
|
|
8116
8188
|
"fs/promises"
|
|
8117
8189
|
);
|
|
8118
8190
|
}
|
|
8119
|
-
async function
|
|
8191
|
+
async function Jt(i) {
|
|
8120
8192
|
if (typeof window < "u")
|
|
8121
8193
|
throw new Error(
|
|
8122
8194
|
`Cannot read file from path "${i}" in a browser environment. Provide file.data (Uint8Array) instead.`
|
|
@@ -8150,8 +8222,8 @@ async function fr() {
|
|
|
8150
8222
|
await a.default({ module_or_path: r }), q = a.scan;
|
|
8151
8223
|
}
|
|
8152
8224
|
}
|
|
8153
|
-
const yr = "qlever", $ = 1e3,
|
|
8154
|
-
async function
|
|
8225
|
+
const yr = "qlever", $ = 1e3, mt = "cue:pending:";
|
|
8226
|
+
async function wt(i) {
|
|
8155
8227
|
const { tmpdir: t } = await import(
|
|
8156
8228
|
/* webpackIgnore: true */
|
|
8157
8229
|
"os"
|
|
@@ -8161,33 +8233,33 @@ async function mt(i) {
|
|
|
8161
8233
|
);
|
|
8162
8234
|
return e(t(), `cue-sync-pending-${i}.json`);
|
|
8163
8235
|
}
|
|
8164
|
-
async function
|
|
8236
|
+
async function te(i) {
|
|
8165
8237
|
if (typeof window < "u") {
|
|
8166
|
-
const t = window.localStorage.getItem(`${
|
|
8238
|
+
const t = window.localStorage.getItem(`${mt}${i}`);
|
|
8167
8239
|
return t ? JSON.parse(t) : null;
|
|
8168
8240
|
}
|
|
8169
8241
|
try {
|
|
8170
|
-
const t = await (await U()).readFile(await
|
|
8242
|
+
const t = await (await U()).readFile(await wt(i), "utf-8");
|
|
8171
8243
|
return JSON.parse(t);
|
|
8172
8244
|
} catch {
|
|
8173
8245
|
return null;
|
|
8174
8246
|
}
|
|
8175
8247
|
}
|
|
8176
|
-
async function
|
|
8248
|
+
async function ee(i) {
|
|
8177
8249
|
const t = JSON.stringify(i);
|
|
8178
8250
|
if (typeof window < "u") {
|
|
8179
|
-
window.localStorage.setItem(`${
|
|
8251
|
+
window.localStorage.setItem(`${mt}${i.spaceId}`, t);
|
|
8180
8252
|
return;
|
|
8181
8253
|
}
|
|
8182
|
-
await (await U()).writeFile(await
|
|
8254
|
+
await (await U()).writeFile(await wt(i.spaceId), t, "utf-8");
|
|
8183
8255
|
}
|
|
8184
8256
|
async function br(i) {
|
|
8185
8257
|
if (typeof window < "u") {
|
|
8186
|
-
window.localStorage.removeItem(`${
|
|
8258
|
+
window.localStorage.removeItem(`${mt}${i}`);
|
|
8187
8259
|
return;
|
|
8188
8260
|
}
|
|
8189
8261
|
try {
|
|
8190
|
-
await (await U()).unlink(await
|
|
8262
|
+
await (await U()).unlink(await wt(i));
|
|
8191
8263
|
} catch {
|
|
8192
8264
|
}
|
|
8193
8265
|
}
|
|
@@ -8247,7 +8319,7 @@ class vr {
|
|
|
8247
8319
|
*/
|
|
8248
8320
|
async flushPendingMetadata(t, e, o) {
|
|
8249
8321
|
this._legacy = o ?? !1;
|
|
8250
|
-
const r = await
|
|
8322
|
+
const r = await te(t);
|
|
8251
8323
|
if (!(!r || r.items.length === 0)) {
|
|
8252
8324
|
console.info(`Trying to upload metadata (${r.items.length} item(s))...`), e && console.info(`Flushing ${r.items.length} pending file location(s) from previous sync ⏳`);
|
|
8253
8325
|
try {
|
|
@@ -8270,12 +8342,12 @@ class vr {
|
|
|
8270
8342
|
this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance")),
|
|
8271
8343
|
this._fetchUnitCreditMap(s),
|
|
8272
8344
|
this._fetchTierNames()
|
|
8273
|
-
]), f = (await
|
|
8345
|
+
]), f = (await Yt(t, h)).localNotOnRemote ?? [], E = f.length > 0 ? await this.scanCost(f) : [];
|
|
8274
8346
|
let m = 0, x = 0;
|
|
8275
8347
|
for (const v of E) {
|
|
8276
8348
|
m += v.units;
|
|
8277
|
-
const
|
|
8278
|
-
s &&
|
|
8349
|
+
const b = g[c], C = b?.[v.ext] ?? 1;
|
|
8350
|
+
s && b && !(v.ext in b) && console.info(` Unknown format: .${v.ext} (using default rate of 1 credit/unit)`);
|
|
8279
8351
|
const P = v.units * C;
|
|
8280
8352
|
x += P, v.credits = Math.round(P);
|
|
8281
8353
|
}
|
|
@@ -8302,54 +8374,54 @@ class vr {
|
|
|
8302
8374
|
const [d, g] = await Promise.all([
|
|
8303
8375
|
this._listRemoteFiles(h, o, r, a),
|
|
8304
8376
|
this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance"))
|
|
8305
|
-
]), { unitsAvailable: w } = g, u = await
|
|
8377
|
+
]), { unitsAvailable: w } = g, u = await Yt(t, d);
|
|
8306
8378
|
a && (console.info(`Total local files: ${t.length}`), console.info(`Total remote files: ${d.length}`), console.info(
|
|
8307
8379
|
`Total files to sync: ${(u.localNotOnRemote?.length ?? 0) + u.localNotOnRemotePathOnly.length}`
|
|
8308
8380
|
));
|
|
8309
8381
|
let f = u.syncCount, E = u.syncSize, m = 0, x = !1;
|
|
8310
8382
|
const I = u.localNotOnRemote ?? [];
|
|
8311
8383
|
if (I.length > 0) {
|
|
8312
|
-
const C = (await this.scanCost(I)).reduce((P,
|
|
8384
|
+
const C = (await this.scanCost(I)).reduce((P, ye) => P + ye.units, 0);
|
|
8313
8385
|
if (C > w)
|
|
8314
8386
|
throw new Error(
|
|
8315
8387
|
`Insufficient units: ${C} units required but only ${w} available.`
|
|
8316
8388
|
);
|
|
8317
8389
|
}
|
|
8318
8390
|
await this._initPendingBatch(o, a), a && I.length && console.info("Syncing missing files ⏳");
|
|
8319
|
-
for (const
|
|
8391
|
+
for (const b of I)
|
|
8320
8392
|
try {
|
|
8321
|
-
const C =
|
|
8322
|
-
|
|
8393
|
+
const C = Zt(
|
|
8394
|
+
b.relativePath,
|
|
8323
8395
|
o,
|
|
8324
8396
|
s,
|
|
8325
|
-
|
|
8397
|
+
b.md5,
|
|
8326
8398
|
r
|
|
8327
8399
|
);
|
|
8328
|
-
if (!C.blob_name) throw new Error(`blob_name missing for ${
|
|
8329
|
-
const P =
|
|
8400
|
+
if (!C.blob_name) throw new Error(`blob_name missing for ${b.relativePath}`);
|
|
8401
|
+
const P = b.data ?? new Uint8Array(await Jt(b.fullPath));
|
|
8330
8402
|
await this._blob.uploadRaw(
|
|
8331
8403
|
C.blob_name,
|
|
8332
8404
|
P,
|
|
8333
8405
|
C
|
|
8334
8406
|
), await this._queueFileLocation({
|
|
8335
|
-
relativePath:
|
|
8336
|
-
md5:
|
|
8337
|
-
size:
|
|
8407
|
+
relativePath: b.relativePath,
|
|
8408
|
+
md5: b.md5,
|
|
8409
|
+
size: b.size,
|
|
8338
8410
|
providerId: r,
|
|
8339
8411
|
fileContentExists: !1
|
|
8340
|
-
}), x = !0, f += 1, E +=
|
|
8412
|
+
}), x = !0, f += 1, E += b.size || 0, this._logProgress(f, u.totalCount, E, u.totalSize, n);
|
|
8341
8413
|
} catch (C) {
|
|
8342
|
-
m += 1, console.error(`[CueSyncApi] Failed to upload file: ${
|
|
8414
|
+
m += 1, console.error(`[CueSyncApi] Failed to upload file: ${b.fullPath}`), a && console.error("[CueSyncApi] Upload error details:", C);
|
|
8343
8415
|
}
|
|
8344
8416
|
a && u.localNotOnRemotePathOnly.length && console.info(`Syncing missing file locations (on provider "${r}") ⏳`);
|
|
8345
|
-
for (const
|
|
8417
|
+
for (const b of u.localNotOnRemotePathOnly)
|
|
8346
8418
|
await this._queueFileLocation({
|
|
8347
|
-
relativePath:
|
|
8348
|
-
md5:
|
|
8349
|
-
size:
|
|
8419
|
+
relativePath: b.relativePath,
|
|
8420
|
+
md5: b.md5,
|
|
8421
|
+
size: b.size,
|
|
8350
8422
|
providerId: r,
|
|
8351
8423
|
fileContentExists: !0
|
|
8352
|
-
}), x = !0, f += 1, E +=
|
|
8424
|
+
}), x = !0, f += 1, E += b.size || 0, this._logProgress(f, u.totalCount, E, u.totalSize, n);
|
|
8353
8425
|
await this._drainPending(a), this._stopFlushTimer();
|
|
8354
8426
|
const v = await (this._api?.getConsumption(o) ?? Promise.resolve({ creditsAvailable: 0 }));
|
|
8355
8427
|
return {
|
|
@@ -8365,7 +8437,7 @@ class vr {
|
|
|
8365
8437
|
async _getOrCreateGraph(t, e) {
|
|
8366
8438
|
const o = this._graphMap.get(t);
|
|
8367
8439
|
if (o) return o;
|
|
8368
|
-
const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ?? yr, a = s === "qlever" ? `${this._gatewayUrl}${
|
|
8440
|
+
const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ?? yr, a = s === "qlever" ? `${this._gatewayUrl}${pe}` : `${this._gatewayUrl}${ne}`, n = s === "qlever" ? `${this._gatewayUrl}${go}` : `${this._gatewayUrl}${co}`, p = new Je({
|
|
8369
8441
|
graphType: s,
|
|
8370
8442
|
queryEndpoint: a,
|
|
8371
8443
|
updateEndpoint: n,
|
|
@@ -8405,7 +8477,7 @@ class vr {
|
|
|
8405
8477
|
return p;
|
|
8406
8478
|
}
|
|
8407
8479
|
async _getGraphFiles(t, e) {
|
|
8408
|
-
const o = `PREFIX qcy: <${
|
|
8480
|
+
const o = `PREFIX qcy: <${y.qcy}>
|
|
8409
8481
|
SELECT ?fc ?loc ?created ?fp ?size
|
|
8410
8482
|
WHERE {
|
|
8411
8483
|
?fc a qcy:FileContent ;
|
|
@@ -8431,7 +8503,7 @@ WHERE {
|
|
|
8431
8503
|
}
|
|
8432
8504
|
async _initPendingBatch(t, e) {
|
|
8433
8505
|
this._flushTimer !== null && (clearInterval(this._flushTimer), this._flushTimer = null), this._pendingSpaceId = t, this._pendingItems = [];
|
|
8434
|
-
const o = await
|
|
8506
|
+
const o = await te(t);
|
|
8435
8507
|
if (o && o.items.length > 0) {
|
|
8436
8508
|
console.info(`Trying to upload metadata from interrupted sync (${o.items.length} item(s))...`), e && console.info(`Flushing ${o.items.length} pending file location(s) from previous sync ⏳`);
|
|
8437
8509
|
try {
|
|
@@ -8452,7 +8524,7 @@ WHERE {
|
|
|
8452
8524
|
typeof r == "object" && typeof r.unref == "function" && r.unref(), this._flushTimer = r;
|
|
8453
8525
|
}
|
|
8454
8526
|
async _queueFileLocation(t) {
|
|
8455
|
-
this._pendingItems.push(t), this._pendingSpaceId && await
|
|
8527
|
+
this._pendingItems.push(t), this._pendingSpaceId && await ee({ spaceId: this._pendingSpaceId, items: this._pendingItems });
|
|
8456
8528
|
}
|
|
8457
8529
|
/**
|
|
8458
8530
|
* Flush all queued file-location items to the commands API in a single batch.
|
|
@@ -8474,11 +8546,11 @@ WHERE {
|
|
|
8474
8546
|
o && console.info(`Wrote ${r.length} file location(s) to commands API ✅`);
|
|
8475
8547
|
} catch (s) {
|
|
8476
8548
|
const a = [...r, ...this._pendingItems];
|
|
8477
|
-
throw this._pendingItems = a, await
|
|
8549
|
+
throw this._pendingItems = a, await ee({ spaceId: e, items: a }), s;
|
|
8478
8550
|
}
|
|
8479
8551
|
}
|
|
8480
8552
|
async _postFssBatch(t, e) {
|
|
8481
|
-
const o = this._legacy ? `${this._gatewayUrl}${
|
|
8553
|
+
const o = this._legacy ? `${this._gatewayUrl}${Lt}?blob=true` : `${this._gatewayUrl}${Lt}`;
|
|
8482
8554
|
let r;
|
|
8483
8555
|
try {
|
|
8484
8556
|
r = await this._auth.authenticatedFetch(o, {
|
|
@@ -8515,7 +8587,7 @@ WHERE {
|
|
|
8515
8587
|
s.map(async (p) => ({
|
|
8516
8588
|
originalPath: p.relativePath,
|
|
8517
8589
|
// Use pre-loaded data if available (browser), otherwise read from disk (Node.js).
|
|
8518
|
-
data: p.data ?? new Uint8Array(await
|
|
8590
|
+
data: p.data ?? new Uint8Array(await Jt(p.fullPath))
|
|
8519
8591
|
}))
|
|
8520
8592
|
), n = q(a);
|
|
8521
8593
|
for (const p of n) {
|
|
@@ -8575,7 +8647,7 @@ WHERE {
|
|
|
8575
8647
|
const { spaceId: o, providerId: r, userId: s, signal: a, onProgress: n } = e;
|
|
8576
8648
|
if (!t.data)
|
|
8577
8649
|
throw new Error("syncBrowserFile requires file.data (Uint8Array). Read the file with File.arrayBuffer() first.");
|
|
8578
|
-
const p =
|
|
8650
|
+
const p = Zt(t.relativePath, o, s, t.md5, r);
|
|
8579
8651
|
if (!p.blob_name) throw new Error(`blob_name missing for ${t.relativePath}`);
|
|
8580
8652
|
await this._blob.uploadRaw(
|
|
8581
8653
|
p.blob_name,
|
|
@@ -8619,7 +8691,7 @@ WHERE {
|
|
|
8619
8691
|
s({ percent: a, syncCount: t, totalCount: e, syncSize: o, totalSize: r });
|
|
8620
8692
|
}
|
|
8621
8693
|
}
|
|
8622
|
-
const
|
|
8694
|
+
const oe = {
|
|
8623
8695
|
production: {
|
|
8624
8696
|
gatewayUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app",
|
|
8625
8697
|
tokenUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app/token",
|
|
@@ -8639,7 +8711,7 @@ const ee = {
|
|
|
8639
8711
|
firestoreEmulatorPort: 8080
|
|
8640
8712
|
}
|
|
8641
8713
|
};
|
|
8642
|
-
class
|
|
8714
|
+
class fe {
|
|
8643
8715
|
auth;
|
|
8644
8716
|
api;
|
|
8645
8717
|
projects;
|
|
@@ -8666,7 +8738,7 @@ class we {
|
|
|
8666
8738
|
* ```
|
|
8667
8739
|
*/
|
|
8668
8740
|
get gis() {
|
|
8669
|
-
return this._gis || (this._gis = new
|
|
8741
|
+
return this._gis || (this._gis = new ir(
|
|
8670
8742
|
() => this.api.getAuthHeaders(),
|
|
8671
8743
|
this._endpoints.gatewayUrl
|
|
8672
8744
|
)), this._gis;
|
|
@@ -8675,18 +8747,18 @@ class we {
|
|
|
8675
8747
|
!t.apiKey && !t.appId && !t.measurementId && console.warn(
|
|
8676
8748
|
"Using default SDK app settings. Contact QAECY for your own configuration for any production code."
|
|
8677
8749
|
);
|
|
8678
|
-
const o = t.apiKey ??
|
|
8679
|
-
this._endpoints = { ...
|
|
8750
|
+
const o = t.apiKey ?? Z.apiKey, r = t.appId ?? Z.appId, s = t.measurementId ?? Z.measurementId, a = t.environment ?? "production";
|
|
8751
|
+
this._endpoints = { ...oe[a], ...t.endpoints }, this._isEmulator = a === "emulator", this._app = be().find((g) => g.name === "[DEFAULT]") ?? ve({
|
|
8680
8752
|
apiKey: o,
|
|
8681
8753
|
appId: r,
|
|
8682
8754
|
measurementId: s,
|
|
8683
|
-
authDomain: `${
|
|
8684
|
-
projectId:
|
|
8685
|
-
messagingSenderId:
|
|
8686
|
-
}), this.auth = new
|
|
8687
|
-
const n = T(this._app,
|
|
8688
|
-
this._isEmulator && (
|
|
8689
|
-
const d = new
|
|
8755
|
+
authDomain: `${xt}.firebaseapp.com`,
|
|
8756
|
+
projectId: xt,
|
|
8757
|
+
messagingSenderId: oo
|
|
8758
|
+
}), this.auth = new Ut(this._app, this._isEmulator, this._endpoints), this.projects = new Ht(this.auth, this._app, this._isEmulator, this._endpoints), this._storageRaw = T(this._app, Tt), this._storageProcessed = T(this._app, St);
|
|
8759
|
+
const n = T(this._app, At), p = T(this._app, Rt), c = T(this._app, Ct), h = T(this._app, Pt);
|
|
8760
|
+
this._isEmulator && (Q(this._storageRaw, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), Q(this._storageProcessed, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort)), this.api = this._buildApi(this.projects);
|
|
8761
|
+
const d = new kt({
|
|
8690
8762
|
storageRaw: this._storageRaw,
|
|
8691
8763
|
storageProcessed: this._storageProcessed,
|
|
8692
8764
|
storagePublic: n,
|
|
@@ -8694,12 +8766,12 @@ class we {
|
|
|
8694
8766
|
storageChatSessions: c,
|
|
8695
8767
|
storagePersistence: h
|
|
8696
8768
|
});
|
|
8697
|
-
this.storage = new
|
|
8769
|
+
this.storage = new Mt(d), this.profile = new Wt(
|
|
8698
8770
|
this.auth,
|
|
8699
8771
|
this._app,
|
|
8700
8772
|
this._isEmulator,
|
|
8701
8773
|
this._endpoints.gatewayUrl
|
|
8702
|
-
), this.privileges = new
|
|
8774
|
+
), this.privileges = new Qt(this.auth.isSuperAdmin), this._isEmulator && Q(h, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), this.cache = new Xt(h);
|
|
8703
8775
|
}
|
|
8704
8776
|
/**
|
|
8705
8777
|
* Create a `Cue` instance from an already-initialized Firebase app.
|
|
@@ -8718,16 +8790,16 @@ class we {
|
|
|
8718
8790
|
* });
|
|
8719
8791
|
*/
|
|
8720
8792
|
static fromApp(t, e = {}) {
|
|
8721
|
-
const o = e.environment ?? "production", r = { ...
|
|
8793
|
+
const o = e.environment ?? "production", r = { ...oe[o], ...e.endpoints }, s = new Ut(t, !1, r), a = new Ht(s, t, !1, r), n = T(t, Tt), p = T(t, St), c = T(t, At), h = T(t, Rt), d = T(t, Ct), g = T(t, Pt), w = new kt({
|
|
8722
8794
|
storageRaw: n,
|
|
8723
8795
|
storageProcessed: p,
|
|
8724
8796
|
storagePublic: c,
|
|
8725
8797
|
storageLogs: h,
|
|
8726
8798
|
storageChatSessions: d,
|
|
8727
8799
|
storagePersistence: g
|
|
8728
|
-
}), u = new vr(s, a, w, r.gatewayUrl), f = new
|
|
8800
|
+
}), u = new vr(s, a, w, r.gatewayUrl), f = new zt(s, r.gatewayUrl, a, u);
|
|
8729
8801
|
u._bindApi(f);
|
|
8730
|
-
const E = new
|
|
8802
|
+
const E = new Wt(s, t, !1, r.gatewayUrl), m = Object.create(fe.prototype), x = new Qt(s.isSuperAdmin), I = new Xt(g), v = new Mt(w);
|
|
8731
8803
|
return Object.assign(m, {
|
|
8732
8804
|
_app: t,
|
|
8733
8805
|
_endpoints: r,
|
|
@@ -8745,7 +8817,7 @@ class we {
|
|
|
8745
8817
|
}
|
|
8746
8818
|
/** Override in subclasses to provide a custom CueApi (e.g. with sync). */
|
|
8747
8819
|
_buildApi(t) {
|
|
8748
|
-
return new
|
|
8820
|
+
return new zt(this.auth, this._endpoints.gatewayUrl, t);
|
|
8749
8821
|
}
|
|
8750
8822
|
/** Convenience: get the current user's Firebase ID token */
|
|
8751
8823
|
getToken(t = !1) {
|
|
@@ -8770,7 +8842,7 @@ class we {
|
|
|
8770
8842
|
get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
|
|
8771
8843
|
set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
|
|
8772
8844
|
};
|
|
8773
|
-
return new
|
|
8845
|
+
return new hr(this.api, t, { ...e, queryCache: o });
|
|
8774
8846
|
}
|
|
8775
8847
|
/**
|
|
8776
8848
|
* Creates a `CueProjectEntities` instance for the given project, with the
|
|
@@ -8794,7 +8866,7 @@ class we {
|
|
|
8794
8866
|
get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
|
|
8795
8867
|
set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
|
|
8796
8868
|
};
|
|
8797
|
-
return new
|
|
8869
|
+
return new we(
|
|
8798
8870
|
this.api,
|
|
8799
8871
|
t,
|
|
8800
8872
|
e?.rdfBase,
|
|
@@ -8824,7 +8896,7 @@ class we {
|
|
|
8824
8896
|
const a = {
|
|
8825
8897
|
get: (p) => this.cache.getQueryCache(t, p).then((c) => c?.results),
|
|
8826
8898
|
set: (p, c) => this.cache.setQueryCache(t, p, { query: p, results: c })
|
|
8827
|
-
}, n = new
|
|
8899
|
+
}, n = new ct(
|
|
8828
8900
|
this.api,
|
|
8829
8901
|
t,
|
|
8830
8902
|
this.api.language,
|
|
@@ -8838,7 +8910,7 @@ class we {
|
|
|
8838
8910
|
get: (s) => this.cache.getQueryCache(t, s).then((a) => a?.results),
|
|
8839
8911
|
set: (s, a) => this.cache.setQueryCache(t, s, { query: s, results: a })
|
|
8840
8912
|
};
|
|
8841
|
-
return new
|
|
8913
|
+
return new ct(
|
|
8842
8914
|
this.api,
|
|
8843
8915
|
t,
|
|
8844
8916
|
e?.language ?? this.api.language,
|
|
@@ -8849,30 +8921,30 @@ class we {
|
|
|
8849
8921
|
}
|
|
8850
8922
|
}
|
|
8851
8923
|
export {
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8924
|
+
Ct as B,
|
|
8925
|
+
fe as C,
|
|
8926
|
+
Kt as R,
|
|
8927
|
+
zt as a,
|
|
8928
|
+
Ut as b,
|
|
8929
|
+
Xt as c,
|
|
8930
|
+
bo as d,
|
|
8931
|
+
ir as e,
|
|
8932
|
+
Qt as f,
|
|
8933
|
+
Wt as g,
|
|
8934
|
+
ct as h,
|
|
8935
|
+
we as i,
|
|
8936
|
+
lr as j,
|
|
8937
|
+
hr as k,
|
|
8938
|
+
Ht as l,
|
|
8867
8939
|
k as m,
|
|
8868
|
-
|
|
8940
|
+
Mt as n,
|
|
8869
8941
|
vr as o,
|
|
8870
|
-
|
|
8942
|
+
fo as p,
|
|
8871
8943
|
Lr as q,
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8944
|
+
dt as r,
|
|
8945
|
+
gt as s,
|
|
8946
|
+
Rt as t,
|
|
8947
|
+
Pt as u,
|
|
8948
|
+
At as v,
|
|
8949
|
+
kt as w
|
|
8878
8950
|
};
|