@archont561/qgis-sdk-bridge 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,163 +1,31 @@
1
- // src/index.ts
2
- var MAX_SAFE_INTEGER = 9007199254740991;
3
- var MIN_SAFE_INTEGER = -9007199254740991;
4
- var PLUGIN_DESCRIPTION_SCHEMA_VERSION = 1;
5
- function isSafeJsonInteger(value) {
6
- return typeof value === "number" && Number.isSafeInteger(value);
7
- }
8
-
9
- class QgisSdkError extends Error {
10
- code;
11
- constructor(message, code = "sdk_error") {
12
- super(message);
13
- this.name = new.target.name;
14
- this.code = code;
15
- }
16
- }
17
-
18
- class QgisSdkScopeClosedError extends QgisSdkError {
19
- constructor() {
20
- super("This resource scope has been disposed", "scope_closed");
21
- }
22
- }
23
-
24
- class QgisSdkUnsupportedCapabilityError extends QgisSdkError {
25
- capability;
26
- constructor(capability) {
27
- super(`Capability ${JSON.stringify(capability)} is unavailable in this runtime`, "unsupported_capability");
28
- this.capability = capability;
29
- }
30
- }
31
-
32
- class QgisSdkDeclarationError extends QgisSdkError {
33
- constructor(message) {
34
- super(message, "invalid_declaration");
35
- }
36
- }
37
-
38
- class QgisSdkValidationIssue {
39
- path;
40
- code;
41
- constructor(path, code) {
42
- this.path = Object.freeze([...path]);
43
- this.code = code;
44
- }
45
- toJSON() {
46
- return {
47
- path: [...this.path],
48
- code: this.code
49
- };
50
- }
51
- }
52
-
53
- class QgisSdkContractValidationError extends QgisSdkError {
54
- direction;
55
- issues;
56
- constructor(direction, issues) {
57
- const prefix = direction === "request" ? "Request" : "Result";
58
- super(`${prefix} contract validation failed`, "contract_validation_failed");
59
- this.direction = direction;
60
- this.issues = Object.freeze([...issues]);
61
- }
62
- toJSON() {
63
- return {
64
- code: this.code,
65
- direction: this.direction,
66
- issues: this.issues.map((issue) => issue.toJSON())
67
- };
68
- }
69
- }
70
- var DECLARATION_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
71
- var PYTHON_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
72
- function isPlainRecord(value) {
73
- return typeof value === "object" && value !== null && !Array.isArray(value);
74
- }
75
- function validateDeclarationId(value, label) {
76
- if (typeof value !== "string" || !DECLARATION_ID_PATTERN.test(value)) {
77
- throw new QgisSdkDeclarationError(`Invalid ${label} id: expected [a-zA-Z][a-zA-Z0-9_.-]*`);
78
- }
79
- return value;
80
- }
81
- function validateNonBlankTitle(value, id) {
82
- if (typeof value !== "string" || value.trim().length === 0) {
83
- throw new QgisSdkDeclarationError(`${id}: title must be a nonempty string`);
84
- }
85
- return value;
86
- }
87
- function parseActionDescription(raw) {
88
- if (!isPlainRecord(raw)) {
89
- throw new QgisSdkDeclarationError("Action description must be an object");
90
- }
91
- const id = validateDeclarationId(raw.id, "action");
92
- const title = validateNonBlankTitle(raw.title, id);
93
- if (typeof raw.handler !== "string" || !PYTHON_IDENTIFIER_PATTERN.test(raw.handler)) {
94
- throw new QgisSdkDeclarationError(`${id}: handler must be a valid Python identifier`);
95
- }
96
- if (!isPlainRecord(raw.request)) {
97
- throw new QgisSdkDeclarationError(`${id}: request schema must be an object`);
98
- }
99
- if (!isPlainRecord(raw.result)) {
100
- throw new QgisSdkDeclarationError(`${id}: result schema must be an object`);
101
- }
102
- return Object.freeze({
103
- id,
104
- title,
105
- handler: raw.handler,
106
- request: Object.freeze({ ...raw.request }),
107
- result: Object.freeze({ ...raw.result })
108
- });
109
- }
110
- function parsePluginDescription(input) {
111
- let parsed = input;
112
- if (typeof input === "string") {
113
- try {
114
- parsed = JSON.parse(input);
115
- } catch {
116
- throw new QgisSdkDeclarationError("Plugin description is not valid JSON");
117
- }
118
- }
119
- if (!isPlainRecord(parsed)) {
120
- throw new QgisSdkDeclarationError("Plugin description must be an object");
121
- }
122
- if (parsed.schema_version !== PLUGIN_DESCRIPTION_SCHEMA_VERSION) {
123
- throw new QgisSdkDeclarationError(`Unsupported plugin description schema_version: ${String(parsed.schema_version)}`);
124
- }
125
- const id = validateDeclarationId(parsed.id, "plugin");
126
- const title = validateNonBlankTitle(parsed.title, id);
127
- if (!Array.isArray(parsed.actions)) {
128
- throw new QgisSdkDeclarationError(`${id}: actions must be an array`);
129
- }
130
- const seenIds = new Set;
131
- const actions = [];
132
- for (const item of parsed.actions) {
133
- const action = parseActionDescription(item);
134
- if (seenIds.has(action.id)) {
135
- throw new QgisSdkDeclarationError(`${id}: duplicate action id ${action.id}`);
136
- }
137
- seenIds.add(action.id);
138
- actions.push(action);
139
- }
140
- actions.sort((left, right) => left.id < right.id ? -1 : 1);
141
- return Object.freeze({
142
- schema_version: PLUGIN_DESCRIPTION_SCHEMA_VERSION,
143
- id,
144
- title,
145
- actions: Object.freeze(actions)
146
- });
147
- }
1
+ import {
2
+ MAX_SAFE_INTEGER2,
3
+ MIN_SAFE_INTEGER2,
4
+ PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
5
+ isSafeJsonInteger2,
6
+ QgisSdkError2,
7
+ QgisSdkScopeClosedError2,
8
+ QgisSdkUnsupportedCapabilityError2,
9
+ QgisSdkDeclarationError2,
10
+ QgisSdkValidationIssue2,
11
+ QgisSdkContractValidationError2,
12
+ isPlainRecord2,
13
+ parsePluginDescription2
14
+ } from "./shared/chunk-0fknax6w.js";
148
15
  export {
149
- MAX_SAFE_INTEGER,
150
- MIN_SAFE_INTEGER,
151
- PLUGIN_DESCRIPTION_SCHEMA_VERSION,
152
- QgisSdkContractValidationError,
153
- QgisSdkDeclarationError,
154
- QgisSdkError,
155
- QgisSdkScopeClosedError,
156
- QgisSdkUnsupportedCapabilityError,
157
- QgisSdkValidationIssue,
158
- isSafeJsonInteger,
159
- parsePluginDescription
16
+ MAX_SAFE_INTEGER2 as MAX_SAFE_INTEGER,
17
+ MIN_SAFE_INTEGER2 as MIN_SAFE_INTEGER,
18
+ PLUGIN_DESCRIPTION_SCHEMA_VERSION2 as PLUGIN_DESCRIPTION_SCHEMA_VERSION,
19
+ QgisSdkContractValidationError2 as QgisSdkContractValidationError,
20
+ QgisSdkDeclarationError2 as QgisSdkDeclarationError,
21
+ QgisSdkError2 as QgisSdkError,
22
+ QgisSdkScopeClosedError2 as QgisSdkScopeClosedError,
23
+ QgisSdkUnsupportedCapabilityError2 as QgisSdkUnsupportedCapabilityError,
24
+ QgisSdkValidationIssue2 as QgisSdkValidationIssue,
25
+ isPlainRecord2 as isPlainRecord,
26
+ isSafeJsonInteger2 as isSafeJsonInteger,
27
+ parsePluginDescription2 as parsePluginDescription
160
28
  };
161
29
 
162
- //# debugId=3494C4156313BA2364756E2164756E21
163
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogUHVibGljIDAuMS4wIGNvbnRyYWN0LCB3aXJlLWxpbWl0LCBhbmQgZXJyb3IgcHJpbWl0aXZlcyBmb3IgdGhlIFFHSVMgU0RLIGJyaWRnZS5cbiAqXG4gKiBNaXJyb3JzIHRoZSBRR0lTLWZyZWUgYHFnaXNfc2RrLm1vZGVsc2AgYW5kIGBxZ2lzX3Nkay5kZWNsYXJhdGlvbnNgXG4gKiAoYHNjaGVtYV92ZXJzaW9uID0gMWApIGNvbnRyYWN0cyB3aXRob3V0IGltcG9ydGluZyBicm93c2VyIG9yIFF0IGdsb2JhbHMuXG4gKi9cblxuZXhwb3J0IGNvbnN0IE1BWF9TQUZFX0lOVEVHRVI6IG51bWJlciA9IDlfMDA3XzE5OV8yNTRfNzQwXzk5MTtcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSOiBudW1iZXIgPSAtOV8wMDdfMTk5XzI1NF83NDBfOTkxO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTjogMSA9IDE7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25EaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdHJlYWRvbmx5IHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHJlYWRvbmx5IGNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJpYWxpemVkQ29udHJhY3RWYWxpZGF0aW9uRXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgcmVzdWx0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBzY2hlbWFfdmVyc2lvbjogMTtcblx0cmVhZG9ubHkgaWQ6IHN0cmluZztcblx0cmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblx0cmVhZG9ubHkgYWN0aW9uczogcmVhZG9ubHkgQWN0aW9uRGVzY3JpcHRpb25bXTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciBgdmFsdWVgIGlzIGEgZmluaXRlIGludGVnZXIgd2l0aGluIHRoZSBKYXZhU2NyaXB0LXNhZmUgd2lyZSByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2FmZUpzb25JbnRlZ2VyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVtYmVyIHtcblx0cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSk7XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZXhwZWN0ZWQgU0RLIGVycm9ycyBhY3Jvc3MgdGhlIGJyaWRnZSBib3VuZGFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtFcnJvciBleHRlbmRzIEVycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGNvZGU6IHN0cmluZztcblxuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb2RlOiBzdHJpbmcgPSBcInNka19lcnJvclwiKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5uYW1lID0gbmV3LnRhcmdldC5uYW1lO1xuXHRcdHRoaXMuY29kZSA9IGNvZGU7XG5cdH1cbn1cblxuLyoqXG4gKiBBbiBvcGVyYXRpb24gYXR0ZW1wdGVkIHRvIHVzZSBhbiBhbHJlYWR5IGRpc3Bvc2VkIG93bmVyIHNjb3BlLlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka1Njb3BlQ2xvc2VkRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoXCJUaGlzIHJlc291cmNlIHNjb3BlIGhhcyBiZWVuIGRpc3Bvc2VkXCIsIFwic2NvcGVfY2xvc2VkXCIpO1xuXHR9XG59XG5cbi8qKlxuICogVGhlIHNlbGVjdGVkIHJ1bnRpbWUgZG9lcyBub3Qgb2ZmZXIgYW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgY2FwYWJpbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtVbnN1cHBvcnRlZENhcGFiaWxpdHlFcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyByZWFkb25seSBjYXBhYmlsaXR5OiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKGNhcGFiaWxpdHk6IHN0cmluZykge1xuXHRcdHN1cGVyKFxuXHRcdFx0YENhcGFiaWxpdHkgJHtKU09OLnN0cmluZ2lmeShjYXBhYmlsaXR5KX0gaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBydW50aW1lYCxcblx0XHRcdFwidW5zdXBwb3J0ZWRfY2FwYWJpbGl0eVwiLFxuXHRcdCk7XG5cdFx0dGhpcy5jYXBhYmlsaXR5ID0gY2FwYWJpbGl0eTtcblx0fVxufVxuXG4vKipcbiAqIEEgZGVjbGFyYXRpb24gY2Fubm90IGJlIHJlcHJlc2VudGVkIG9yIHBhcnNlZCBpbiB0aGUgdmVyc2lvbmVkIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJpbnZhbGlkX2RlY2xhcmF0aW9uXCIpO1xuXHR9XG59XG5cbi8qKlxuICogU2FmZSwgc3RydWN0dXJlZCBsb2NhdGlvbiBhbmQgY2F0ZWdvcnkgZm9yIGEgcmVqZWN0ZWQgY29udHJhY3QgdmFsdWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlIHtcblx0cHVibGljIHJlYWRvbmx5IHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHB1YmxpYyByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW10sIGNvZGU6IHN0cmluZykge1xuXHRcdHRoaXMucGF0aCA9IE9iamVjdC5mcmVlemUoWy4uLnBhdGhdKTtcblx0XHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR9XG5cblx0cHVibGljIHRvSlNPTigpOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cGF0aDogWy4uLnRoaXMucGF0aF0sXG5cdFx0XHRjb2RlOiB0aGlzLmNvZGUsXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIEEgcmVxdWVzdCBvciByZXN1bHQgZGlkIG5vdCBzYXRpc2Z5IGl0cyBkZWNsYXJlZCB3aXJlIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0NvbnRyYWN0VmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cHVibGljIHJlYWRvbmx5IGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRkaXJlY3Rpb246IFZhbGlkYXRpb25EaXJlY3Rpb24sXG5cdFx0aXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG5cdCkge1xuXHRcdGNvbnN0IHByZWZpeCA9IGRpcmVjdGlvbiA9PT0gXCJyZXF1ZXN0XCIgPyBcIlJlcXVlc3RcIiA6IFwiUmVzdWx0XCI7XG5cdFx0c3VwZXIoYCR7cHJlZml4fSBjb250cmFjdCB2YWxpZGF0aW9uIGZhaWxlZGAsIFwiY29udHJhY3RfdmFsaWRhdGlvbl9mYWlsZWRcIik7XG5cdFx0dGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cdFx0dGhpcy5pc3N1ZXMgPSBPYmplY3QuZnJlZXplKFsuLi5pc3N1ZXNdKTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZENvbnRyYWN0VmFsaWRhdGlvbkVycm9yIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdFx0ZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcblx0XHRcdGlzc3VlczogdGhpcy5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gaXNzdWUudG9KU09OKCkpLFxuXHRcdH07XG5cdH1cbn1cblxuY29uc3QgREVDTEFSQVRJT05fSURfUEFUVEVSTiA9IC9eW2EtekEtWl1bYS16QS1aMC05Xy4tXSokLztcbmNvbnN0IFBZVEhPTl9JREVOVElGSUVSX1BBVFRFUk4gPSAvXlthLXpBLVpfXVthLXpBLVowLTlfXSokLztcblxuZnVuY3Rpb24gaXNQbGFpblJlY29yZCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcblx0cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlRGVjbGFyYXRpb25JZCh2YWx1ZTogdW5rbm93biwgbGFiZWw6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgIURFQ0xBUkFUSU9OX0lEX1BBVFRFUk4udGVzdCh2YWx1ZSkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgSW52YWxpZCAke2xhYmVsfSBpZDogZXhwZWN0ZWQgW2EtekEtWl1bYS16QS1aMC05Xy4tXSpgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUodmFsdWU6IHVua25vd24sIGlkOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiIHx8IHZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiB0aXRsZSBtdXN0IGJlIGEgbm9uZW1wdHkgc3RyaW5nYCk7XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFjdGlvbkRlc2NyaXB0aW9uKHJhdzogdW5rbm93bik6IEFjdGlvbkRlc2NyaXB0aW9uIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHJhdykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJBY3Rpb24gZGVzY3JpcHRpb24gbXVzdCBiZSBhbiBvYmplY3RcIik7XG5cdH1cblx0Y29uc3QgaWQgPSB2YWxpZGF0ZURlY2xhcmF0aW9uSWQocmF3LmlkLCBcImFjdGlvblwiKTtcblx0Y29uc3QgdGl0bGUgPSB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUocmF3LnRpdGxlLCBpZCk7XG5cdGlmIChcblx0XHR0eXBlb2YgcmF3LmhhbmRsZXIgIT09IFwic3RyaW5nXCIgfHxcblx0XHQhUFlUSE9OX0lERU5USUZJRVJfUEFUVEVSTi50ZXN0KHJhdy5oYW5kbGVyKVxuXHQpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IGhhbmRsZXIgbXVzdCBiZSBhIHZhbGlkIFB5dGhvbiBpZGVudGlmaWVyYCxcblx0XHQpO1xuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChyYXcucmVxdWVzdCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IHJlcXVlc3Qgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChyYXcucmVzdWx0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHtpZH06IHJlc3VsdCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgKTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0aGFuZGxlcjogcmF3LmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXF1ZXN0IH0pLFxuXHRcdHJlc3VsdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXN1bHQgfSksXG5cdH0pO1xufVxuXG4vKipcbiAqIFBhcnNlIGFuZCB2YWxpZGF0ZSBhIHZlcnNpb24gMSBgUGx1Z2luRGVzY3JpcHRpb25gIGVtaXR0ZWQgYnkgYGRlc2NyaWJlX3BsdWdpbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uKFxuXHRpbnB1dDogc3RyaW5nIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuKTogUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRsZXQgcGFyc2VkOiB1bmtub3duID0gaW5wdXQ7XG5cdGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcblx0XHR0cnkge1xuXHRcdFx0cGFyc2VkID0gSlNPTi5wYXJzZShpbnB1dCk7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJQbHVnaW4gZGVzY3JpcHRpb24gaXMgbm90IHZhbGlkIEpTT05cIik7XG5cdFx0fVxuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChwYXJzZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFwiUGx1Z2luIGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuXHR9XG5cdGlmIChwYXJzZWQuc2NoZW1hX3ZlcnNpb24gIT09IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTikge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBVbnN1cHBvcnRlZCBwbHVnaW4gZGVzY3JpcHRpb24gc2NoZW1hX3ZlcnNpb246ICR7U3RyaW5nKHBhcnNlZC5zY2hlbWFfdmVyc2lvbil9YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHBhcnNlZC5pZCwgXCJwbHVnaW5cIik7XG5cdGNvbnN0IHRpdGxlID0gdmFsaWRhdGVOb25CbGFua1RpdGxlKHBhcnNlZC50aXRsZSwgaWQpO1xuXHRpZiAoIUFycmF5LmlzQXJyYXkocGFyc2VkLmFjdGlvbnMpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKGAke2lkfTogYWN0aW9ucyBtdXN0IGJlIGFuIGFycmF5YCk7XG5cdH1cblx0Y29uc3Qgc2VlbklkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRjb25zdCBhY3Rpb25zOiBBY3Rpb25EZXNjcmlwdGlvbltdID0gW107XG5cdGZvciAoY29uc3QgaXRlbSBvZiBwYXJzZWQuYWN0aW9ucykge1xuXHRcdGNvbnN0IGFjdGlvbiA9IHBhcnNlQWN0aW9uRGVzY3JpcHRpb24oaXRlbSk7XG5cdFx0aWYgKHNlZW5JZHMuaGFzKGFjdGlvbi5pZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aWR9OiBkdXBsaWNhdGUgYWN0aW9uIGlkICR7YWN0aW9uLmlkfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRzZWVuSWRzLmFkZChhY3Rpb24uaWQpO1xuXHRcdGFjdGlvbnMucHVzaChhY3Rpb24pO1xuXHR9XG5cdGFjdGlvbnMuc29ydCgobGVmdCwgcmlnaHQpID0+IChsZWZ0LmlkIDwgcmlnaHQuaWQgPyAtMSA6IDEpKTtcblx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdHNjaGVtYV92ZXJzaW9uOiBQTFVHSU5fREVTQ1JJUFRJT05fU0NIRU1BX1ZFUlNJT04sXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0YWN0aW9uczogT2JqZWN0LmZyZWV6ZShhY3Rpb25zKSxcblx0fSk7XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiO0FBT08sSUFBTSxtQkFBMkI7QUFDakMsSUFBTSxtQkFBMkI7QUFDakMsSUFBTSxvQ0FBdUM7QUFpQzdDLFNBQVMsaUJBQWlCLENBQUMsT0FBaUM7QUFBQSxFQUNsRSxPQUFPLE9BQU8sVUFBVSxZQUFZLE9BQU8sY0FBYyxLQUFLO0FBQUE7QUFBQTtBQU14RCxNQUFNLHFCQUFxQixNQUFNO0FBQUEsRUFDdkI7QUFBQSxFQUVULFdBQVcsQ0FBQyxTQUFpQixPQUFlLGFBQWE7QUFBQSxJQUMvRCxNQUFNLE9BQU87QUFBQSxJQUNiLEtBQUssT0FBTyxXQUFXO0FBQUEsSUFDdkIsS0FBSyxPQUFPO0FBQUE7QUFFZDtBQUFBO0FBS08sTUFBTSxnQ0FBZ0MsYUFBYTtBQUFBLEVBQ2xELFdBQVcsR0FBRztBQUFBLElBQ3BCLE1BQU0seUNBQXlDLGNBQWM7QUFBQTtBQUUvRDtBQUFBO0FBS08sTUFBTSwwQ0FBMEMsYUFBYTtBQUFBLEVBQ25EO0FBQUEsRUFFVCxXQUFXLENBQUMsWUFBb0I7QUFBQSxJQUN0QyxNQUNDLGNBQWMsS0FBSyxVQUFVLFVBQVUsb0NBQ3ZDLHdCQUNEO0FBQUEsSUFDQSxLQUFLLGFBQWE7QUFBQTtBQUVwQjtBQUFBO0FBS08sTUFBTSxnQ0FBZ0MsYUFBYTtBQUFBLEVBQ2xELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQ25DLE1BQU0sU0FBUyxxQkFBcUI7QUFBQTtBQUV0QztB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
30
+ //# debugId=B8E64E2D8764D48064756E2164756E21
31
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFtdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICBdLAogICJtYXBwaW5ncyI6ICIiLAogICJkZWJ1Z0lkIjogIkI4RTY0RTJEODc2NEQ0ODA2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
@@ -0,0 +1,217 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ /**
3
+ * Base class for expected SDK errors across the bridge boundary.
4
+ */
5
+ declare class QgisSdkError extends Error {
6
+ readonly code: string;
7
+ constructor(message: string, code?: string);
8
+ }
9
+ /** The kinds of event a stream may carry; only `progress` may be coalesced. */
10
+ type StreamEventKind2 = "data" | "progress" | "state";
11
+ /** Why a subscription stopped. */
12
+ type StreamTerminalKind = "complete" | "error" | "cancelled" | "gap" | "disposed";
13
+ /** One event on a subscription. */
14
+ interface BridgeStreamEvent {
15
+ readonly kind: StreamEventKind2;
16
+ readonly payload: unknown;
17
+ }
18
+ /** The end of a subscription, as the host described it. */
19
+ interface BridgeStreamTerminal {
20
+ readonly kind: StreamTerminalKind;
21
+ readonly message?: string;
22
+ readonly dropped?: number;
23
+ }
24
+ /** The transport a client speaks through; a QWebChannel adapter or a script. */
25
+ interface WireTransport {
26
+ send(message: unknown): void;
27
+ subscribe(listener: (message: unknown) => void): () => void;
28
+ }
29
+ /** Options for {@link BridgeClient}. */
30
+ interface BridgeClientOptions {
31
+ readonly timeoutMs?: number;
32
+ }
33
+ /** Options for one invocation. */
34
+ interface InvokeOptions {
35
+ readonly signal?: AbortSignal;
36
+ }
37
+ /** Callbacks a subscription reports through. */
38
+ interface SubscriptionHandlers {
39
+ readonly onEvent?: (event: BridgeStreamEvent) => void;
40
+ readonly onTerminal?: (terminal: BridgeStreamTerminal) => void;
41
+ }
42
+ /** A live subscription, as the caller holds it. */
43
+ interface BridgeSubscription {
44
+ readonly id: string;
45
+ readonly closed: boolean;
46
+ close(): void;
47
+ }
48
+ /**
49
+ * Correlate invocations with replies over an injected transport.
50
+ *
51
+ * The client never retries: a timeout, an abort and a closed client are three
52
+ * different answers, and each is reported as itself.
53
+ */
54
+ declare class BridgeClient {
55
+ private readonly transport;
56
+ private readonly timeoutMs;
57
+ private readonly pending;
58
+ private readonly subscriptions;
59
+ private readonly disposals;
60
+ private readonly unsubscribe;
61
+ private counter;
62
+ private closed;
63
+ private unmatched;
64
+ private breaks;
65
+ private lastProtocolError;
66
+ constructor(transport: WireTransport, options?: BridgeClientOptions);
67
+ /** Whether {@link close} has run; a closed client answers nothing. */
68
+ get isClosed(): boolean;
69
+ /** Replies that named no pending call: a late duplicate, or a stray message. */
70
+ get unmatchedReplies(): number;
71
+ /** Number of calls still waiting for a reply. */
72
+ get pendingCalls(): number;
73
+ /**
74
+ * Invoke one operation and settle with its value or with a typed failure.
75
+ */
76
+ invoke(operation: string, payload?: Readonly<Record<string, unknown>>, options?: InvokeOptions): Promise<unknown>;
77
+ /**
78
+ * Open a subscription and resolve once the host has acknowledged it.
79
+ *
80
+ * Frames are matched to the subscription by id and by sequence; a frame that
81
+ * does not continue the sequence ends the subscription instead of being
82
+ * delivered out of order.
83
+ */
84
+ subscribe(operation: string, payload?: Readonly<Record<string, unknown>>, handlers?: SubscriptionHandlers, options?: InvokeOptions): Promise<BridgeSubscription>;
85
+ /** Subscriptions still open; a leak check for callers and tests. */
86
+ get activeSubscriptions(): readonly string[];
87
+ /** Frames that did not continue their subscription's sequence. */
88
+ get sequenceBreaks(): number;
89
+ private send;
90
+ /**
91
+ * Refuse further calls, reject what is still pending, and stop listening.
92
+ */
93
+ close(): void;
94
+ private settle;
95
+ private handle;
96
+ private handleFrame;
97
+ private endSubscription;
98
+ private disposeSubscription;
99
+ /** The last malformed message this client refused, if any. */
100
+ get protocolError(): Error | null;
101
+ }
102
+ /** A hook or provider was used outside the shape it needs. */
103
+ declare class QgisSdkBridgeReactError extends QgisSdkError {
104
+ constructor(message: string);
105
+ }
106
+ /** Props for {@link BridgeProvider}: exactly one of `client` or `transport`. */
107
+ interface BridgeProviderProps {
108
+ /** A client the caller owns; the provider never closes it. */
109
+ readonly client?: BridgeClient;
110
+ /** A transport the provider builds and owns a client for. */
111
+ readonly transport?: WireTransport;
112
+ /** Options for the owned client; ignored when `client` is given. */
113
+ readonly options?: BridgeClientOptions;
114
+ readonly children?: ReactNode;
115
+ }
116
+ /**
117
+ * Share one client with a subtree.
118
+ *
119
+ * An owned client is created in an effect, never during render, because
120
+ * StrictMode renders twice and a client made in render would leave a second
121
+ * listener on the transport. Until that effect has run the subtree is not
122
+ * rendered, which is one tick. StrictMode's simulated unmount closes the
123
+ * owned client and the effect that follows makes a new one, so the subtree
124
+ * never holds a dead client. The transport must be stable across renders; to
125
+ * swap it, change the provider's `key`.
126
+ */
127
+ declare function BridgeProvider(props: BridgeProviderProps): ReactElement;
128
+ /** The client of the nearest {@link BridgeProvider}. */
129
+ declare function useBridgeClient(): BridgeClient;
130
+ /**
131
+ * Build a generated operation map once per client: `useOperations(createOperations)`.
132
+ */
133
+ declare function useOperations<T>(create: (client: BridgeClient) => T): T;
134
+ /** Where one invocation stands. */
135
+ type OperationState<R> = {
136
+ readonly status: "idle";
137
+ } | {
138
+ readonly status: "pending";
139
+ } | {
140
+ readonly status: "ok";
141
+ readonly value: R;
142
+ } | {
143
+ readonly status: "error";
144
+ readonly error: Error;
145
+ };
146
+ /** Controls beyond running: abort what is in flight, or forget the outcome. */
147
+ interface OperationControls {
148
+ /** Abort the in-flight call locally; the host may still run it. */
149
+ abort(): void;
150
+ /** Back to `idle`, aborting anything in flight. */
151
+ reset(): void;
152
+ }
153
+ /** An operation member of a generated map: input, optional signal, promise. */
154
+ type Operation<
155
+ I,
156
+ R
157
+ > = (input: I, options?: {
158
+ readonly signal?: AbortSignal;
159
+ }) => Promise<R>;
160
+ /**
161
+ * Run a generated operation from a component.
162
+ *
163
+ * `run` resolves with the value, or with `undefined` when the call failed, was
164
+ * aborted or was superseded by a later run - the state carries the error, so
165
+ * the promise never rejects into an event handler. Only the latest run can
166
+ * change the state; unmounting aborts whatever is in flight.
167
+ */
168
+ declare function useOperation<
169
+ I,
170
+ R
171
+ >(operation: Operation<I, R>): readonly [OperationState<R>, (input: I) => Promise<R | undefined>, OperationControls];
172
+ /** How a stream ended, as the generated module reports it. */
173
+ interface StreamTerminalLike {
174
+ readonly kind: string;
175
+ readonly message?: string;
176
+ readonly dropped?: number;
177
+ }
178
+ /** The handle a generated stream member resolves with. */
179
+ interface StreamHandleLike {
180
+ readonly id: string;
181
+ readonly closed: boolean;
182
+ close(): void;
183
+ }
184
+ /** Handlers for a stream, as a generated module types them. */
185
+ interface StreamHandlersLike<E> {
186
+ readonly onEvent?: (event: E) => void;
187
+ readonly onTerminal?: (terminal: StreamTerminalLike) => void;
188
+ }
189
+ /** A stream member of a generated map. */
190
+ type Stream<
191
+ I,
192
+ E
193
+ > = (input: I, handlers: StreamHandlersLike<E>, options?: {
194
+ readonly signal?: AbortSignal;
195
+ }) => Promise<StreamHandleLike>;
196
+ /** Where one subscription stands. */
197
+ interface StreamState<E> {
198
+ /** `idle` with a null input, `failed` when the host refused to open it. */
199
+ readonly status: "idle" | "opening" | "open" | "ended" | "failed";
200
+ readonly lastEvent: E | null;
201
+ readonly terminal: StreamTerminalLike | null;
202
+ readonly error: Error | null;
203
+ }
204
+ /**
205
+ * Hold a generated stream open while a component is mounted.
206
+ *
207
+ * The subscription follows `open` and the *content* of `input`: a new object
208
+ * with the same fields does not reopen it, a different one closes the old
209
+ * stream and opens a new one, and `null` closes it. Handlers are read fresh
210
+ * on every frame, so a new closure does not reopen anything either. Unmount
211
+ * closes the stream, even if the host has not yet acknowledged it.
212
+ */
213
+ declare function useStream<
214
+ I,
215
+ E
216
+ >(open: Stream<I, E>, input: I | null, handlers?: StreamHandlersLike<E>): StreamState<E>;
217
+ export { BridgeProvider, BridgeProviderProps, Operation, OperationControls, OperationState, QgisSdkBridgeReactError, Stream, StreamHandleLike, StreamHandlersLike, StreamState, StreamTerminalLike, useBridgeClient, useOperation, useOperations, useStream };
package/dist/react.js ADDED
@@ -0,0 +1,196 @@
1
+ import {
2
+ QgisSdkError2,
3
+ isPlainRecord2
4
+ } from "./shared/chunk-0fknax6w.js";
5
+ import {
6
+ QgisSdkBridgeAbortedError2,
7
+ BridgeClient2
8
+ } from "./shared/chunk-a7bjgeve.js";
9
+
10
+ // src/react.ts
11
+ import {
12
+ createContext,
13
+ createElement,
14
+ useCallback,
15
+ useContext,
16
+ useEffect,
17
+ useMemo,
18
+ useRef,
19
+ useState
20
+ } from "react";
21
+ class QgisSdkBridgeReactError extends QgisSdkError2 {
22
+ constructor(message) {
23
+ super(message, "react_binding");
24
+ }
25
+ }
26
+ var ClientContext = createContext(null);
27
+ function BridgeProvider(props) {
28
+ const { client, transport, options, children } = props;
29
+ if (client === undefined === (transport === undefined)) {
30
+ throw new QgisSdkBridgeReactError("BridgeProvider needs exactly one of client or transport");
31
+ }
32
+ const timeoutMs = options?.timeoutMs;
33
+ const [owned, setOwned] = useState(null);
34
+ useEffect(() => {
35
+ if (transport === undefined) {
36
+ return;
37
+ }
38
+ const live = new BridgeClient2(transport, timeoutMs === undefined ? {} : { timeoutMs });
39
+ setOwned(live);
40
+ return () => {
41
+ live.close();
42
+ setOwned((current) => current === live ? null : current);
43
+ };
44
+ }, [transport, timeoutMs]);
45
+ const value = client ?? owned;
46
+ return createElement(ClientContext.Provider, { value }, value === null ? null : children);
47
+ }
48
+ function useBridgeClient() {
49
+ const client = useContext(ClientContext);
50
+ if (client === null) {
51
+ throw new QgisSdkBridgeReactError("useBridgeClient needs a BridgeProvider above it");
52
+ }
53
+ return client;
54
+ }
55
+ function useOperations(create) {
56
+ const client = useBridgeClient();
57
+ return useMemo(() => create(client), [create, client]);
58
+ }
59
+ var IDLE = Object.freeze({ status: "idle" });
60
+ var PENDING = Object.freeze({ status: "pending" });
61
+ function useOperation(operation) {
62
+ const [state, setState] = useState(IDLE);
63
+ const generation = useRef(0);
64
+ const controller = useRef(null);
65
+ const mounted = useRef(true);
66
+ const abort = useCallback(() => {
67
+ generation.current += 1;
68
+ controller.current?.abort();
69
+ controller.current = null;
70
+ }, []);
71
+ useEffect(() => {
72
+ mounted.current = true;
73
+ return () => {
74
+ mounted.current = false;
75
+ abort();
76
+ };
77
+ }, [abort]);
78
+ const run = useCallback(async (input) => {
79
+ abort();
80
+ const mine = generation.current;
81
+ const signal = new AbortController;
82
+ controller.current = signal;
83
+ setState(PENDING);
84
+ try {
85
+ const value = await operation(input, { signal: signal.signal });
86
+ if (generation.current !== mine || !mounted.current) {
87
+ return;
88
+ }
89
+ setState({ status: "ok", value });
90
+ return value;
91
+ } catch (error) {
92
+ if (generation.current !== mine || !mounted.current) {
93
+ return;
94
+ }
95
+ if (error instanceof QgisSdkBridgeAbortedError2) {
96
+ return;
97
+ }
98
+ setState({
99
+ status: "error",
100
+ error: error instanceof Error ? error : new Error(String(error))
101
+ });
102
+ return;
103
+ } finally {
104
+ if (controller.current === signal) {
105
+ controller.current = null;
106
+ }
107
+ }
108
+ }, [operation, abort]);
109
+ const reset = useCallback(() => {
110
+ abort();
111
+ setState(IDLE);
112
+ }, [abort]);
113
+ const controls = useMemo(() => ({ abort, reset }), [abort, reset]);
114
+ return [state, run, controls];
115
+ }
116
+ var IDLE_STREAM = Object.freeze({
117
+ status: "idle",
118
+ lastEvent: null,
119
+ terminal: null,
120
+ error: null
121
+ });
122
+ function stableKey(value) {
123
+ return JSON.stringify(value, (_key, item) => isPlainRecord2(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item);
124
+ }
125
+ function useStream(open, input, handlers = {}) {
126
+ const [state, setState] = useState(IDLE_STREAM);
127
+ const latest = useRef(handlers);
128
+ latest.current = handlers;
129
+ const key = input === null ? null : stableKey(input);
130
+ const inputRef = useRef(input);
131
+ inputRef.current = input;
132
+ useEffect(() => {
133
+ if (key === null) {
134
+ setState(IDLE_STREAM);
135
+ return;
136
+ }
137
+ const current = inputRef.current;
138
+ let cancelled = false;
139
+ let handle = null;
140
+ setState({
141
+ status: "opening",
142
+ lastEvent: null,
143
+ terminal: null,
144
+ error: null
145
+ });
146
+ open(current, {
147
+ onEvent: (event) => {
148
+ if (cancelled) {
149
+ return;
150
+ }
151
+ latest.current.onEvent?.(event);
152
+ setState((previous) => ({ ...previous, lastEvent: event }));
153
+ },
154
+ onTerminal: (terminal) => {
155
+ if (cancelled) {
156
+ return;
157
+ }
158
+ latest.current.onTerminal?.(terminal);
159
+ setState((previous) => ({ ...previous, status: "ended", terminal }));
160
+ }
161
+ }).then((opened) => {
162
+ if (cancelled) {
163
+ opened.close();
164
+ return;
165
+ }
166
+ handle = opened;
167
+ setState((previous) => previous.status === "ended" ? previous : { ...previous, status: "open" });
168
+ }, (error) => {
169
+ if (cancelled) {
170
+ return;
171
+ }
172
+ setState({
173
+ status: "failed",
174
+ lastEvent: null,
175
+ terminal: null,
176
+ error: error instanceof Error ? error : new Error(String(error))
177
+ });
178
+ });
179
+ return () => {
180
+ cancelled = true;
181
+ handle?.close();
182
+ };
183
+ }, [open, key]);
184
+ return state;
185
+ }
186
+ export {
187
+ BridgeProvider,
188
+ QgisSdkBridgeReactError,
189
+ useBridgeClient,
190
+ useOperation,
191
+ useOperations,
192
+ useStream
193
+ };
194
+
195
+ //# debugId=B9173116D0A8AD4364756E2164756E21
196
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3JlYWN0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogVGhpbiBSZWFjdCBiaW5kaW5ncyBvdmVyIHRoZSBicmlkZ2UgY2xpZW50IChUQVNLLTE4LCBkZWNpc2lvbi0xOCkuXG4gKlxuICogVGhpcyBlbnRyeSBwb2ludCBpcyBvcHRpb25hbCBhbmQgaXMgdGhlIG9ubHkgb25lIHRoYXQgaW1wb3J0cyBSZWFjdC4gSXQgYWRkc1xuICogbm8gc2Vjb25kIGNsaWVudDogYSBjb21wb25lbnQgcmVhY2hlcyB0aGUgc2FtZSBgQnJpZGdlQ2xpZW50YCBhIHZhbmlsbGEgcGFnZVxuICogd291bGQgYnVpbGQsIHRocm91Z2ggYSBwcm92aWRlciB0aGF0IGVpdGhlciBvd25zIG9uZSAoYW5kIGNsb3NlcyBpdCBvblxuICogdW5tb3VudCkgb3IgaXMgaGFuZGVkIG9uZSAoYW5kIGxlYXZlcyBpdCBhbG9uZSkuIFRoZSBob29rcyB0YWtlIHRoZVxuICogZnVuY3Rpb25zIGEgZ2VuZXJhdGVkIG1vZHVsZSBhbHJlYWR5IGV4cG9ydHMgLSBgb3BlcmF0aW9ucy5zaXRlcy5zdW1tYXJ5YCxcbiAqIGBvcGVyYXRpb25zLnNpdGVzLndhdGNoYCAtIHNvIHRoZSB0eXBlZCBjb250cmFjdCBpcyB0aGUgZ2VuZXJhdGVkIG9uZSwgbm90IGFcbiAqIFJlYWN0IGNvcHkgb2YgaXQuXG4gKlxuICogV2hhdCB0aGUgaG9va3MgYWRkIGlzIGxpZmV0aW1lOiBhIGNhbGwgYWJvcnRlZCB3aGVuIGl0cyBjb21wb25lbnQgdW5tb3VudHMsXG4gKiBhIHN0YWxlIHJlcGx5IGlnbm9yZWQsIGEgc3RyZWFtIGNsb3NlZCBvbiB1bm1vdW50IG9yIHdoZW4gaXRzIGlucHV0IGNoYW5nZXMsXG4gKiBhbmQgYSBzaW11bGF0ZWQgU3RyaWN0TW9kZSByZW1vdW50IHRoYXQgbGVhdmVzIGV4YWN0bHkgb25lIG9mIGVhY2guXG4gKi9cblxuaW1wb3J0IHtcblx0Y3JlYXRlQ29udGV4dCxcblx0Y3JlYXRlRWxlbWVudCxcblx0dHlwZSBSZWFjdEVsZW1lbnQsXG5cdHR5cGUgUmVhY3ROb2RlLFxuXHR1c2VDYWxsYmFjayxcblx0dXNlQ29udGV4dCxcblx0dXNlRWZmZWN0LFxuXHR1c2VNZW1vLFxuXHR1c2VSZWYsXG5cdHVzZVN0YXRlLFxufSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7XG5cdEJyaWRnZUNsaWVudCxcblx0dHlwZSBCcmlkZ2VDbGllbnRPcHRpb25zLFxuXHRRZ2lzU2RrQnJpZGdlQWJvcnRlZEVycm9yLFxuXHR0eXBlIFdpcmVUcmFuc3BvcnQsXG59IGZyb20gXCIuL2JyaWRnZVwiO1xuaW1wb3J0IHsgaXNQbGFpblJlY29yZCwgUWdpc1Nka0Vycm9yIH0gZnJvbSBcIi4vaW5kZXhcIjtcblxuLyoqIEEgaG9vayBvciBwcm92aWRlciB3YXMgdXNlZCBvdXRzaWRlIHRoZSBzaGFwZSBpdCBuZWVkcy4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrQnJpZGdlUmVhY3RFcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcblx0XHRzdXBlcihtZXNzYWdlLCBcInJlYWN0X2JpbmRpbmdcIik7XG5cdH1cbn1cblxuY29uc3QgQ2xpZW50Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8QnJpZGdlQ2xpZW50IHwgbnVsbD4obnVsbCk7XG5cbi8qKiBQcm9wcyBmb3Ige0BsaW5rIEJyaWRnZVByb3ZpZGVyfTogZXhhY3RseSBvbmUgb2YgYGNsaWVudGAgb3IgYHRyYW5zcG9ydGAuICovXG5leHBvcnQgaW50ZXJmYWNlIEJyaWRnZVByb3ZpZGVyUHJvcHMge1xuXHQvKiogQSBjbGllbnQgdGhlIGNhbGxlciBvd25zOyB0aGUgcHJvdmlkZXIgbmV2ZXIgY2xvc2VzIGl0LiAqL1xuXHRyZWFkb25seSBjbGllbnQ/OiBCcmlkZ2VDbGllbnQ7XG5cdC8qKiBBIHRyYW5zcG9ydCB0aGUgcHJvdmlkZXIgYnVpbGRzIGFuZCBvd25zIGEgY2xpZW50IGZvci4gKi9cblx0cmVhZG9ubHkgdHJhbnNwb3J0PzogV2lyZVRyYW5zcG9ydDtcblx0LyoqIE9wdGlvbnMgZm9yIHRoZSBvd25lZCBjbGllbnQ7IGlnbm9yZWQgd2hlbiBgY2xpZW50YCBpcyBnaXZlbi4gKi9cblx0cmVhZG9ubHkgb3B0aW9ucz86IEJyaWRnZUNsaWVudE9wdGlvbnM7XG5cdHJlYWRvbmx5IGNoaWxkcmVuPzogUmVhY3ROb2RlO1xufVxuXG4vKipcbiAqIFNoYXJlIG9uZSBjbGllbnQgd2l0aCBhIHN1YnRyZWUuXG4gKlxuICogQW4gb3duZWQgY2xpZW50IGlzIGNyZWF0ZWQgaW4gYW4gZWZmZWN0LCBuZXZlciBkdXJpbmcgcmVuZGVyLCBiZWNhdXNlXG4gKiBTdHJpY3RNb2RlIHJlbmRlcnMgdHdpY2UgYW5kIGEgY2xpZW50IG1hZGUgaW4gcmVuZGVyIHdvdWxkIGxlYXZlIGEgc2Vjb25kXG4gKiBsaXN0ZW5lciBvbiB0aGUgdHJhbnNwb3J0LiBVbnRpbCB0aGF0IGVmZmVjdCBoYXMgcnVuIHRoZSBzdWJ0cmVlIGlzIG5vdFxuICogcmVuZGVyZWQsIHdoaWNoIGlzIG9uZSB0aWNrLiBTdHJpY3RNb2RlJ3Mgc2ltdWxhdGVkIHVubW91bnQgY2xvc2VzIHRoZVxuICogb3duZWQgY2xpZW50IGFuZCB0aGUgZWZmZWN0IHRoYXQgZm9sbG93cyBtYWtlcyBhIG5ldyBvbmUsIHNvIHRoZSBzdWJ0cmVlXG4gKiBuZXZlciBob2xkcyBhIGRlYWQgY2xpZW50LiBUaGUgdHJhbnNwb3J0IG11c3QgYmUgc3RhYmxlIGFjcm9zcyByZW5kZXJzOyB0b1xuICogc3dhcCBpdCwgY2hhbmdlIHRoZSBwcm92aWRlcidzIGBrZXlgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQnJpZGdlUHJvdmlkZXIocHJvcHM6IEJyaWRnZVByb3ZpZGVyUHJvcHMpOiBSZWFjdEVsZW1lbnQge1xuXHRjb25zdCB7IGNsaWVudCwgdHJhbnNwb3J0LCBvcHRpb25zLCBjaGlsZHJlbiB9ID0gcHJvcHM7XG5cdGlmICgoY2xpZW50ID09PSB1bmRlZmluZWQpID09PSAodHJhbnNwb3J0ID09PSB1bmRlZmluZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VSZWFjdEVycm9yKFxuXHRcdFx0XCJCcmlkZ2VQcm92aWRlciBuZWVkcyBleGFjdGx5IG9uZSBvZiBjbGllbnQgb3IgdHJhbnNwb3J0XCIsXG5cdFx0KTtcblx0fVxuXHRjb25zdCB0aW1lb3V0TXMgPSBvcHRpb25zPy50aW1lb3V0TXM7XG5cdGNvbnN0IFtvd25lZCwgc2V0T3duZWRdID0gdXNlU3RhdGU8QnJpZGdlQ2xpZW50IHwgbnVsbD4obnVsbCk7XG5cdHVzZUVmZmVjdCgoKSA9PiB7XG5cdFx0aWYgKHRyYW5zcG9ydCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRjb25zdCBsaXZlID0gbmV3IEJyaWRnZUNsaWVudChcblx0XHRcdHRyYW5zcG9ydCxcblx0XHRcdHRpbWVvdXRNcyA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHRpbWVvdXRNcyB9LFxuXHRcdCk7XG5cdFx0c2V0T3duZWQobGl2ZSk7XG5cdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdGxpdmUuY2xvc2UoKTtcblx0XHRcdHNldE93bmVkKChjdXJyZW50KSA9PiAoY3VycmVudCA9PT0gbGl2ZSA/IG51bGwgOiBjdXJyZW50KSk7XG5cdFx0fTtcblx0fSwgW3RyYW5zcG9ydCwgdGltZW91dE1zXSk7XG5cdGNvbnN0IHZhbHVlID0gY2xpZW50ID8/IG93bmVkO1xuXHRyZXR1cm4gY3JlYXRlRWxlbWVudChcblx0XHRDbGllbnRDb250ZXh0LlByb3ZpZGVyLFxuXHRcdHsgdmFsdWUgfSxcblx0XHR2YWx1ZSA9PT0gbnVsbCA/IG51bGwgOiBjaGlsZHJlbixcblx0KTtcbn1cblxuLyoqIFRoZSBjbGllbnQgb2YgdGhlIG5lYXJlc3Qge0BsaW5rIEJyaWRnZVByb3ZpZGVyfS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VCcmlkZ2VDbGllbnQoKTogQnJpZGdlQ2xpZW50IHtcblx0Y29uc3QgY2xpZW50ID0gdXNlQ29udGV4dChDbGllbnRDb250ZXh0KTtcblx0aWYgKGNsaWVudCA9PT0gbnVsbCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrQnJpZGdlUmVhY3RFcnJvcihcblx0XHRcdFwidXNlQnJpZGdlQ2xpZW50IG5lZWRzIGEgQnJpZGdlUHJvdmlkZXIgYWJvdmUgaXRcIixcblx0XHQpO1xuXHR9XG5cdHJldHVybiBjbGllbnQ7XG59XG5cbi8qKlxuICogQnVpbGQgYSBnZW5lcmF0ZWQgb3BlcmF0aW9uIG1hcCBvbmNlIHBlciBjbGllbnQ6IGB1c2VPcGVyYXRpb25zKGNyZWF0ZU9wZXJhdGlvbnMpYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZU9wZXJhdGlvbnM8VD4oY3JlYXRlOiAoY2xpZW50OiBCcmlkZ2VDbGllbnQpID0+IFQpOiBUIHtcblx0Y29uc3QgY2xpZW50ID0gdXNlQnJpZGdlQ2xpZW50KCk7XG5cdHJldHVybiB1c2VNZW1vKCgpID0+IGNyZWF0ZShjbGllbnQpLCBbY3JlYXRlLCBjbGllbnRdKTtcbn1cblxuLyoqIFdoZXJlIG9uZSBpbnZvY2F0aW9uIHN0YW5kcy4gKi9cbmV4cG9ydCB0eXBlIE9wZXJhdGlvblN0YXRlPFI+ID1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJpZGxlXCIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcInBlbmRpbmdcIiB9XG5cdHwgeyByZWFkb25seSBzdGF0dXM6IFwib2tcIjsgcmVhZG9ubHkgdmFsdWU6IFIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcImVycm9yXCI7IHJlYWRvbmx5IGVycm9yOiBFcnJvciB9O1xuXG4vKiogQ29udHJvbHMgYmV5b25kIHJ1bm5pbmc6IGFib3J0IHdoYXQgaXMgaW4gZmxpZ2h0LCBvciBmb3JnZXQgdGhlIG91dGNvbWUuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvbkNvbnRyb2xzIHtcblx0LyoqIEFib3J0IHRoZSBpbi1mbGlnaHQgY2FsbCBsb2NhbGx5OyB0aGUgaG9zdCBtYXkgc3RpbGwgcnVuIGl0LiAqL1xuXHRhYm9ydCgpOiB2b2lkO1xuXHQvKiogQmFjayB0byBgaWRsZWAsIGFib3J0aW5nIGFueXRoaW5nIGluIGZsaWdodC4gKi9cblx0cmVzZXQoKTogdm9pZDtcbn1cblxuLyoqIEFuIG9wZXJhdGlvbiBtZW1iZXIgb2YgYSBnZW5lcmF0ZWQgbWFwOiBpbnB1dCwgb3B0aW9uYWwgc2lnbmFsLCBwcm9taXNlLiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uPEksIFI+ID0gKFxuXHRpbnB1dDogSSxcblx0b3B0aW9ucz86IHsgcmVhZG9ubHkgc2lnbmFsPzogQWJvcnRTaWduYWwgfSxcbikgPT4gUHJvbWlzZTxSPjtcblxuY29uc3QgSURMRTogT3BlcmF0aW9uU3RhdGU8bmV2ZXI+ID0gT2JqZWN0LmZyZWV6ZSh7IHN0YXR1czogXCJpZGxlXCIgfSk7XG5jb25zdCBQRU5ESU5HOiBPcGVyYXRpb25TdGF0ZTxuZXZlcj4gPSBPYmplY3QuZnJlZXplKHsgc3RhdHVzOiBcInBlbmRpbmdcIiB9KTtcblxuLyoqXG4gKiBSdW4gYSBnZW5lcmF0ZWQgb3BlcmF0aW9uIGZyb20gYSBjb21wb25lbnQuXG4gKlxuICogYHJ1bmAgcmVzb2x2ZXMgd2l0aCB0aGUgdmFsdWUsIG9yIHdpdGggYHVuZGVmaW5lZGAgd2hlbiB0aGUgY2FsbCBmYWlsZWQsIHdhc1xuICogYWJvcnRlZCBvciB3YXMgc3VwZXJzZWRlZCBieSBhIGxhdGVyIHJ1biAtIHRoZSBzdGF0ZSBjYXJyaWVzIHRoZSBlcnJvciwgc29cbiAqIHRoZSBwcm9taXNlIG5ldmVyIHJlamVjdHMgaW50byBhbiBldmVudCBoYW5kbGVyLiBPbmx5IHRoZSBsYXRlc3QgcnVuIGNhblxuICogY2hhbmdlIHRoZSBzdGF0ZTsgdW5tb3VudGluZyBhYm9ydHMgd2hhdGV2ZXIgaXMgaW4gZmxpZ2h0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlT3BlcmF0aW9uPEksIFI+KFxuXHRvcGVyYXRpb246IE9wZXJhdGlvbjxJLCBSPixcbik6IHJlYWRvbmx5IFtcblx0T3BlcmF0aW9uU3RhdGU8Uj4sXG5cdChpbnB1dDogSSkgPT4gUHJvbWlzZTxSIHwgdW5kZWZpbmVkPixcblx0T3BlcmF0aW9uQ29udHJvbHMsXG5dIHtcblx0Y29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSB1c2VTdGF0ZTxPcGVyYXRpb25TdGF0ZTxSPj4oSURMRSk7XG5cdGNvbnN0IGdlbmVyYXRpb24gPSB1c2VSZWYoMCk7XG5cdGNvbnN0IGNvbnRyb2xsZXIgPSB1c2VSZWY8QWJvcnRDb250cm9sbGVyIHwgbnVsbD4obnVsbCk7XG5cdGNvbnN0IG1vdW50ZWQgPSB1c2VSZWYodHJ1ZSk7XG5cblx0Y29uc3QgYWJvcnQgPSB1c2VDYWxsYmFjaygoKTogdm9pZCA9PiB7XG5cdFx0Z2VuZXJhdGlvbi5jdXJyZW50ICs9IDE7XG5cdFx0Y29udHJvbGxlci5jdXJyZW50Py5hYm9ydCgpO1xuXHRcdGNvbnRyb2xsZXIuY3VycmVudCA9IG51bGw7XG5cdH0sIFtdKTtcblxuXHR1c2VFZmZlY3QoKCkgPT4ge1xuXHRcdG1vdW50ZWQuY3VycmVudCA9IHRydWU7XG5cdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdG1vdW50ZWQuY3VycmVudCA9IGZhbHNlO1xuXHRcdFx0YWJvcnQoKTtcblx0XHR9O1xuXHR9LCBbYWJvcnRdKTtcblxuXHRjb25zdCBydW4gPSB1c2VDYWxsYmFjayhcblx0XHRhc3luYyAoaW5wdXQ6IEkpOiBQcm9taXNlPFIgfCB1bmRlZmluZWQ+ID0+IHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRjb25zdCBtaW5lID0gZ2VuZXJhdGlvbi5jdXJyZW50O1xuXHRcdFx0Y29uc3Qgc2lnbmFsID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXHRcdFx0Y29udHJvbGxlci5jdXJyZW50ID0gc2lnbmFsO1xuXHRcdFx0c2V0U3RhdGUoUEVORElORyk7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCB2YWx1ZSA9IGF3YWl0IG9wZXJhdGlvbihpbnB1dCwgeyBzaWduYWw6IHNpZ25hbC5zaWduYWwgfSk7XG5cdFx0XHRcdGlmIChnZW5lcmF0aW9uLmN1cnJlbnQgIT09IG1pbmUgfHwgIW1vdW50ZWQuY3VycmVudCkge1xuXHRcdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2V0U3RhdGUoeyBzdGF0dXM6IFwib2tcIiwgdmFsdWUgfSk7XG5cdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdGlmIChnZW5lcmF0aW9uLmN1cnJlbnQgIT09IG1pbmUgfHwgIW1vdW50ZWQuY3VycmVudCkge1xuXHRcdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGVycm9yIGluc3RhbmNlb2YgUWdpc1Nka0JyaWRnZUFib3J0ZWRFcnJvcikge1xuXHRcdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2V0U3RhdGUoe1xuXHRcdFx0XHRcdHN0YXR1czogXCJlcnJvclwiLFxuXHRcdFx0XHRcdGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSksXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0aWYgKGNvbnRyb2xsZXIuY3VycmVudCA9PT0gc2lnbmFsKSB7XG5cdFx0XHRcdFx0Y29udHJvbGxlci5jdXJyZW50ID0gbnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cdFx0W29wZXJhdGlvbiwgYWJvcnRdLFxuXHQpO1xuXG5cdGNvbnN0IHJlc2V0ID0gdXNlQ2FsbGJhY2soKCk6IHZvaWQgPT4ge1xuXHRcdGFib3J0KCk7XG5cdFx0c2V0U3RhdGUoSURMRSk7XG5cdH0sIFthYm9ydF0pO1xuXG5cdGNvbnN0IGNvbnRyb2xzID0gdXNlTWVtbygoKSA9PiAoeyBhYm9ydCwgcmVzZXQgfSksIFthYm9ydCwgcmVzZXRdKTtcblx0cmV0dXJuIFtzdGF0ZSwgcnVuLCBjb250cm9sc107XG59XG5cbi8qKiBIb3cgYSBzdHJlYW0gZW5kZWQsIGFzIHRoZSBnZW5lcmF0ZWQgbW9kdWxlIHJlcG9ydHMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmVhbVRlcm1pbmFsTGlrZSB7XG5cdHJlYWRvbmx5IGtpbmQ6IHN0cmluZztcblx0cmVhZG9ubHkgbWVzc2FnZT86IHN0cmluZztcblx0cmVhZG9ubHkgZHJvcHBlZD86IG51bWJlcjtcbn1cblxuLyoqIFRoZSBoYW5kbGUgYSBnZW5lcmF0ZWQgc3RyZWFtIG1lbWJlciByZXNvbHZlcyB3aXRoLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1IYW5kbGVMaWtlIHtcblx0cmVhZG9ubHkgaWQ6IHN0cmluZztcblx0cmVhZG9ubHkgY2xvc2VkOiBib29sZWFuO1xuXHRjbG9zZSgpOiB2b2lkO1xufVxuXG4vKiogSGFuZGxlcnMgZm9yIGEgc3RyZWFtLCBhcyBhIGdlbmVyYXRlZCBtb2R1bGUgdHlwZXMgdGhlbS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtSGFuZGxlcnNMaWtlPEU+IHtcblx0cmVhZG9ubHkgb25FdmVudD86IChldmVudDogRSkgPT4gdm9pZDtcblx0cmVhZG9ubHkgb25UZXJtaW5hbD86ICh0ZXJtaW5hbDogU3RyZWFtVGVybWluYWxMaWtlKSA9PiB2b2lkO1xufVxuXG4vKiogQSBzdHJlYW0gbWVtYmVyIG9mIGEgZ2VuZXJhdGVkIG1hcC4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbTxJLCBFPiA9IChcblx0aW5wdXQ6IEksXG5cdGhhbmRsZXJzOiBTdHJlYW1IYW5kbGVyc0xpa2U8RT4sXG5cdG9wdGlvbnM/OiB7IHJlYWRvbmx5IHNpZ25hbD86IEFib3J0U2lnbmFsIH0sXG4pID0+IFByb21pc2U8U3RyZWFtSGFuZGxlTGlrZT47XG5cbi8qKiBXaGVyZSBvbmUgc3Vic2NyaXB0aW9uIHN0YW5kcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtU3RhdGU8RT4ge1xuXHQvKiogYGlkbGVgIHdpdGggYSBudWxsIGlucHV0LCBgZmFpbGVkYCB3aGVuIHRoZSBob3N0IHJlZnVzZWQgdG8gb3BlbiBpdC4gKi9cblx0cmVhZG9ubHkgc3RhdHVzOiBcImlkbGVcIiB8IFwib3BlbmluZ1wiIHwgXCJvcGVuXCIgfCBcImVuZGVkXCIgfCBcImZhaWxlZFwiO1xuXHRyZWFkb25seSBsYXN0RXZlbnQ6IEUgfCBudWxsO1xuXHRyZWFkb25seSB0ZXJtaW5hbDogU3RyZWFtVGVybWluYWxMaWtlIHwgbnVsbDtcblx0cmVhZG9ubHkgZXJyb3I6IEVycm9yIHwgbnVsbDtcbn1cblxuY29uc3QgSURMRV9TVFJFQU06IFN0cmVhbVN0YXRlPG5ldmVyPiA9IE9iamVjdC5mcmVlemUoe1xuXHRzdGF0dXM6IFwiaWRsZVwiLFxuXHRsYXN0RXZlbnQ6IG51bGwsXG5cdHRlcm1pbmFsOiBudWxsLFxuXHRlcnJvcjogbnVsbCxcbn0pO1xuXG5mdW5jdGlvbiBzdGFibGVLZXkodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuXHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIChfa2V5LCBpdGVtOiB1bmtub3duKSA9PlxuXHRcdGlzUGxhaW5SZWNvcmQoaXRlbSlcblx0XHRcdD8gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0XHRcdE9iamVjdC5lbnRyaWVzKGl0ZW0pLnNvcnQoKFthXSwgW2JdKSA9PiAoYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDApKSxcblx0XHRcdFx0KVxuXHRcdFx0OiBpdGVtLFxuXHQpO1xufVxuXG4vKipcbiAqIEhvbGQgYSBnZW5lcmF0ZWQgc3RyZWFtIG9wZW4gd2hpbGUgYSBjb21wb25lbnQgaXMgbW91bnRlZC5cbiAqXG4gKiBUaGUgc3Vic2NyaXB0aW9uIGZvbGxvd3MgYG9wZW5gIGFuZCB0aGUgKmNvbnRlbnQqIG9mIGBpbnB1dGA6IGEgbmV3IG9iamVjdFxuICogd2l0aCB0aGUgc2FtZSBmaWVsZHMgZG9lcyBub3QgcmVvcGVuIGl0LCBhIGRpZmZlcmVudCBvbmUgY2xvc2VzIHRoZSBvbGRcbiAqIHN0cmVhbSBhbmQgb3BlbnMgYSBuZXcgb25lLCBhbmQgYG51bGxgIGNsb3NlcyBpdC4gSGFuZGxlcnMgYXJlIHJlYWQgZnJlc2hcbiAqIG9uIGV2ZXJ5IGZyYW1lLCBzbyBhIG5ldyBjbG9zdXJlIGRvZXMgbm90IHJlb3BlbiBhbnl0aGluZyBlaXRoZXIuIFVubW91bnRcbiAqIGNsb3NlcyB0aGUgc3RyZWFtLCBldmVuIGlmIHRoZSBob3N0IGhhcyBub3QgeWV0IGFja25vd2xlZGdlZCBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVN0cmVhbTxJLCBFPihcblx0b3BlbjogU3RyZWFtPEksIEU+LFxuXHRpbnB1dDogSSB8IG51bGwsXG5cdGhhbmRsZXJzOiBTdHJlYW1IYW5kbGVyc0xpa2U8RT4gPSB7fSxcbik6IFN0cmVhbVN0YXRlPEU+IHtcblx0Y29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSB1c2VTdGF0ZTxTdHJlYW1TdGF0ZTxFPj4oSURMRV9TVFJFQU0pO1xuXHRjb25zdCBsYXRlc3QgPSB1c2VSZWYoaGFuZGxlcnMpO1xuXHRsYXRlc3QuY3VycmVudCA9IGhhbmRsZXJzO1xuXHRjb25zdCBrZXkgPSBpbnB1dCA9PT0gbnVsbCA/IG51bGwgOiBzdGFibGVLZXkoaW5wdXQpO1xuXHQvLyBgaW5wdXRgIGlzIGRlbGliZXJhdGVseSByZWFkIHRocm91Z2ggYGtleWA6IHR3byBvYmplY3RzIHdpdGggdGhlIHNhbWVcblx0Ly8gZmllbGRzIGFyZSB0aGUgc2FtZSBzdWJzY3JpcHRpb24uXG5cdGNvbnN0IGlucHV0UmVmID0gdXNlUmVmKGlucHV0KTtcblx0aW5wdXRSZWYuY3VycmVudCA9IGlucHV0O1xuXG5cdHVzZUVmZmVjdCgoKSA9PiB7XG5cdFx0aWYgKGtleSA9PT0gbnVsbCkge1xuXHRcdFx0c2V0U3RhdGUoSURMRV9TVFJFQU0pO1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0Y29uc3QgY3VycmVudCA9IGlucHV0UmVmLmN1cnJlbnQgYXMgSTtcblx0XHRsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG5cdFx0bGV0IGhhbmRsZTogU3RyZWFtSGFuZGxlTGlrZSB8IG51bGwgPSBudWxsO1xuXHRcdHNldFN0YXRlKHtcblx0XHRcdHN0YXR1czogXCJvcGVuaW5nXCIsXG5cdFx0XHRsYXN0RXZlbnQ6IG51bGwsXG5cdFx0XHR0ZXJtaW5hbDogbnVsbCxcblx0XHRcdGVycm9yOiBudWxsLFxuXHRcdH0pO1xuXHRcdG9wZW4oY3VycmVudCwge1xuXHRcdFx0b25FdmVudDogKGV2ZW50KSA9PiB7XG5cdFx0XHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0bGF0ZXN0LmN1cnJlbnQub25FdmVudD8uKGV2ZW50KTtcblx0XHRcdFx0c2V0U3RhdGUoKHByZXZpb3VzKSA9PiAoeyAuLi5wcmV2aW91cywgbGFzdEV2ZW50OiBldmVudCB9KSk7XG5cdFx0XHR9LFxuXHRcdFx0b25UZXJtaW5hbDogKHRlcm1pbmFsKSA9PiB7XG5cdFx0XHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0bGF0ZXN0LmN1cnJlbnQub25UZXJtaW5hbD8uKHRlcm1pbmFsKTtcblx0XHRcdFx0c2V0U3RhdGUoKHByZXZpb3VzKSA9PiAoeyAuLi5wcmV2aW91cywgc3RhdHVzOiBcImVuZGVkXCIsIHRlcm1pbmFsIH0pKTtcblx0XHRcdH0sXG5cdFx0fSkudGhlbihcblx0XHRcdChvcGVuZWQpID0+IHtcblx0XHRcdFx0aWYgKGNhbmNlbGxlZCkge1xuXHRcdFx0XHRcdG9wZW5lZC5jbG9zZSgpO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRoYW5kbGUgPSBvcGVuZWQ7XG5cdFx0XHRcdHNldFN0YXRlKChwcmV2aW91cykgPT5cblx0XHRcdFx0XHRwcmV2aW91cy5zdGF0dXMgPT09IFwiZW5kZWRcIlxuXHRcdFx0XHRcdFx0PyBwcmV2aW91c1xuXHRcdFx0XHRcdFx0OiB7IC4uLnByZXZpb3VzLCBzdGF0dXM6IFwib3BlblwiIH0sXG5cdFx0XHRcdCk7XG5cdFx0XHR9LFxuXHRcdFx0KGVycm9yOiB1bmtub3duKSA9PiB7XG5cdFx0XHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0c2V0U3RhdGUoe1xuXHRcdFx0XHRcdHN0YXR1czogXCJmYWlsZWRcIixcblx0XHRcdFx0XHRsYXN0RXZlbnQ6IG51bGwsXG5cdFx0XHRcdFx0dGVybWluYWw6IG51bGwsXG5cdFx0XHRcdFx0ZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSxcblx0XHRcdFx0fSk7XG5cdFx0XHR9LFxuXHRcdCk7XG5cdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdGNhbmNlbGxlZCA9IHRydWU7XG5cdFx0XHRoYW5kbGU/LmNsb3NlKCk7XG5cdFx0fTtcblx0fSwgW29wZW4sIGtleV0pO1xuXG5cdHJldHVybiBzdGF0ZTtcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7QUFnQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFxQk8sTUFBTSxnQ0FBZ0MsY0FBYTtBQUFBLEVBQ2xELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQ25DLE1BQU0sU0FBUyxlQUFlO0FBQUE7QUFFaEM7QUFFQSxJQUFNLGdCQUFnQixjQUFtQyxJQUFJO0FBd0J0RCxTQUFTLGNBQWMsQ0FBQyxPQUEwQztBQUFBLEVBQ3hFLFFBQVEsUUFBUSxXQUFXLFNBQVMsYUFBYTtBQUFBLEVBQ2pELElBQUssV0FBVyxlQUFnQixjQUFjLFlBQVk7QUFBQSxJQUN6RCxNQUFNLElBQUks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O0FBQUEsTUFDakIsU0FBUyxXQUFXO0FBQUEsTUFDcEI7QUFBQSxJQUNEO0FBQUEsSUFDQSxNQUFNLFVBQVUsU0FBUztBQUFBLElBQ3pCLElBQUksWUFBWTtBQUFBLElBQ2hCLElBQUksU0FBa0M7QUFBQSxJQUN0QyxTQUFTO0FBQUEsTUFDUixRQUFRO0FBQUEsTUFDUixXQUFXO0FBQUEsTUFDWCxVQUFVO0FBQUEsTUFDVixPQUFPO0FBQUEsSUFDUixDQUFDO0FBQUEsSUFDRCxLQUFLLFNBQVM7QUFBQSxNQUNiLFNBQVMsQ0FBQyxVQUFVO0FBQUEsUUFDbkIsSUFBSSxXQUFXO0FBQUEsVUFDZDtBQUFBLFFBQ0Q7QUFBQSxRQUNBLE9BQU8sUUFBUSxVQUFVLEtBQUs7QUFBQSxRQUM5QixTQUFTLENBQUMsY0FBYyxLQUFLLFVBQVUsV0FBVyxNQUFNLEVBQUU7QUFBQTtBQUFBLE1BRTNELFlBQVksQ0FBQyxhQUFhO0FBQUEsUUFDekIsSUFBSSxXQUFXO0FBQUEsVUFDZDtBQUFBLFFBQ0Q7QUFBQSxRQUNBLE9BQU8sUUFBUSxhQUFhLFFBQVE7QUFBQSxRQUNwQyxTQUFTLENBQUMsY0FBYyxLQUFLLFVBQVUsUUFBUSxTQUFTLFNBQVMsRUFBRTtBQUFBO0FBQUEsSUFFckUsQ0FBQyxFQUFFLEtBQ0YsQ0FBQyxXQUFXO0FBQUEsTUFDWCxJQUFJLFdBQVc7QUFBQSxRQUNkLE9BQU8sTUFBTTtBQUFBLFFBQ2I7QUFBQSxNQUNEO0FBQUEsTUFDQSxTQUFTO0FBQUEsTUFDVCxTQUFTLENBQUMsYUFDVCxTQUFTLFdBQVcsVUFDakIsV0FDQSxLQUFLLFVBQVUsUUFBUSxPQUFPLENBQ2xDO0FBQUEsT0FFRCxDQUFDLFVBQW1CO0FBQUEsTUFDbkIsSUFBSSxXQUFXO0FBQUEsUUFDZDtBQUFBLE1BQ0Q7QUFBQSxNQUNBLFNBQVM7QUFBQSxRQUNSLFFBQVE7QUFBQSxRQUNSLFdBQVc7QUFBQSxRQUNYLFVBQVU7QUFBQSxRQUNWLE9BQU8saUJBQWlCLFFBQVEsUUFBUSxJQUFJLE1BQU0sT0FBTyxLQUFLLENBQUM7QUFBQSxNQUNoRSxDQUFDO0FBQUEsS0FFSDtBQUFBLElBQ0EsT0FBTyxNQUFNO0FBQUEsTUFDWixZQUFZO0FBQUEsTUFDWixRQUFRLE1BQU07QUFBQTtBQUFBLEtBRWIsQ0FBQyxNQUFNLEdBQUcsQ0FBQztBQUFBLEVBRWQsT0FBTztBQUFBOyIsCiAgImRlYnVnSWQiOiAiQjkxNzMxMTZEMEE4QUQ0MzY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=