@garrix82/reactgenie-lib 1.3.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/.env.example +22 -0
- package/.github/workflows/publish.yml +20 -0
- package/LICENSE.txt +201 -0
- package/README.md +621 -0
- package/babel.config.js +29 -0
- package/dist/adapters/__tests__/expo-router-adapter.test.d.ts +1 -0
- package/dist/adapters/expo-router-adapter.d.ts +16 -0
- package/dist/adapters/expo-router-adapter.js +521 -0
- package/dist/adapters/navigation-adapter.d.ts +20 -0
- package/dist/adapters/navigation-adapter.js +137 -0
- package/dist/audio-visualizer.d.ts +14 -0
- package/dist/audio-visualizer.js +123 -0
- package/dist/current-selection.d.ts +27 -0
- package/dist/current-selection.js +94 -0
- package/dist/errors.d.ts +19 -0
- package/dist/errors.js +37 -0
- package/dist/genie/DateTime.d.ts +66 -0
- package/dist/genie/DateTime.js +399 -0
- package/dist/genie/TimeDelta.d.ts +35 -0
- package/dist/genie/TimeDelta.js +169 -0
- package/dist/genie-view-wrapper.d.ts +1 -0
- package/dist/genie-view-wrapper.js +377 -0
- package/dist/hooks/__tests__/useSpeechRecognition.test.d.ts +1 -0
- package/dist/hooks/useSpeechRecognition.d.ts +28 -0
- package/dist/hooks/useSpeechRecognition.js +118 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +469 -0
- package/dist/logger.d.ts +23 -0
- package/dist/logger.js +597 -0
- package/dist/logger.remote.test.d.ts +0 -0
- package/dist/modality-provider-v2.d.ts +28 -0
- package/dist/modality-provider-v2.js +1321 -0
- package/dist/modality-provider.d.ts +22 -0
- package/dist/modality-provider.js +373 -0
- package/dist/native-visibility.d.ts +28 -0
- package/dist/native-visibility.js +50 -0
- package/dist/platform/VoiceRecognitionBar.d.ts +17 -0
- package/dist/platform/VoiceRecognitionBar.js +332 -0
- package/dist/platform/components.d.ts +32 -0
- package/dist/platform/components.js +351 -0
- package/dist/platform/events.d.ts +31 -0
- package/dist/platform/events.js +274 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +39 -0
- package/dist/platform/types.d.ts +79 -0
- package/dist/platform/types.js +97 -0
- package/dist/react-decorators.d.ts +87 -0
- package/dist/react-decorators.js +368 -0
- package/dist/shared-store.d.ts +74 -0
- package/dist/shared-store.js +589 -0
- package/dist/speech-recognition/__tests__/speech-recognition-groq-transport.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified-import.test.d.ts +0 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified.test.d.ts +1 -0
- package/dist/speech-recognition/speech-recognition-groq.d.ts +21 -0
- package/dist/speech-recognition/speech-recognition-groq.js +409 -0
- package/dist/speech-recognition/speech-recognition-mlx.d.ts +15 -0
- package/dist/speech-recognition/speech-recognition-mlx.js +393 -0
- package/dist/speech-recognition/speech-recognition-native.d.ts +24 -0
- package/dist/speech-recognition/speech-recognition-native.js +632 -0
- package/dist/speech-recognition/speech-recognition-openai-native.d.ts +40 -0
- package/dist/speech-recognition/speech-recognition-openai-native.js +653 -0
- package/dist/speech-recognition/speech-recognition-openai.d.ts +39 -0
- package/dist/speech-recognition/speech-recognition-openai.js +718 -0
- package/dist/speech-recognition/speech-recognition-unified.d.ts +93 -0
- package/dist/speech-recognition/speech-recognition-unified.js +589 -0
- package/dist/speech-recognition/utils/groq-transcription.d.ts +41 -0
- package/dist/speech-recognition/utils/groq-transcription.js +382 -0
- package/dist/speech-recognition.d.ts +7 -0
- package/dist/speech-recognition.js +61 -0
- package/dist/voice-pipeline-telemetry.d.ts +26 -0
- package/dist/voice-pipeline-telemetry.js +15 -0
- package/garrix82-reactgenie-lib-1.3.0.tgz +0 -0
- package/metro/index.js +3 -0
- package/metro/with-genie-registry.js +47 -0
- package/package.json +111 -0
- package/scripts/dry-run.js +23 -0
- package/scripts/generate-genie-registry.js +278 -0
- package/scripts/log-file-test.js +51 -0
- package/scripts/parse.js +26 -0
- package/scripts/prompt.js +19 -0
- package/scripts/set-script.js +200 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildQueryParamsFromNavState = buildQueryParamsFromNavState;
|
|
7
|
+
exports.getRegisteredRoutes = getRegisteredRoutes;
|
|
8
|
+
exports.getRouteMap = getRouteMap;
|
|
9
|
+
exports.isExpoRouterAvailable = isExpoRouterAvailable;
|
|
10
|
+
exports.registerGenieRoute = registerGenieRoute;
|
|
11
|
+
exports.useExpoRouterAdapter = useExpoRouterAdapter;
|
|
12
|
+
exports.useRegisterGenieRoute = useRegisterGenieRoute;
|
|
13
|
+
exports.withExpoRouterAdapter = withExpoRouterAdapter;
|
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
15
|
+
var _sharedStore = require("../shared-store");
|
|
16
|
+
var _reactgenieDsl = require("@garrix82/reactgenie-dsl");
|
|
17
|
+
var _logger = require("../logger");
|
|
18
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
19
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
20
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
21
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
23
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /**
|
|
24
|
+
* Expo Router Adapter for ReactGenie
|
|
25
|
+
*
|
|
26
|
+
* Automatically handles navigation compatibility between ReactGenie's
|
|
27
|
+
* programmatic navigation and expo-router's file-based routing.
|
|
28
|
+
*
|
|
29
|
+
* Routes are auto-discovered from the actual file paths where components are used,
|
|
30
|
+
* not inferred from component names.
|
|
31
|
+
*/
|
|
32
|
+
// Try to import expo-router dynamically (optional peer dependency)
|
|
33
|
+
let useRouter = null;
|
|
34
|
+
let useSegments = null;
|
|
35
|
+
let usePathname = null;
|
|
36
|
+
let useLocalSearchParams = null;
|
|
37
|
+
try {
|
|
38
|
+
const expoRouter = require('expo-router');
|
|
39
|
+
useRouter = expoRouter.useRouter;
|
|
40
|
+
useSegments = expoRouter.useSegments;
|
|
41
|
+
usePathname = expoRouter.usePathname;
|
|
42
|
+
useLocalSearchParams = expoRouter.useLocalSearchParams;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// expo-router not available, adapter will be no-op
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Route registration info with metadata for duplicate detection
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Internal function to reset navigation state
|
|
53
|
+
* Prevents infinite navigation loops by clearing navState after routing
|
|
54
|
+
*/
|
|
55
|
+
function resetGenieNavigation() {
|
|
56
|
+
(0, _reactgenieDsl.genieDispatch)(() => {
|
|
57
|
+
const reactGenieState = _reactgenieDsl.sharedState;
|
|
58
|
+
reactGenieState.navState = {
|
|
59
|
+
objectViewClassName: null,
|
|
60
|
+
objectConstructorParams: null,
|
|
61
|
+
queryIntent: null,
|
|
62
|
+
resultRef: null,
|
|
63
|
+
resultObjectType: null
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Auto-discovered route registry built from actual file paths
|
|
70
|
+
* Maps decorator class names to their actual route file locations
|
|
71
|
+
*
|
|
72
|
+
* Key: View class name (e.g., "CounterView")
|
|
73
|
+
* Value: Route registration info with path and duplicate detection
|
|
74
|
+
*/
|
|
75
|
+
const AUTO_ROUTE_REGISTRY = new Map();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Extract dynamic segment names from an expo-router path.
|
|
79
|
+
* Examples:
|
|
80
|
+
* - /probes/[probeId] -> ["probeId"]
|
|
81
|
+
* - /files/[...path] -> ["path"]
|
|
82
|
+
* - /blog/[[...slug]] -> ["slug"]
|
|
83
|
+
*/
|
|
84
|
+
function getDynamicParamNames(routePath) {
|
|
85
|
+
if (!routePath) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Normalize optional catch-all segments: [[...slug]] -> [...slug]
|
|
90
|
+
const normalized = routePath.replace(/\[\[/g, '[').replace(/\]\]/g, ']');
|
|
91
|
+
const matches = normalized.match(/\[([^\]]+)\]/g) || [];
|
|
92
|
+
return matches.map(segment => segment.slice(1, -1).replace(/^\.\.\./, '')).filter(name => name.length > 0);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Keep only params that map to dynamic segments in the route path.
|
|
97
|
+
* This prevents extra Genie params from becoming query strings.
|
|
98
|
+
*/
|
|
99
|
+
function filterParamsForRoute(routePath, params) {
|
|
100
|
+
if (!params || typeof params !== 'object') {
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
const paramNames = getDynamicParamNames(routePath);
|
|
104
|
+
if (paramNames.length === 0) {
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
const filtered = {};
|
|
108
|
+
for (const name of paramNames) {
|
|
109
|
+
if (params[name] !== undefined && params[name] !== null) {
|
|
110
|
+
filtered[name] = params[name];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return filtered;
|
|
114
|
+
}
|
|
115
|
+
function sanitizeFieldName(field) {
|
|
116
|
+
return field.replace(/[^a-zA-Z0-9_.-]/g, '_');
|
|
117
|
+
}
|
|
118
|
+
function toQueryParamValue(value) {
|
|
119
|
+
if (value === null || value === undefined) return null;
|
|
120
|
+
if (typeof value === 'string') return value;
|
|
121
|
+
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function setQueryParam(params, key, value) {
|
|
125
|
+
const normalized = toQueryParamValue(value);
|
|
126
|
+
if (normalized === null) return;
|
|
127
|
+
let candidate = key;
|
|
128
|
+
let i = 1;
|
|
129
|
+
while (params[candidate] !== undefined) {
|
|
130
|
+
candidate = `${key}_${i}`;
|
|
131
|
+
i += 1;
|
|
132
|
+
}
|
|
133
|
+
params[candidate] = normalized;
|
|
134
|
+
}
|
|
135
|
+
function buildQueryParamsFromNavState(navState) {
|
|
136
|
+
const params = {};
|
|
137
|
+
if (navState.resultRef) {
|
|
138
|
+
params.rg_result = String(navState.resultRef);
|
|
139
|
+
}
|
|
140
|
+
if (navState.queryIntent?.hash) {
|
|
141
|
+
params.rg_qh = navState.queryIntent.hash;
|
|
142
|
+
}
|
|
143
|
+
const ops = navState.queryIntent?.ops ?? [];
|
|
144
|
+
for (const op of ops) {
|
|
145
|
+
if (op.kind === 'matching' || op.kind === 'contains' || op.kind === 'equals') {
|
|
146
|
+
setQueryParam(params, `q_${op.kind}_${sanitizeFieldName(op.field)}`, op.value);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (op.kind === 'between') {
|
|
150
|
+
setQueryParam(params, `q_between_${sanitizeFieldName(op.field)}_from`, op.from);
|
|
151
|
+
setQueryParam(params, `q_between_${sanitizeFieldName(op.field)}_to`, op.to);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (op.kind === 'sort') {
|
|
155
|
+
setQueryParam(params, 'q_sort', `${sanitizeFieldName(op.field)}:${op.ascending ? 'asc' : 'desc'}`);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (op.kind === 'index') {
|
|
159
|
+
setQueryParam(params, 'q_index', op.value);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (op.kind === 'length') {
|
|
163
|
+
setQueryParam(params, 'q_length', 'true');
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return Object.keys(params).sort((a, b) => a.localeCompare(b)).reduce((acc, key) => {
|
|
168
|
+
acc[key] = params[key];
|
|
169
|
+
return acc;
|
|
170
|
+
}, {});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Type guard to check if a view class name has already been registered
|
|
175
|
+
*/
|
|
176
|
+
function isViewClassRegistered(viewClassName) {
|
|
177
|
+
return AUTO_ROUTE_REGISTRY.has(viewClassName);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get registration info for a view class (for error messages)
|
|
182
|
+
*/
|
|
183
|
+
function getRegistrationInfo(viewClassName) {
|
|
184
|
+
return AUTO_ROUTE_REGISTRY.get(viewClassName);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Generate unique view class name for dynamic routes
|
|
189
|
+
*
|
|
190
|
+
* Handles dynamic segments by appending normalized segment names:
|
|
191
|
+
* - /probes → "ProbeView"
|
|
192
|
+
* - /probes/[id] → "ProbeView_id"
|
|
193
|
+
* - /probes/[id]/edit → "ProbeView_id_edit"
|
|
194
|
+
* - /probes/[slug]/comments/[commentId] → "ProbeView_slug_comments_commentId"
|
|
195
|
+
*
|
|
196
|
+
* @param baseClassName - The base view class name (e.g., "ProbeView")
|
|
197
|
+
* @param routePath - The route path (e.g., "/probes/[id]")
|
|
198
|
+
* @returns Unique view class name
|
|
199
|
+
*/
|
|
200
|
+
function generateUniqueViewClassName(baseClassName, routePath) {
|
|
201
|
+
// Extract dynamic segments: [id], [slug], etc.
|
|
202
|
+
const dynamicSegments = routePath.match(/\[([^\]]+)\]/g);
|
|
203
|
+
if (!dynamicSegments || dynamicSegments.length === 0) {
|
|
204
|
+
// No dynamic segments, return base name
|
|
205
|
+
return baseClassName;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Remove brackets and join with underscore
|
|
209
|
+
// [id] → id, [slug] → slug
|
|
210
|
+
const segmentNames = dynamicSegments.map(seg => seg.replace(/[\[\]]/g, '')).join('_');
|
|
211
|
+
return `${baseClassName}_${segmentNames}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Registers a route with its actual file path from expo-router
|
|
216
|
+
*
|
|
217
|
+
* This should be called from route files (app directory), not from component files.
|
|
218
|
+
* The route path is auto-discovered from the file location.
|
|
219
|
+
*
|
|
220
|
+
* **Duplicate Detection**: If a view class is already registered to a different route,
|
|
221
|
+
* a runtime error will be thrown with details about both registrations.
|
|
222
|
+
*
|
|
223
|
+
* @param viewClassName - The name of the view class being rendered on this route
|
|
224
|
+
* @param routePath - Optional explicit path, otherwise auto-discovered from current route
|
|
225
|
+
*
|
|
226
|
+
* @throws Error if viewClassName is already registered to a different route
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* // In app/genie/counter.tsx
|
|
230
|
+
* import { useRegisterGenieRoute } from '@garrix82/reactgenie-lib';
|
|
231
|
+
*
|
|
232
|
+
* export default function CounterRoute() {
|
|
233
|
+
* useRegisterGenieRoute('CounterView'); // Auto-discovers: /genie/counter
|
|
234
|
+
* return <CounterView />;
|
|
235
|
+
* }
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* // Dynamic route: app/genie/[id].tsx
|
|
239
|
+
* export default function DynamicCounterRoute() {
|
|
240
|
+
* useRegisterGenieRoute('CounterView'); // Auto-discovers: /genie/[id]
|
|
241
|
+
* return <CounterView />;
|
|
242
|
+
* }
|
|
243
|
+
*/
|
|
244
|
+
function useRegisterGenieRoute(baseViewClassName, routePath) {
|
|
245
|
+
// Only works if expo-router is available
|
|
246
|
+
if (!usePathname) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const pathname = usePathname();
|
|
250
|
+
(0, _react.useEffect)(() => {
|
|
251
|
+
const path = routePath || pathname;
|
|
252
|
+
if (path && baseViewClassName) {
|
|
253
|
+
// Generate unique view class name for dynamic routes
|
|
254
|
+
const viewClassName = generateUniqueViewClassName(baseViewClassName, path);
|
|
255
|
+
const existingRegistration = getRegistrationInfo(viewClassName);
|
|
256
|
+
|
|
257
|
+
// Auto registry already owns this view class; ignore runtime registration.
|
|
258
|
+
if (existingRegistration && existingRegistration.source === "auto") {
|
|
259
|
+
if (routePath && existingRegistration.routePath !== path) {
|
|
260
|
+
console.warn(`[ReactGenie] Skipping runtime registration for "${viewClassName}" ` + `(${path}). Auto registry already mapped it to "${existingRegistration.routePath}".`);
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Check for duplicate runtime registration
|
|
266
|
+
if (existingRegistration && existingRegistration.routePath !== path) {
|
|
267
|
+
const errorMsg = `[ReactGenie] ERROR: Duplicate registration detected!\n` + `View class "${viewClassName}" is already registered.\n\n` + `Existing registration:\n` + ` Route: ${existingRegistration.routePath}\n` + ` File: ${existingRegistration.registeredAt}\n\n` + `New registration attempt:\n` + ` Route: ${path}\n\n` + `Each view class can only be registered to ONE route.\n` + `Please use a different view class name for the second route,\n` + `or remove one of the registrations.`;
|
|
268
|
+
console.error(errorMsg);
|
|
269
|
+
throw new Error(errorMsg);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Register the route with metadata
|
|
273
|
+
AUTO_ROUTE_REGISTRY.set(viewClassName, {
|
|
274
|
+
viewClassName,
|
|
275
|
+
routePath: path,
|
|
276
|
+
registeredAt: path,
|
|
277
|
+
// Use pathname as "file location"
|
|
278
|
+
source: "runtime"
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// console.log(`[ReactGenie] Registered route: ${viewClassName} → ${path}`);
|
|
282
|
+
}
|
|
283
|
+
}, [baseViewClassName, pathname, routePath]);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Alternative: Register route without hook (for use outside React components)
|
|
288
|
+
*
|
|
289
|
+
* **Duplicate Detection**: Throws error if view class already registered to different route.
|
|
290
|
+
*
|
|
291
|
+
* @param viewClassName - The name of the view class
|
|
292
|
+
* @param routePath - The file-based route path where this view is used
|
|
293
|
+
* @throws Error if viewClassName is already registered to a different route
|
|
294
|
+
*/
|
|
295
|
+
function registerGenieRoute(viewClassName, routePath) {
|
|
296
|
+
// Check for duplicate registration
|
|
297
|
+
const existingRegistration = getRegistrationInfo(viewClassName);
|
|
298
|
+
if (existingRegistration && existingRegistration.routePath !== routePath) {
|
|
299
|
+
const errorMsg = `[ReactGenie] ERROR: Duplicate registration detected!\n` + `View class "${viewClassName}" is already registered.\n\n` + `Existing registration:\n` + ` Route: ${existingRegistration.routePath}\n` + ` File: ${existingRegistration.registeredAt}\n\n` + `New registration attempt:\n` + ` Route: ${routePath}\n\n` + `Each view class can only be registered to ONE route.\n` + `Please use a different view class name for the second route,\n` + `or remove one of the registrations.`;
|
|
300
|
+
console.error(errorMsg);
|
|
301
|
+
throw new Error(errorMsg);
|
|
302
|
+
}
|
|
303
|
+
AUTO_ROUTE_REGISTRY.set(viewClassName, {
|
|
304
|
+
viewClassName,
|
|
305
|
+
routePath,
|
|
306
|
+
registeredAt: routePath,
|
|
307
|
+
source: "auto"
|
|
308
|
+
});
|
|
309
|
+
// console.log(`[ReactGenie] Registered route: ${viewClassName} → ${routePath}`);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Gets the route path for a view class name
|
|
314
|
+
*/
|
|
315
|
+
function getRouteForView(viewClassName) {
|
|
316
|
+
const registration = AUTO_ROUTE_REGISTRY.get(viewClassName);
|
|
317
|
+
return registration?.routePath || null;
|
|
318
|
+
}
|
|
319
|
+
function splitRouteSegments(path) {
|
|
320
|
+
if (!path || path === '/') {
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
return path.split('/').filter(segment => segment.length > 0);
|
|
324
|
+
}
|
|
325
|
+
function isDynamicSegment(segment) {
|
|
326
|
+
return segment.startsWith('[') && segment.endsWith(']');
|
|
327
|
+
}
|
|
328
|
+
function isCatchAllSegment(segment) {
|
|
329
|
+
return segment.startsWith('[...') && segment.endsWith(']');
|
|
330
|
+
}
|
|
331
|
+
function isOptionalCatchAllSegment(segment) {
|
|
332
|
+
return segment.startsWith('[[...') && segment.endsWith(']]');
|
|
333
|
+
}
|
|
334
|
+
function routeTemplateMatchesPath(routeTemplate, pathname) {
|
|
335
|
+
const templateSegments = splitRouteSegments(routeTemplate);
|
|
336
|
+
const pathSegments = splitRouteSegments(pathname);
|
|
337
|
+
let templateIndex = 0;
|
|
338
|
+
let pathIndex = 0;
|
|
339
|
+
while (templateIndex < templateSegments.length) {
|
|
340
|
+
const templateSegment = templateSegments[templateIndex];
|
|
341
|
+
if (isOptionalCatchAllSegment(templateSegment)) {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
if (isCatchAllSegment(templateSegment)) {
|
|
345
|
+
return pathIndex < pathSegments.length;
|
|
346
|
+
}
|
|
347
|
+
const pathSegment = pathSegments[pathIndex];
|
|
348
|
+
if (pathSegment === undefined) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
if (isDynamicSegment(templateSegment)) {
|
|
352
|
+
templateIndex += 1;
|
|
353
|
+
pathIndex += 1;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (templateSegment !== pathSegment) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
templateIndex += 1;
|
|
360
|
+
pathIndex += 1;
|
|
361
|
+
}
|
|
362
|
+
return pathIndex === pathSegments.length;
|
|
363
|
+
}
|
|
364
|
+
function getRouteSpecificity(routeTemplate) {
|
|
365
|
+
const segments = splitRouteSegments(routeTemplate);
|
|
366
|
+
const staticSegments = segments.filter(segment => !isDynamicSegment(segment)).length;
|
|
367
|
+
return staticSegments * 100 + segments.length;
|
|
368
|
+
}
|
|
369
|
+
function getCurrentRouteTemplate(pathname) {
|
|
370
|
+
const candidates = [];
|
|
371
|
+
AUTO_ROUTE_REGISTRY.forEach(info => {
|
|
372
|
+
if (routeTemplateMatchesPath(info.routePath, pathname)) {
|
|
373
|
+
candidates.push(info.routePath);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
if (candidates.length === 0) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
candidates.sort((a, b) => getRouteSpecificity(b) - getRouteSpecificity(a));
|
|
380
|
+
return candidates[0];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Hook that automatically intercepts ReactGenie navigation and routes via expo-router
|
|
385
|
+
*
|
|
386
|
+
* Routes are auto-discovered from where components are actually used, not inferred.
|
|
387
|
+
*
|
|
388
|
+
* Usage: Import and call in your root _layout.tsx (inside Provider context):
|
|
389
|
+
* ```tsx
|
|
390
|
+
* import { useExpoRouterAdapter } from '@garrix82/reactgenie-lib';
|
|
391
|
+
*
|
|
392
|
+
* function RootLayoutContent() {
|
|
393
|
+
* useExpoRouterAdapter(); // <- Add this line
|
|
394
|
+
* // ... rest of layout
|
|
395
|
+
* }
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
function useExpoRouterAdapter() {
|
|
399
|
+
// Check if expo-router is available
|
|
400
|
+
if (!useRouter || !useSegments) {
|
|
401
|
+
// No expo-router, navigation will fall back to react-navigation
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
const router = useRouter();
|
|
405
|
+
const pathname = usePathname ? usePathname() : '';
|
|
406
|
+
const localSearchParams = useLocalSearchParams ? useLocalSearchParams() : {};
|
|
407
|
+
const navState = (0, _sharedStore.useGenieSelector)(state => state.navState);
|
|
408
|
+
const navStack = (0, _sharedStore.useGenieSelector)(state => state.navStack);
|
|
409
|
+
const lastHandledNavStackRef = (0, _react.useRef)(0);
|
|
410
|
+
(0, _react.useEffect)(() => {
|
|
411
|
+
if (!navState?.objectViewClassName) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (navStack <= lastHandledNavStackRef.current) {
|
|
415
|
+
_logger.logger.debug(`[ReactGenieNav] reason=ignored_duplicate_event navStack=${navStack} lastHandled=${lastHandledNavStackRef.current}`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const eventId = navStack;
|
|
419
|
+
const viewClassName = navState.objectViewClassName;
|
|
420
|
+
const params = navState.objectConstructorParams;
|
|
421
|
+
try {
|
|
422
|
+
const routePath = getRouteForView(viewClassName);
|
|
423
|
+
if (!routePath) {
|
|
424
|
+
_logger.logger.warn(`[ReactGenieNav] reason=skipped_unregistered_view event=${eventId} view=${viewClassName}`);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
_logger.logger.debug(`[ReactGenie] Auto-routing: ${viewClassName} → ${routePath}`);
|
|
428
|
+
_logger.logger.debug(`[ReactGenie] Navigation params:`, params);
|
|
429
|
+
const routeParams = filterParamsForRoute(routePath, params);
|
|
430
|
+
const queryParams = buildQueryParamsFromNavState(navState);
|
|
431
|
+
const dynamicParamNames = getDynamicParamNames(routePath);
|
|
432
|
+
const missingParams = dynamicParamNames.filter(name => routeParams[name] === undefined || routeParams[name] === null);
|
|
433
|
+
if (dynamicParamNames.length > 0 && missingParams.length > 0) {
|
|
434
|
+
_logger.logger.warn(`[ReactGenieNav] reason=skipped_missing_params event=${eventId} view=${viewClassName} missing=${missingParams.join(',')}`);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const activeTemplate = getCurrentRouteTemplate(pathname || '');
|
|
438
|
+
const dynamicParamsUnchanged = dynamicParamNames.every(name => {
|
|
439
|
+
const current = Array.isArray(localSearchParams?.[name]) ? localSearchParams[name][0] : localSearchParams?.[name];
|
|
440
|
+
return String(current ?? '') === String(routeParams[name] ?? '');
|
|
441
|
+
});
|
|
442
|
+
const shouldReplace = activeTemplate !== null && activeTemplate === routePath && dynamicParamsUnchanged;
|
|
443
|
+
const destinationParams = _objectSpread(_objectSpread({}, routeParams), queryParams);
|
|
444
|
+
const hasParams = Object.keys(destinationParams).length > 0;
|
|
445
|
+
if (hasParams) {
|
|
446
|
+
const destination = {
|
|
447
|
+
pathname: routePath,
|
|
448
|
+
params: destinationParams
|
|
449
|
+
};
|
|
450
|
+
if (shouldReplace && typeof router.replace === 'function') {
|
|
451
|
+
router.replace(destination);
|
|
452
|
+
} else {
|
|
453
|
+
router.push(destination);
|
|
454
|
+
}
|
|
455
|
+
} else if (shouldReplace && typeof router.replace === 'function') {
|
|
456
|
+
router.replace(routePath);
|
|
457
|
+
} else {
|
|
458
|
+
router.push(routePath);
|
|
459
|
+
}
|
|
460
|
+
_logger.logger.info(`[ReactGenieNav] reason=${shouldReplace ? 'handled_replace' : 'handled_push'} event=${eventId} view=${viewClassName} route=${routePath}`);
|
|
461
|
+
} catch (error) {
|
|
462
|
+
console.error(`[ReactGenie] Navigation error:`, error);
|
|
463
|
+
} finally {
|
|
464
|
+
lastHandledNavStackRef.current = eventId;
|
|
465
|
+
// Reset navigation state to prevent infinite loops after handling this event.
|
|
466
|
+
resetGenieNavigation();
|
|
467
|
+
}
|
|
468
|
+
}, [navStack, navState, pathname, localSearchParams, router]);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Higher-order component that wraps your root layout with expo-router adapter
|
|
473
|
+
*
|
|
474
|
+
* Usage:
|
|
475
|
+
* ```tsx
|
|
476
|
+
* import { withExpoRouterAdapter } from '@garrix82/reactgenie-lib';
|
|
477
|
+
*
|
|
478
|
+
* function RootLayout() {
|
|
479
|
+
* return (
|
|
480
|
+
* <Provider store={reactGenieStore}>
|
|
481
|
+
* <Stack>...</Stack>
|
|
482
|
+
* </Provider>
|
|
483
|
+
* );
|
|
484
|
+
* }
|
|
485
|
+
*
|
|
486
|
+
* export default withExpoRouterAdapter(RootLayout);
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
function withExpoRouterAdapter(Component) {
|
|
490
|
+
return function ExpoRouterAdapterWrapper(props) {
|
|
491
|
+
useExpoRouterAdapter();
|
|
492
|
+
return /*#__PURE__*/_react.default.createElement(Component, props);
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Utility to check if expo-router is available
|
|
498
|
+
*/
|
|
499
|
+
function isExpoRouterAvailable() {
|
|
500
|
+
return useRouter !== null && useSegments !== null;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Get all registered routes (for debugging)
|
|
505
|
+
* Returns a copy of the registration map with full metadata
|
|
506
|
+
*/
|
|
507
|
+
function getRegisteredRoutes() {
|
|
508
|
+
return new Map(AUTO_ROUTE_REGISTRY);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Get simple route map (viewClassName → routePath) for debugging
|
|
513
|
+
*/
|
|
514
|
+
function getRouteMap() {
|
|
515
|
+
const simpleMap = new Map();
|
|
516
|
+
AUTO_ROUTE_REGISTRY.forEach((info, viewClassName) => {
|
|
517
|
+
simpleMap.set(viewClassName, info.routePath);
|
|
518
|
+
});
|
|
519
|
+
return simpleMap;
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc2hhcmVkU3RvcmUiLCJfcmVhY3RnZW5pZURzbCIsIl9sb2dnZXIiLCJlIiwidCIsIldlYWtNYXAiLCJyIiwibiIsIl9fZXNNb2R1bGUiLCJvIiwiaSIsImYiLCJfX3Byb3RvX18iLCJkZWZhdWx0IiwiaGFzIiwiZ2V0Iiwic2V0IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiX3RvUHJvcGVydHlLZXkiLCJ2YWx1ZSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiX3RvUHJpbWl0aXZlIiwiU3ltYm9sIiwidG9QcmltaXRpdmUiLCJUeXBlRXJyb3IiLCJTdHJpbmciLCJOdW1iZXIiLCJ1c2VSb3V0ZXIiLCJ1c2VTZWdtZW50cyIsInVzZVBhdGhuYW1lIiwidXNlTG9jYWxTZWFyY2hQYXJhbXMiLCJleHBvUm91dGVyIiwicmVzZXRHZW5pZU5hdmlnYXRpb24iLCJnZW5pZURpc3BhdGNoIiwicmVhY3RHZW5pZVN0YXRlIiwic2hhcmVkU3RhdGUiLCJuYXZTdGF0ZSIsIm9iamVjdFZpZXdDbGFzc05hbWUiLCJvYmplY3RDb25zdHJ1Y3RvclBhcmFtcyIsInF1ZXJ5SW50ZW50IiwicmVzdWx0UmVmIiwicmVzdWx0T2JqZWN0VHlwZSIsIkFVVE9fUk9VVEVfUkVHSVNUUlkiLCJNYXAiLCJnZXREeW5hbWljUGFyYW1OYW1lcyIsInJvdXRlUGF0aCIsIm5vcm1hbGl6ZWQiLCJyZXBsYWNlIiwibWF0Y2hlcyIsIm1hdGNoIiwibWFwIiwic2VnbWVudCIsInNsaWNlIiwibmFtZSIsImZpbHRlclBhcmFtc0ZvclJvdXRlIiwicGFyYW1zIiwicGFyYW1OYW1lcyIsImZpbHRlcmVkIiwidW5kZWZpbmVkIiwic2FuaXRpemVGaWVsZE5hbWUiLCJmaWVsZCIsInRvUXVlcnlQYXJhbVZhbHVlIiwic2V0UXVlcnlQYXJhbSIsImtleSIsImNhbmRpZGF0ZSIsImJ1aWxkUXVlcnlQYXJhbXNGcm9tTmF2U3RhdGUiLCJyZ19yZXN1bHQiLCJoYXNoIiwicmdfcWgiLCJvcHMiLCJvcCIsImtpbmQiLCJmcm9tIiwidG8iLCJhc2NlbmRpbmciLCJzb3J0IiwiYSIsImIiLCJsb2NhbGVDb21wYXJlIiwicmVkdWNlIiwiYWNjIiwiaXNWaWV3Q2xhc3NSZWdpc3RlcmVkIiwidmlld0NsYXNzTmFtZSIsImdldFJlZ2lzdHJhdGlvbkluZm8iLCJnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUiLCJiYXNlQ2xhc3NOYW1lIiwiZHluYW1pY1NlZ21lbnRzIiwic2VnbWVudE5hbWVzIiwic2VnIiwiam9pbiIsInVzZVJlZ2lzdGVyR2VuaWVSb3V0ZSIsImJhc2VWaWV3Q2xhc3NOYW1lIiwicGF0aG5hbWUiLCJ1c2VFZmZlY3QiLCJwYXRoIiwiZXhpc3RpbmdSZWdpc3RyYXRpb24iLCJzb3VyY2UiLCJjb25zb2xlIiwid2FybiIsImVycm9yTXNnIiwicmVnaXN0ZXJlZEF0IiwiZXJyb3IiLCJFcnJvciIsInJlZ2lzdGVyR2VuaWVSb3V0ZSIsImdldFJvdXRlRm9yVmlldyIsInJlZ2lzdHJhdGlvbiIsInNwbGl0Um91dGVTZWdtZW50cyIsInNwbGl0IiwiaXNEeW5hbWljU2VnbWVudCIsInN0YXJ0c1dpdGgiLCJlbmRzV2l0aCIsImlzQ2F0Y2hBbGxTZWdtZW50IiwiaXNPcHRpb25hbENhdGNoQWxsU2VnbWVudCIsInJvdXRlVGVtcGxhdGVNYXRjaGVzUGF0aCIsInJvdXRlVGVtcGxhdGUiLCJ0ZW1wbGF0ZVNlZ21lbnRzIiwicGF0aFNlZ21lbnRzIiwidGVtcGxhdGVJbmRleCIsInBhdGhJbmRleCIsInRlbXBsYXRlU2VnbWVudCIsInBhdGhTZWdtZW50IiwiZ2V0Um91dGVTcGVjaWZpY2l0eSIsInNlZ21lbnRzIiwic3RhdGljU2VnbWVudHMiLCJnZXRDdXJyZW50Um91dGVUZW1wbGF0ZSIsImNhbmRpZGF0ZXMiLCJpbmZvIiwidXNlRXhwb1JvdXRlckFkYXB0ZXIiLCJyb3V0ZXIiLCJsb2NhbFNlYXJjaFBhcmFtcyIsInVzZUdlbmllU2VsZWN0b3IiLCJzdGF0ZSIsIm5hdlN0YWNrIiwibGFzdEhhbmRsZWROYXZTdGFja1JlZiIsInVzZVJlZiIsImN1cnJlbnQiLCJsb2dnZXIiLCJkZWJ1ZyIsImV2ZW50SWQiLCJyb3V0ZVBhcmFtcyIsInF1ZXJ5UGFyYW1zIiwiZHluYW1pY1BhcmFtTmFtZXMiLCJtaXNzaW5nUGFyYW1zIiwiYWN0aXZlVGVtcGxhdGUiLCJkeW5hbWljUGFyYW1zVW5jaGFuZ2VkIiwiZXZlcnkiLCJBcnJheSIsImlzQXJyYXkiLCJzaG91bGRSZXBsYWNlIiwiZGVzdGluYXRpb25QYXJhbXMiLCJoYXNQYXJhbXMiLCJkZXN0aW5hdGlvbiIsIndpdGhFeHBvUm91dGVyQWRhcHRlciIsIkNvbXBvbmVudCIsIkV4cG9Sb3V0ZXJBZGFwdGVyV3JhcHBlciIsInByb3BzIiwiY3JlYXRlRWxlbWVudCIsImlzRXhwb1JvdXRlckF2YWlsYWJsZSIsImdldFJlZ2lzdGVyZWRSb3V0ZXMiLCJnZXRSb3V0ZU1hcCIsInNpbXBsZU1hcCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9leHBvLXJvdXRlci1hZGFwdGVyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4cG8gUm91dGVyIEFkYXB0ZXIgZm9yIFJlYWN0R2VuaWVcbiAqIFxuICogQXV0b21hdGljYWxseSBoYW5kbGVzIG5hdmlnYXRpb24gY29tcGF0aWJpbGl0eSBiZXR3ZWVuIFJlYWN0R2VuaWUnc1xuICogcHJvZ3JhbW1hdGljIG5hdmlnYXRpb24gYW5kIGV4cG8tcm91dGVyJ3MgZmlsZS1iYXNlZCByb3V0aW5nLlxuICogXG4gKiBSb3V0ZXMgYXJlIGF1dG8tZGlzY292ZXJlZCBmcm9tIHRoZSBhY3R1YWwgZmlsZSBwYXRocyB3aGVyZSBjb21wb25lbnRzIGFyZSB1c2VkLFxuICogbm90IGluZmVycmVkIGZyb20gY29tcG9uZW50IG5hbWVzLlxuICovXG5cbmltcG9ydCBSZWFjdCwgeyB1c2VFZmZlY3QsIHVzZVJlZiB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZUdlbmllU2VsZWN0b3IgfSBmcm9tICcuLi9zaGFyZWQtc3RvcmUnO1xuaW1wb3J0IHsgZ2VuaWVEaXNwYXRjaCwgc2hhcmVkU3RhdGUgfSBmcm9tICdAZ2Fycml4ODIvcmVhY3RnZW5pZS1kc2wnO1xuaW1wb3J0IHR5cGUgeyBSZWFjdEdlbmllU3RhdGUsIE5hdmlnYXRvclN0YXRlIH0gZnJvbSAnLi4vc2hhcmVkLXN0b3JlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XG5cbi8vIFRyeSB0byBpbXBvcnQgZXhwby1yb3V0ZXIgZHluYW1pY2FsbHkgKG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSlcbmxldCB1c2VSb3V0ZXI6IGFueSA9IG51bGw7XG5sZXQgdXNlU2VnbWVudHM6IGFueSA9IG51bGw7XG5sZXQgdXNlUGF0aG5hbWU6IGFueSA9IG51bGw7XG5sZXQgdXNlTG9jYWxTZWFyY2hQYXJhbXM6IGFueSA9IG51bGw7XG5cbnRyeSB7XG4gIGNvbnN0IGV4cG9Sb3V0ZXIgPSByZXF1aXJlKCdleHBvLXJvdXRlcicpO1xuICB1c2VSb3V0ZXIgPSBleHBvUm91dGVyLnVzZVJvdXRlcjtcbiAgdXNlU2VnbWVudHMgPSBleHBvUm91dGVyLnVzZVNlZ21lbnRzO1xuICB1c2VQYXRobmFtZSA9IGV4cG9Sb3V0ZXIudXNlUGF0aG5hbWU7XG4gIHVzZUxvY2FsU2VhcmNoUGFyYW1zID0gZXhwb1JvdXRlci51c2VMb2NhbFNlYXJjaFBhcmFtcztcbn0gY2F0Y2ggKGUpIHtcbiAgLy8gZXhwby1yb3V0ZXIgbm90IGF2YWlsYWJsZSwgYWRhcHRlciB3aWxsIGJlIG5vLW9wXG59XG5cbi8qKlxuICogUm91dGUgcmVnaXN0cmF0aW9uIGluZm8gd2l0aCBtZXRhZGF0YSBmb3IgZHVwbGljYXRlIGRldGVjdGlvblxuICovXG5leHBvcnQgdHlwZSBSb3V0ZVJlZ2lzdHJhdGlvbkluZm8gPSB7XG4gIHJlYWRvbmx5IHZpZXdDbGFzc05hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcm91dGVQYXRoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlZ2lzdGVyZWRBdDogc3RyaW5nO1xuICByZWFkb25seSBzb3VyY2U6IFwiYXV0b1wiIHwgXCJydW50aW1lXCI7XG59O1xuXG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIHJlc2V0IG5hdmlnYXRpb24gc3RhdGVcbiAqIFByZXZlbnRzIGluZmluaXRlIG5hdmlnYXRpb24gbG9vcHMgYnkgY2xlYXJpbmcgbmF2U3RhdGUgYWZ0ZXIgcm91dGluZ1xuICovXG5mdW5jdGlvbiByZXNldEdlbmllTmF2aWdhdGlvbigpIHtcbiAgZ2VuaWVEaXNwYXRjaCgoKSA9PiB7XG4gICAgY29uc3QgcmVhY3RHZW5pZVN0YXRlID0gc2hhcmVkU3RhdGUgYXMgUmVhY3RHZW5pZVN0YXRlO1xuICAgIHJlYWN0R2VuaWVTdGF0ZS5uYXZTdGF0ZSA9IHtcbiAgICAgIG9iamVjdFZpZXdDbGFzc05hbWU6IG51bGwsXG4gICAgICBvYmplY3RDb25zdHJ1Y3RvclBhcmFtczogbnVsbCxcbiAgICAgIHF1ZXJ5SW50ZW50OiBudWxsLFxuICAgICAgcmVzdWx0UmVmOiBudWxsLFxuICAgICAgcmVzdWx0T2JqZWN0VHlwZTogbnVsbCxcbiAgICB9O1xuICB9KTtcbn1cblxuLyoqXG4gKiBBdXRvLWRpc2NvdmVyZWQgcm91dGUgcmVnaXN0cnkgYnVpbHQgZnJvbSBhY3R1YWwgZmlsZSBwYXRoc1xuICogTWFwcyBkZWNvcmF0b3IgY2xhc3MgbmFtZXMgdG8gdGhlaXIgYWN0dWFsIHJvdXRlIGZpbGUgbG9jYXRpb25zXG4gKiBcbiAqIEtleTogVmlldyBjbGFzcyBuYW1lIChlLmcuLCBcIkNvdW50ZXJWaWV3XCIpXG4gKiBWYWx1ZTogUm91dGUgcmVnaXN0cmF0aW9uIGluZm8gd2l0aCBwYXRoIGFuZCBkdXBsaWNhdGUgZGV0ZWN0aW9uXG4gKi9cbmNvbnN0IEFVVE9fUk9VVEVfUkVHSVNUUlkgPSBuZXcgTWFwPHN0cmluZywgUm91dGVSZWdpc3RyYXRpb25JbmZvPigpO1xuXG4vKipcbiAqIEV4dHJhY3QgZHluYW1pYyBzZWdtZW50IG5hbWVzIGZyb20gYW4gZXhwby1yb3V0ZXIgcGF0aC5cbiAqIEV4YW1wbGVzOlxuICogLSAvcHJvYmVzL1twcm9iZUlkXSAtPiBbXCJwcm9iZUlkXCJdXG4gKiAtIC9maWxlcy9bLi4ucGF0aF0gLT4gW1wicGF0aFwiXVxuICogLSAvYmxvZy9bWy4uLnNsdWddXSAtPiBbXCJzbHVnXCJdXG4gKi9cbmZ1bmN0aW9uIGdldER5bmFtaWNQYXJhbU5hbWVzKHJvdXRlUGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBpZiAoIXJvdXRlUGF0aCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBvcHRpb25hbCBjYXRjaC1hbGwgc2VnbWVudHM6IFtbLi4uc2x1Z11dIC0+IFsuLi5zbHVnXVxuICBjb25zdCBub3JtYWxpemVkID0gcm91dGVQYXRoLnJlcGxhY2UoL1xcW1xcWy9nLCAnWycpLnJlcGxhY2UoL1xcXVxcXS9nLCAnXScpO1xuICBjb25zdCBtYXRjaGVzID0gbm9ybWFsaXplZC5tYXRjaCgvXFxbKFteXFxdXSspXFxdL2cpIHx8IFtdO1xuXG4gIHJldHVybiBtYXRjaGVzXG4gICAgLm1hcCgoc2VnbWVudCkgPT4gc2VnbWVudC5zbGljZSgxLCAtMSkucmVwbGFjZSgvXlxcLlxcLlxcLi8sICcnKSlcbiAgICAuZmlsdGVyKChuYW1lKSA9PiBuYW1lLmxlbmd0aCA+IDApO1xufVxuXG4vKipcbiAqIEtlZXAgb25seSBwYXJhbXMgdGhhdCBtYXAgdG8gZHluYW1pYyBzZWdtZW50cyBpbiB0aGUgcm91dGUgcGF0aC5cbiAqIFRoaXMgcHJldmVudHMgZXh0cmEgR2VuaWUgcGFyYW1zIGZyb20gYmVjb21pbmcgcXVlcnkgc3RyaW5ncy5cbiAqL1xuZnVuY3Rpb24gZmlsdGVyUGFyYW1zRm9yUm91dGUocm91dGVQYXRoOiBzdHJpbmcsIHBhcmFtczogYW55KTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGlmICghcGFyYW1zIHx8IHR5cGVvZiBwYXJhbXMgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgcGFyYW1OYW1lcyA9IGdldER5bmFtaWNQYXJhbU5hbWVzKHJvdXRlUGF0aCk7XG4gIGlmIChwYXJhbU5hbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IGZpbHRlcmVkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIGZvciAoY29uc3QgbmFtZSBvZiBwYXJhbU5hbWVzKSB7XG4gICAgaWYgKHBhcmFtc1tuYW1lXSAhPT0gdW5kZWZpbmVkICYmIHBhcmFtc1tuYW1lXSAhPT0gbnVsbCkge1xuICAgICAgZmlsdGVyZWRbbmFtZV0gPSBwYXJhbXNbbmFtZV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZpbHRlcmVkO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUZpZWxkTmFtZShmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGZpZWxkLnJlcGxhY2UoL1teYS16QS1aMC05Xy4tXS9nLCAnXycpO1xufVxuXG5mdW5jdGlvbiB0b1F1ZXJ5UGFyYW1WYWx1ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IG51bGwge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gdmFsdWU7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIHNldFF1ZXJ5UGFyYW0ocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LCBrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHRvUXVlcnlQYXJhbVZhbHVlKHZhbHVlKTtcbiAgaWYgKG5vcm1hbGl6ZWQgPT09IG51bGwpIHJldHVybjtcbiAgbGV0IGNhbmRpZGF0ZSA9IGtleTtcbiAgbGV0IGkgPSAxO1xuICB3aGlsZSAocGFyYW1zW2NhbmRpZGF0ZV0gIT09IHVuZGVmaW5lZCkge1xuICAgIGNhbmRpZGF0ZSA9IGAke2tleX1fJHtpfWA7XG4gICAgaSArPSAxO1xuICB9XG4gIHBhcmFtc1tjYW5kaWRhdGVdID0gbm9ybWFsaXplZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUXVlcnlQYXJhbXNGcm9tTmF2U3RhdGUoXG4gIG5hdlN0YXRlOiBOYXZpZ2F0b3JTdGF0ZSxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBpZiAobmF2U3RhdGUucmVzdWx0UmVmKSB7XG4gICAgcGFyYW1zLnJnX3Jlc3VsdCA9IFN0cmluZyhuYXZTdGF0ZS5yZXN1bHRSZWYpO1xuICB9XG5cbiAgaWYgKG5hdlN0YXRlLnF1ZXJ5SW50ZW50Py5oYXNoKSB7XG4gICAgcGFyYW1zLnJnX3FoID0gbmF2U3RhdGUucXVlcnlJbnRlbnQuaGFzaDtcbiAgfVxuXG4gIGNvbnN0IG9wcyA9IG5hdlN0YXRlLnF1ZXJ5SW50ZW50Py5vcHMgPz8gW107XG4gIGZvciAoY29uc3Qgb3Agb2Ygb3BzKSB7XG4gICAgaWYgKG9wLmtpbmQgPT09ICdtYXRjaGluZycgfHwgb3Aua2luZCA9PT0gJ2NvbnRhaW5zJyB8fCBvcC5raW5kID09PSAnZXF1YWxzJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsIGBxXyR7b3Aua2luZH1fJHtzYW5pdGl6ZUZpZWxkTmFtZShvcC5maWVsZCl9YCwgb3AudmFsdWUpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG9wLmtpbmQgPT09ICdiZXR3ZWVuJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsIGBxX2JldHdlZW5fJHtzYW5pdGl6ZUZpZWxkTmFtZShvcC5maWVsZCl9X2Zyb21gLCBvcC5mcm9tKTtcbiAgICAgIHNldFF1ZXJ5UGFyYW0ocGFyYW1zLCBgcV9iZXR3ZWVuXyR7c2FuaXRpemVGaWVsZE5hbWUob3AuZmllbGQpfV90b2AsIG9wLnRvKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChvcC5raW5kID09PSAnc29ydCcpIHtcbiAgICAgIHNldFF1ZXJ5UGFyYW0oXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgJ3Ffc29ydCcsXG4gICAgICAgIGAke3Nhbml0aXplRmllbGROYW1lKG9wLmZpZWxkKX06JHtvcC5hc2NlbmRpbmcgPyAnYXNjJyA6ICdkZXNjJ31gXG4gICAgICApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG9wLmtpbmQgPT09ICdpbmRleCcpIHtcbiAgICAgIHNldFF1ZXJ5UGFyYW0ocGFyYW1zLCAncV9pbmRleCcsIG9wLnZhbHVlKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChvcC5raW5kID09PSAnbGVuZ3RoJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsICdxX2xlbmd0aCcsICd0cnVlJyk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmtleXMocGFyYW1zKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgLnJlZHVjZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PigoYWNjLCBrZXkpID0+IHtcbiAgICAgIGFjY1trZXldID0gcGFyYW1zW2tleV07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmlldyBjbGFzcyBuYW1lIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZFxuICovXG5mdW5jdGlvbiBpc1ZpZXdDbGFzc1JlZ2lzdGVyZWQodmlld0NsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBBVVRPX1JPVVRFX1JFR0lTVFJZLmhhcyh2aWV3Q2xhc3NOYW1lKTtcbn1cblxuLyoqXG4gKiBHZXQgcmVnaXN0cmF0aW9uIGluZm8gZm9yIGEgdmlldyBjbGFzcyAoZm9yIGVycm9yIG1lc3NhZ2VzKVxuICovXG5mdW5jdGlvbiBnZXRSZWdpc3RyYXRpb25JbmZvKHZpZXdDbGFzc05hbWU6IHN0cmluZyk6IFJvdXRlUmVnaXN0cmF0aW9uSW5mbyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBBVVRPX1JPVVRFX1JFR0lTVFJZLmdldCh2aWV3Q2xhc3NOYW1lKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSB1bmlxdWUgdmlldyBjbGFzcyBuYW1lIGZvciBkeW5hbWljIHJvdXRlc1xuICogXG4gKiBIYW5kbGVzIGR5bmFtaWMgc2VnbWVudHMgYnkgYXBwZW5kaW5nIG5vcm1hbGl6ZWQgc2VnbWVudCBuYW1lczpcbiAqIC0gL3Byb2JlcyDihpIgXCJQcm9iZVZpZXdcIlxuICogLSAvcHJvYmVzL1tpZF0g4oaSIFwiUHJvYmVWaWV3X2lkXCIgIFxuICogLSAvcHJvYmVzL1tpZF0vZWRpdCDihpIgXCJQcm9iZVZpZXdfaWRfZWRpdFwiXG4gKiAtIC9wcm9iZXMvW3NsdWddL2NvbW1lbnRzL1tjb21tZW50SWRdIOKGkiBcIlByb2JlVmlld19zbHVnX2NvbW1lbnRzX2NvbW1lbnRJZFwiXG4gKiBcbiAqIEBwYXJhbSBiYXNlQ2xhc3NOYW1lIC0gVGhlIGJhc2UgdmlldyBjbGFzcyBuYW1lIChlLmcuLCBcIlByb2JlVmlld1wiKVxuICogQHBhcmFtIHJvdXRlUGF0aCAtIFRoZSByb3V0ZSBwYXRoIChlLmcuLCBcIi9wcm9iZXMvW2lkXVwiKVxuICogQHJldHVybnMgVW5pcXVlIHZpZXcgY2xhc3MgbmFtZVxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUoYmFzZUNsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIEV4dHJhY3QgZHluYW1pYyBzZWdtZW50czogW2lkXSwgW3NsdWddLCBldGMuXG4gIGNvbnN0IGR5bmFtaWNTZWdtZW50cyA9IHJvdXRlUGF0aC5tYXRjaCgvXFxbKFteXFxdXSspXFxdL2cpO1xuICBcbiAgaWYgKCFkeW5hbWljU2VnbWVudHMgfHwgZHluYW1pY1NlZ21lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIE5vIGR5bmFtaWMgc2VnbWVudHMsIHJldHVybiBiYXNlIG5hbWVcbiAgICByZXR1cm4gYmFzZUNsYXNzTmFtZTtcbiAgfVxuICBcbiAgLy8gUmVtb3ZlIGJyYWNrZXRzIGFuZCBqb2luIHdpdGggdW5kZXJzY29yZVxuICAvLyBbaWRdIOKGkiBpZCwgW3NsdWddIOKGkiBzbHVnXG4gIGNvbnN0IHNlZ21lbnROYW1lcyA9IGR5bmFtaWNTZWdtZW50c1xuICAgIC5tYXAoc2VnID0+IHNlZy5yZXBsYWNlKC9bXFxbXFxdXS9nLCAnJykpXG4gICAgLmpvaW4oJ18nKTtcbiAgXG4gIHJldHVybiBgJHtiYXNlQ2xhc3NOYW1lfV8ke3NlZ21lbnROYW1lc31gO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIHJvdXRlIHdpdGggaXRzIGFjdHVhbCBmaWxlIHBhdGggZnJvbSBleHBvLXJvdXRlclxuICogXG4gKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgZnJvbSByb3V0ZSBmaWxlcyAoYXBwIGRpcmVjdG9yeSksIG5vdCBmcm9tIGNvbXBvbmVudCBmaWxlcy5cbiAqIFRoZSByb3V0ZSBwYXRoIGlzIGF1dG8tZGlzY292ZXJlZCBmcm9tIHRoZSBmaWxlIGxvY2F0aW9uLlxuICogXG4gKiAqKkR1cGxpY2F0ZSBEZXRlY3Rpb24qKjogSWYgYSB2aWV3IGNsYXNzIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCB0byBhIGRpZmZlcmVudCByb3V0ZSxcbiAqIGEgcnVudGltZSBlcnJvciB3aWxsIGJlIHRocm93biB3aXRoIGRldGFpbHMgYWJvdXQgYm90aCByZWdpc3RyYXRpb25zLlxuICogXG4gKiBAcGFyYW0gdmlld0NsYXNzTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB2aWV3IGNsYXNzIGJlaW5nIHJlbmRlcmVkIG9uIHRoaXMgcm91dGVcbiAqIEBwYXJhbSByb3V0ZVBhdGggLSBPcHRpb25hbCBleHBsaWNpdCBwYXRoLCBvdGhlcndpc2UgYXV0by1kaXNjb3ZlcmVkIGZyb20gY3VycmVudCByb3V0ZVxuICogXG4gKiBAdGhyb3dzIEVycm9yIGlmIHZpZXdDbGFzc05hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHRvIGEgZGlmZmVyZW50IHJvdXRlXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBJbiBhcHAvZ2VuaWUvY291bnRlci50c3hcbiAqIGltcG9ydCB7IHVzZVJlZ2lzdGVyR2VuaWVSb3V0ZSB9IGZyb20gJ0BnYXJyaXg4Mi9yZWFjdGdlbmllLWxpYic7XG4gKiBcbiAqIGV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvdW50ZXJSb3V0ZSgpIHtcbiAqICAgdXNlUmVnaXN0ZXJHZW5pZVJvdXRlKCdDb3VudGVyVmlldycpOyAvLyBBdXRvLWRpc2NvdmVyczogL2dlbmllL2NvdW50ZXJcbiAqICAgcmV0dXJuIDxDb3VudGVyVmlldyAvPjtcbiAqIH1cbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIER5bmFtaWMgcm91dGU6IGFwcC9nZW5pZS9baWRdLnRzeFxuICogZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRHluYW1pY0NvdW50ZXJSb3V0ZSgpIHtcbiAqICAgdXNlUmVnaXN0ZXJHZW5pZVJvdXRlKCdDb3VudGVyVmlldycpOyAvLyBBdXRvLWRpc2NvdmVyczogL2dlbmllL1tpZF1cbiAqICAgcmV0dXJuIDxDb3VudGVyVmlldyAvPjtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVJlZ2lzdGVyR2VuaWVSb3V0ZShiYXNlVmlld0NsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg/OiBzdHJpbmcpIHtcbiAgLy8gT25seSB3b3JrcyBpZiBleHBvLXJvdXRlciBpcyBhdmFpbGFibGVcbiAgaWYgKCF1c2VQYXRobmFtZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBhdGhuYW1lID0gdXNlUGF0aG5hbWUoKTtcbiAgXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgcGF0aCA9IHJvdXRlUGF0aCB8fCBwYXRobmFtZTtcbiAgICBcbiAgICBpZiAocGF0aCAmJiBiYXNlVmlld0NsYXNzTmFtZSkge1xuICAgICAgLy8gR2VuZXJhdGUgdW5pcXVlIHZpZXcgY2xhc3MgbmFtZSBmb3IgZHluYW1pYyByb3V0ZXNcbiAgICAgIGNvbnN0IHZpZXdDbGFzc05hbWUgPSBnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUoYmFzZVZpZXdDbGFzc05hbWUsIHBhdGgpO1xuICAgICAgXG4gICAgICBjb25zdCBleGlzdGluZ1JlZ2lzdHJhdGlvbiA9IGdldFJlZ2lzdHJhdGlvbkluZm8odmlld0NsYXNzTmFtZSk7XG5cbiAgICAgIC8vIEF1dG8gcmVnaXN0cnkgYWxyZWFkeSBvd25zIHRoaXMgdmlldyBjbGFzczsgaWdub3JlIHJ1bnRpbWUgcmVnaXN0cmF0aW9uLlxuICAgICAgaWYgKGV4aXN0aW5nUmVnaXN0cmF0aW9uICYmIGV4aXN0aW5nUmVnaXN0cmF0aW9uLnNvdXJjZSA9PT0gXCJhdXRvXCIpIHtcbiAgICAgICAgaWYgKHJvdXRlUGF0aCAmJiBleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGggIT09IHBhdGgpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgW1JlYWN0R2VuaWVdIFNraXBwaW5nIHJ1bnRpbWUgcmVnaXN0cmF0aW9uIGZvciBcIiR7dmlld0NsYXNzTmFtZX1cIiBgICtcbiAgICAgICAgICAgIGAoJHtwYXRofSkuIEF1dG8gcmVnaXN0cnkgYWxyZWFkeSBtYXBwZWQgaXQgdG8gXCIke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJvdXRlUGF0aH1cIi5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBkdXBsaWNhdGUgcnVudGltZSByZWdpc3RyYXRpb25cbiAgICAgIGlmIChleGlzdGluZ1JlZ2lzdHJhdGlvbiAmJiBleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGggIT09IHBhdGgpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcbiAgICAgICAgICBgW1JlYWN0R2VuaWVdIEVSUk9SOiBEdXBsaWNhdGUgcmVnaXN0cmF0aW9uIGRldGVjdGVkIVxcbmAgK1xuICAgICAgICAgIGBWaWV3IGNsYXNzIFwiJHt2aWV3Q2xhc3NOYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cXG5cXG5gICtcbiAgICAgICAgICBgRXhpc3RpbmcgcmVnaXN0cmF0aW9uOlxcbmAgK1xuICAgICAgICAgIGAgIFJvdXRlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJvdXRlUGF0aH1cXG5gICtcbiAgICAgICAgICBgICBGaWxlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJlZ2lzdGVyZWRBdH1cXG5cXG5gICtcbiAgICAgICAgICBgTmV3IHJlZ2lzdHJhdGlvbiBhdHRlbXB0OlxcbmAgK1xuICAgICAgICAgIGAgIFJvdXRlOiAke3BhdGh9XFxuXFxuYCArXG4gICAgICAgICAgYEVhY2ggdmlldyBjbGFzcyBjYW4gb25seSBiZSByZWdpc3RlcmVkIHRvIE9ORSByb3V0ZS5cXG5gICtcbiAgICAgICAgICBgUGxlYXNlIHVzZSBhIGRpZmZlcmVudCB2aWV3IGNsYXNzIG5hbWUgZm9yIHRoZSBzZWNvbmQgcm91dGUsXFxuYCArXG4gICAgICAgICAgYG9yIHJlbW92ZSBvbmUgb2YgdGhlIHJlZ2lzdHJhdGlvbnMuYDtcbiAgICAgICAgXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBSZWdpc3RlciB0aGUgcm91dGUgd2l0aCBtZXRhZGF0YVxuICAgICAgQVVUT19ST1VURV9SRUdJU1RSWS5zZXQodmlld0NsYXNzTmFtZSwge1xuICAgICAgICB2aWV3Q2xhc3NOYW1lLFxuICAgICAgICByb3V0ZVBhdGg6IHBhdGgsXG4gICAgICAgIHJlZ2lzdGVyZWRBdDogcGF0aCwgLy8gVXNlIHBhdGhuYW1lIGFzIFwiZmlsZSBsb2NhdGlvblwiXG4gICAgICAgIHNvdXJjZTogXCJydW50aW1lXCIsXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gY29uc29sZS5sb2coYFtSZWFjdEdlbmllXSBSZWdpc3RlcmVkIHJvdXRlOiAke3ZpZXdDbGFzc05hbWV9IOKGkiAke3BhdGh9YCk7XG4gICAgfVxuICB9LCBbYmFzZVZpZXdDbGFzc05hbWUsIHBhdGhuYW1lLCByb3V0ZVBhdGhdKTtcbn1cblxuLyoqXG4gKiBBbHRlcm5hdGl2ZTogUmVnaXN0ZXIgcm91dGUgd2l0aG91dCBob29rIChmb3IgdXNlIG91dHNpZGUgUmVhY3QgY29tcG9uZW50cylcbiAqIFxuICogKipEdXBsaWNhdGUgRGV0ZWN0aW9uKio6IFRocm93cyBlcnJvciBpZiB2aWV3IGNsYXNzIGFscmVhZHkgcmVnaXN0ZXJlZCB0byBkaWZmZXJlbnQgcm91dGUuXG4gKiBcbiAqIEBwYXJhbSB2aWV3Q2xhc3NOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHZpZXcgY2xhc3NcbiAqIEBwYXJhbSByb3V0ZVBhdGggLSBUaGUgZmlsZS1iYXNlZCByb3V0ZSBwYXRoIHdoZXJlIHRoaXMgdmlldyBpcyB1c2VkXG4gKiBAdGhyb3dzIEVycm9yIGlmIHZpZXdDbGFzc05hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHRvIGEgZGlmZmVyZW50IHJvdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckdlbmllUm91dGUodmlld0NsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg6IHN0cmluZykge1xuICAvLyBDaGVjayBmb3IgZHVwbGljYXRlIHJlZ2lzdHJhdGlvblxuICBjb25zdCBleGlzdGluZ1JlZ2lzdHJhdGlvbiA9IGdldFJlZ2lzdHJhdGlvbkluZm8odmlld0NsYXNzTmFtZSk7XG4gIFxuICBpZiAoZXhpc3RpbmdSZWdpc3RyYXRpb24gJiYgZXhpc3RpbmdSZWdpc3RyYXRpb24ucm91dGVQYXRoICE9PSByb3V0ZVBhdGgpIHtcbiAgICBjb25zdCBlcnJvck1zZyA9IFxuICAgICAgYFtSZWFjdEdlbmllXSBFUlJPUjogRHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkZXRlY3RlZCFcXG5gICtcbiAgICAgIGBWaWV3IGNsYXNzIFwiJHt2aWV3Q2xhc3NOYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cXG5cXG5gICtcbiAgICAgIGBFeGlzdGluZyByZWdpc3RyYXRpb246XFxuYCArXG4gICAgICBgICBSb3V0ZTogJHtleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGh9XFxuYCArXG4gICAgICBgICBGaWxlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJlZ2lzdGVyZWRBdH1cXG5cXG5gICtcbiAgICAgIGBOZXcgcmVnaXN0cmF0aW9uIGF0dGVtcHQ6XFxuYCArXG4gICAgICBgICBSb3V0ZTogJHtyb3V0ZVBhdGh9XFxuXFxuYCArXG4gICAgICBgRWFjaCB2aWV3IGNsYXNzIGNhbiBvbmx5IGJlIHJlZ2lzdGVyZWQgdG8gT05FIHJvdXRlLlxcbmAgK1xuICAgICAgYFBsZWFzZSB1c2UgYSBkaWZmZXJlbnQgdmlldyBjbGFzcyBuYW1lIGZvciB0aGUgc2Vjb25kIHJvdXRlLFxcbmAgK1xuICAgICAgYG9yIHJlbW92ZSBvbmUgb2YgdGhlIHJlZ2lzdHJhdGlvbnMuYDtcbiAgICBcbiAgICBjb25zb2xlLmVycm9yKGVycm9yTXNnKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICB9XG4gIFxuICBBVVRPX1JPVVRFX1JFR0lTVFJZLnNldCh2aWV3Q2xhc3NOYW1lLCB7XG4gICAgdmlld0NsYXNzTmFtZSxcbiAgICByb3V0ZVBhdGgsXG4gICAgcmVnaXN0ZXJlZEF0OiByb3V0ZVBhdGgsXG4gICAgc291cmNlOiBcImF1dG9cIixcbiAgfSk7XG4gIC8vIGNvbnNvbGUubG9nKGBbUmVhY3RHZW5pZV0gUmVnaXN0ZXJlZCByb3V0ZTogJHt2aWV3Q2xhc3NOYW1lfSDihpIgJHtyb3V0ZVBhdGh9YCk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgcm91dGUgcGF0aCBmb3IgYSB2aWV3IGNsYXNzIG5hbWVcbiAqL1xuZnVuY3Rpb24gZ2V0Um91dGVGb3JWaWV3KHZpZXdDbGFzc05hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCByZWdpc3RyYXRpb24gPSBBVVRPX1JPVVRFX1JFR0lTVFJZLmdldCh2aWV3Q2xhc3NOYW1lKTtcbiAgcmV0dXJuIHJlZ2lzdHJhdGlvbj8ucm91dGVQYXRoIHx8IG51bGw7XG59XG5cbmZ1bmN0aW9uIHNwbGl0Um91dGVTZWdtZW50cyhwYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGlmICghcGF0aCB8fCBwYXRoID09PSAnLycpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIHBhdGhcbiAgICAuc3BsaXQoJy8nKVxuICAgIC5maWx0ZXIoKHNlZ21lbnQpID0+IHNlZ21lbnQubGVuZ3RoID4gMCk7XG59XG5cbmZ1bmN0aW9uIGlzRHluYW1pY1NlZ21lbnQoc2VnbWVudDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzZWdtZW50LnN0YXJ0c1dpdGgoJ1snKSAmJiBzZWdtZW50LmVuZHNXaXRoKCddJyk7XG59XG5cbmZ1bmN0aW9uIGlzQ2F0Y2hBbGxTZWdtZW50KHNlZ21lbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2VnbWVudC5zdGFydHNXaXRoKCdbLi4uJykgJiYgc2VnbWVudC5lbmRzV2l0aCgnXScpO1xufVxuXG5mdW5jdGlvbiBpc09wdGlvbmFsQ2F0Y2hBbGxTZWdtZW50KHNlZ21lbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2VnbWVudC5zdGFydHNXaXRoKCdbWy4uLicpICYmIHNlZ21lbnQuZW5kc1dpdGgoJ11dJyk7XG59XG5cbmZ1bmN0aW9uIHJvdXRlVGVtcGxhdGVNYXRjaGVzUGF0aChyb3V0ZVRlbXBsYXRlOiBzdHJpbmcsIHBhdGhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgdGVtcGxhdGVTZWdtZW50cyA9IHNwbGl0Um91dGVTZWdtZW50cyhyb3V0ZVRlbXBsYXRlKTtcbiAgY29uc3QgcGF0aFNlZ21lbnRzID0gc3BsaXRSb3V0ZVNlZ21lbnRzKHBhdGhuYW1lKTtcblxuICBsZXQgdGVtcGxhdGVJbmRleCA9IDA7XG4gIGxldCBwYXRoSW5kZXggPSAwO1xuXG4gIHdoaWxlICh0ZW1wbGF0ZUluZGV4IDwgdGVtcGxhdGVTZWdtZW50cy5sZW5ndGgpIHtcbiAgICBjb25zdCB0ZW1wbGF0ZVNlZ21lbnQgPSB0ZW1wbGF0ZVNlZ21lbnRzW3RlbXBsYXRlSW5kZXhdO1xuXG4gICAgaWYgKGlzT3B0aW9uYWxDYXRjaEFsbFNlZ21lbnQodGVtcGxhdGVTZWdtZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGlzQ2F0Y2hBbGxTZWdtZW50KHRlbXBsYXRlU2VnbWVudCkpIHtcbiAgICAgIHJldHVybiBwYXRoSW5kZXggPCBwYXRoU2VnbWVudHMubGVuZ3RoO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGhTZWdtZW50ID0gcGF0aFNlZ21lbnRzW3BhdGhJbmRleF07XG4gICAgaWYgKHBhdGhTZWdtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaXNEeW5hbWljU2VnbWVudCh0ZW1wbGF0ZVNlZ21lbnQpKSB7XG4gICAgICB0ZW1wbGF0ZUluZGV4ICs9IDE7XG4gICAgICBwYXRoSW5kZXggKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICh0ZW1wbGF0ZVNlZ21lbnQgIT09IHBhdGhTZWdtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGVtcGxhdGVJbmRleCArPSAxO1xuICAgIHBhdGhJbmRleCArPSAxO1xuICB9XG5cbiAgcmV0dXJuIHBhdGhJbmRleCA9PT0gcGF0aFNlZ21lbnRzLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gZ2V0Um91dGVTcGVjaWZpY2l0eShyb3V0ZVRlbXBsYXRlOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCBzZWdtZW50cyA9IHNwbGl0Um91dGVTZWdtZW50cyhyb3V0ZVRlbXBsYXRlKTtcbiAgY29uc3Qgc3RhdGljU2VnbWVudHMgPSBzZWdtZW50cy5maWx0ZXIoKHNlZ21lbnQpID0+ICFpc0R5bmFtaWNTZWdtZW50KHNlZ21lbnQpKS5sZW5ndGg7XG4gIHJldHVybiBzdGF0aWNTZWdtZW50cyAqIDEwMCArIHNlZ21lbnRzLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFJvdXRlVGVtcGxhdGUocGF0aG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjYW5kaWRhdGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEFVVE9fUk9VVEVfUkVHSVNUUlkuZm9yRWFjaCgoaW5mbykgPT4ge1xuICAgIGlmIChyb3V0ZVRlbXBsYXRlTWF0Y2hlc1BhdGgoaW5mby5yb3V0ZVBhdGgsIHBhdGhuYW1lKSkge1xuICAgICAgY2FuZGlkYXRlcy5wdXNoKGluZm8ucm91dGVQYXRoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY2FuZGlkYXRlcy5zb3J0KChhLCBiKSA9PiBnZXRSb3V0ZVNwZWNpZmljaXR5KGIpIC0gZ2V0Um91dGVTcGVjaWZpY2l0eShhKSk7XG4gIHJldHVybiBjYW5kaWRhdGVzWzBdO1xufVxuXG4vKipcbiAqIEhvb2sgdGhhdCBhdXRvbWF0aWNhbGx5IGludGVyY2VwdHMgUmVhY3RHZW5pZSBuYXZpZ2F0aW9uIGFuZCByb3V0ZXMgdmlhIGV4cG8tcm91dGVyXG4gKiBcbiAqIFJvdXRlcyBhcmUgYXV0by1kaXNjb3ZlcmVkIGZyb20gd2hlcmUgY29tcG9uZW50cyBhcmUgYWN0dWFsbHkgdXNlZCwgbm90IGluZmVycmVkLlxuICogXG4gKiBVc2FnZTogSW1wb3J0IGFuZCBjYWxsIGluIHlvdXIgcm9vdCBfbGF5b3V0LnRzeCAoaW5zaWRlIFByb3ZpZGVyIGNvbnRleHQpOlxuICogYGBgdHN4XG4gKiBpbXBvcnQgeyB1c2VFeHBvUm91dGVyQWRhcHRlciB9IGZyb20gJ0BnYXJyaXg4Mi9yZWFjdGdlbmllLWxpYic7XG4gKiBcbiAqIGZ1bmN0aW9uIFJvb3RMYXlvdXRDb250ZW50KCkge1xuICogICB1c2VFeHBvUm91dGVyQWRhcHRlcigpOyAvLyA8LSBBZGQgdGhpcyBsaW5lXG4gKiAgIC8vIC4uLiByZXN0IG9mIGxheW91dFxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VFeHBvUm91dGVyQWRhcHRlcigpIHtcbiAgLy8gQ2hlY2sgaWYgZXhwby1yb3V0ZXIgaXMgYXZhaWxhYmxlXG4gIGlmICghdXNlUm91dGVyIHx8ICF1c2VTZWdtZW50cykge1xuICAgIC8vIE5vIGV4cG8tcm91dGVyLCBuYXZpZ2F0aW9uIHdpbGwgZmFsbCBiYWNrIHRvIHJlYWN0LW5hdmlnYXRpb25cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCByb3V0ZXIgPSB1c2VSb3V0ZXIoKTtcbiAgY29uc3QgcGF0aG5hbWUgPSB1c2VQYXRobmFtZSA/IHVzZVBhdGhuYW1lKCkgOiAnJztcbiAgY29uc3QgbG9jYWxTZWFyY2hQYXJhbXMgPSB1c2VMb2NhbFNlYXJjaFBhcmFtcyA/IHVzZUxvY2FsU2VhcmNoUGFyYW1zKCkgOiB7fTtcbiAgY29uc3QgbmF2U3RhdGUgPSB1c2VHZW5pZVNlbGVjdG9yKChzdGF0ZTogYW55KSA9PiBzdGF0ZS5uYXZTdGF0ZSBhcyBOYXZpZ2F0b3JTdGF0ZSB8IG51bGwpO1xuICBjb25zdCBuYXZTdGFjayA9IHVzZUdlbmllU2VsZWN0b3IoKHN0YXRlOiBhbnkpID0+IHN0YXRlLm5hdlN0YWNrIGFzIG51bWJlcik7XG4gIGNvbnN0IGxhc3RIYW5kbGVkTmF2U3RhY2tSZWYgPSB1c2VSZWY8bnVtYmVyPigwKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghbmF2U3RhdGU/Lm9iamVjdFZpZXdDbGFzc05hbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAobmF2U3RhY2sgPD0gbGFzdEhhbmRsZWROYXZTdGFja1JlZi5jdXJyZW50KSB7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBbUmVhY3RHZW5pZU5hdl0gcmVhc29uPWlnbm9yZWRfZHVwbGljYXRlX2V2ZW50IG5hdlN0YWNrPSR7bmF2U3RhY2t9IGxhc3RIYW5kbGVkPSR7bGFzdEhhbmRsZWROYXZTdGFja1JlZi5jdXJyZW50fWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnRJZCA9IG5hdlN0YWNrO1xuICAgIGNvbnN0IHZpZXdDbGFzc05hbWUgPSBuYXZTdGF0ZS5vYmplY3RWaWV3Q2xhc3NOYW1lO1xuICAgIGNvbnN0IHBhcmFtcyA9IG5hdlN0YXRlLm9iamVjdENvbnN0cnVjdG9yUGFyYW1zO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvdXRlUGF0aCA9IGdldFJvdXRlRm9yVmlldyh2aWV3Q2xhc3NOYW1lKTtcbiAgICAgIGlmICghcm91dGVQYXRoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGBbUmVhY3RHZW5pZU5hdl0gcmVhc29uPXNraXBwZWRfdW5yZWdpc3RlcmVkX3ZpZXcgZXZlbnQ9JHtldmVudElkfSB2aWV3PSR7dmlld0NsYXNzTmFtZX1gXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmRlYnVnKGBbUmVhY3RHZW5pZV0gQXV0by1yb3V0aW5nOiAke3ZpZXdDbGFzc05hbWV9IOKGkiAke3JvdXRlUGF0aH1gKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW1JlYWN0R2VuaWVdIE5hdmlnYXRpb24gcGFyYW1zOmAsIHBhcmFtcyk7XG5cbiAgICAgIGNvbnN0IHJvdXRlUGFyYW1zID0gZmlsdGVyUGFyYW1zRm9yUm91dGUocm91dGVQYXRoLCBwYXJhbXMpO1xuICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBidWlsZFF1ZXJ5UGFyYW1zRnJvbU5hdlN0YXRlKG5hdlN0YXRlKTtcbiAgICAgIGNvbnN0IGR5bmFtaWNQYXJhbU5hbWVzID0gZ2V0RHluYW1pY1BhcmFtTmFtZXMocm91dGVQYXRoKTtcbiAgICAgIGNvbnN0IG1pc3NpbmdQYXJhbXMgPSBkeW5hbWljUGFyYW1OYW1lcy5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiByb3V0ZVBhcmFtc1tuYW1lXSA9PT0gdW5kZWZpbmVkIHx8IHJvdXRlUGFyYW1zW25hbWVdID09PSBudWxsXG4gICAgICApO1xuXG4gICAgICBpZiAoZHluYW1pY1BhcmFtTmFtZXMubGVuZ3RoID4gMCAmJiBtaXNzaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtSZWFjdEdlbmllTmF2XSByZWFzb249c2tpcHBlZF9taXNzaW5nX3BhcmFtcyBldmVudD0ke2V2ZW50SWR9IHZpZXc9JHt2aWV3Q2xhc3NOYW1lfSBtaXNzaW5nPSR7bWlzc2luZ1BhcmFtcy5qb2luKCcsJyl9YFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFjdGl2ZVRlbXBsYXRlID0gZ2V0Q3VycmVudFJvdXRlVGVtcGxhdGUocGF0aG5hbWUgfHwgJycpO1xuICAgICAgY29uc3QgZHluYW1pY1BhcmFtc1VuY2hhbmdlZCA9IGR5bmFtaWNQYXJhbU5hbWVzLmV2ZXJ5KChuYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBBcnJheS5pc0FycmF5KChsb2NhbFNlYXJjaFBhcmFtcyBhcyBhbnkpPy5bbmFtZV0pXG4gICAgICAgICAgPyAobG9jYWxTZWFyY2hQYXJhbXMgYXMgYW55KVtuYW1lXVswXVxuICAgICAgICAgIDogKGxvY2FsU2VhcmNoUGFyYW1zIGFzIGFueSk/LltuYW1lXTtcbiAgICAgICAgcmV0dXJuIFN0cmluZyhjdXJyZW50ID8/ICcnKSA9PT0gU3RyaW5nKHJvdXRlUGFyYW1zW25hbWVdID8/ICcnKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2hvdWxkUmVwbGFjZSA9XG4gICAgICAgIGFjdGl2ZVRlbXBsYXRlICE9PSBudWxsICYmXG4gICAgICAgIGFjdGl2ZVRlbXBsYXRlID09PSByb3V0ZVBhdGggJiZcbiAgICAgICAgZHluYW1pY1BhcmFtc1VuY2hhbmdlZDtcblxuICAgICAgY29uc3QgZGVzdGluYXRpb25QYXJhbXMgPSB7XG4gICAgICAgIC4uLnJvdXRlUGFyYW1zLFxuICAgICAgICAuLi5xdWVyeVBhcmFtcyxcbiAgICAgIH07XG4gICAgICBjb25zdCBoYXNQYXJhbXMgPSBPYmplY3Qua2V5cyhkZXN0aW5hdGlvblBhcmFtcykubGVuZ3RoID4gMDtcblxuICAgICAgaWYgKGhhc1BhcmFtcykge1xuICAgICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IHtcbiAgICAgICAgICBwYXRobmFtZTogcm91dGVQYXRoIGFzIGFueSxcbiAgICAgICAgICBwYXJhbXM6IGRlc3RpbmF0aW9uUGFyYW1zLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoc2hvdWxkUmVwbGFjZSAmJiB0eXBlb2Ygcm91dGVyLnJlcGxhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByb3V0ZXIucmVwbGFjZShkZXN0aW5hdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcm91dGVyLnB1c2goZGVzdGluYXRpb24pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNob3VsZFJlcGxhY2UgJiYgdHlwZW9mIHJvdXRlci5yZXBsYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJvdXRlci5yZXBsYWNlKHJvdXRlUGF0aCBhcyBhbnkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcm91dGVyLnB1c2gocm91dGVQYXRoIGFzIGFueSk7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICBgW1JlYWN0R2VuaWVOYXZdIHJlYXNvbj0ke3Nob3VsZFJlcGxhY2UgPyAnaGFuZGxlZF9yZXBsYWNlJyA6ICdoYW5kbGVkX3B1c2gnfSBldmVudD0ke2V2ZW50SWR9IHZpZXc9JHt2aWV3Q2xhc3NOYW1lfSByb3V0ZT0ke3JvdXRlUGF0aH1gXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBbUmVhY3RHZW5pZV0gTmF2aWdhdGlvbiBlcnJvcjpgLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGxhc3RIYW5kbGVkTmF2U3RhY2tSZWYuY3VycmVudCA9IGV2ZW50SWQ7XG4gICAgICAvLyBSZXNldCBuYXZpZ2F0aW9uIHN0YXRlIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHMgYWZ0ZXIgaGFuZGxpbmcgdGhpcyBldmVudC5cbiAgICAgIHJlc2V0R2VuaWVOYXZpZ2F0aW9uKCk7XG4gICAgfVxuICB9LCBbbmF2U3RhY2ssIG5hdlN0YXRlLCBwYXRobmFtZSwgbG9jYWxTZWFyY2hQYXJhbXMsIHJvdXRlcl0pO1xufVxuXG4vKipcbiAqIEhpZ2hlci1vcmRlciBjb21wb25lbnQgdGhhdCB3cmFwcyB5b3VyIHJvb3QgbGF5b3V0IHdpdGggZXhwby1yb3V0ZXIgYWRhcHRlclxuICogXG4gKiBVc2FnZTpcbiAqIGBgYHRzeFxuICogaW1wb3J0IHsgd2l0aEV4cG9Sb3V0ZXJBZGFwdGVyIH0gZnJvbSAnQGdhcnJpeDgyL3JlYWN0Z2VuaWUtbGliJztcbiAqIFxuICogZnVuY3Rpb24gUm9vdExheW91dCgpIHtcbiAqICAgcmV0dXJuIChcbiAqICAgICA8UHJvdmlkZXIgc3RvcmU9e3JlYWN0R2VuaWVTdG9yZX0+XG4gKiAgICAgICA8U3RhY2s+Li4uPC9TdGFjaz5cbiAqICAgICA8L1Byb3ZpZGVyPlxuICogICApO1xuICogfVxuICogXG4gKiBleHBvcnQgZGVmYXVsdCB3aXRoRXhwb1JvdXRlckFkYXB0ZXIoUm9vdExheW91dCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhFeHBvUm91dGVyQWRhcHRlcjxQIGV4dGVuZHMgb2JqZWN0PihcbiAgQ29tcG9uZW50OiBSZWFjdC5Db21wb25lbnRUeXBlPFA+XG4pOiBSZWFjdC5Db21wb25lbnRUeXBlPFA+IHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEV4cG9Sb3V0ZXJBZGFwdGVyV3JhcHBlcihwcm9wczogUCkge1xuICAgIHVzZUV4cG9Sb3V0ZXJBZGFwdGVyKCk7XG4gICAgcmV0dXJuIDxDb21wb25lbnQgey4uLnByb3BzfSAvPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBVdGlsaXR5IHRvIGNoZWNrIGlmIGV4cG8tcm91dGVyIGlzIGF2YWlsYWJsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFeHBvUm91dGVyQXZhaWxhYmxlKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdXNlUm91dGVyICE9PSBudWxsICYmIHVzZVNlZ21lbnRzICE9PSBudWxsO1xufVxuXG4vKipcbiAqIEdldCBhbGwgcmVnaXN0ZXJlZCByb3V0ZXMgKGZvciBkZWJ1Z2dpbmcpXG4gKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgcmVnaXN0cmF0aW9uIG1hcCB3aXRoIGZ1bGwgbWV0YWRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlZ2lzdGVyZWRSb3V0ZXMoKTogTWFwPHN0cmluZywgUm91dGVSZWdpc3RyYXRpb25JbmZvPiB7XG4gIHJldHVybiBuZXcgTWFwKEFVVE9fUk9VVEVfUkVHSVNUUlkpO1xufVxuXG4vKipcbiAqIEdldCBzaW1wbGUgcm91dGUgbWFwICh2aWV3Q2xhc3NOYW1lIOKGkiByb3V0ZVBhdGgpIGZvciBkZWJ1Z2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJvdXRlTWFwKCk6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBzaW1wbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBBVVRPX1JPVVRFX1JFR0lTVFJZLmZvckVhY2goKGluZm8sIHZpZXdDbGFzc05hbWUpID0+IHtcbiAgICBzaW1wbGVNYXAuc2V0KHZpZXdDbGFzc05hbWUsIGluZm8ucm91dGVQYXRoKTtcbiAgfSk7XG4gIHJldHVybiBzaW1wbGVNYXA7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFVQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxjQUFBLEdBQUFGLE9BQUE7QUFFQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFBbUMsU0FBQUQsd0JBQUFLLENBQUEsRUFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxNQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFQLHVCQUFBLFlBQUFBLENBQUFLLENBQUEsRUFBQUMsQ0FBQSxTQUFBQSxDQUFBLElBQUFELENBQUEsSUFBQUEsQ0FBQSxDQUFBSyxVQUFBLFNBQUFMLENBQUEsTUFBQU0sQ0FBQSxFQUFBQyxDQUFBLEVBQUFDLENBQUEsS0FBQUMsU0FBQSxRQUFBQyxPQUFBLEVBQUFWLENBQUEsaUJBQUFB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
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface NavigationAdapter {
|
|
3
|
+
push: (routeName: string, params?: any) => void;
|
|
4
|
+
navigate: (routeName: string, params?: any) => void;
|
|
5
|
+
goBack: () => void;
|
|
6
|
+
canGoBack: () => boolean;
|
|
7
|
+
setOptions: (options: any) => void;
|
|
8
|
+
getState: () => any;
|
|
9
|
+
}
|
|
10
|
+
export declare function useNavigationAdapter(): NavigationAdapter;
|
|
11
|
+
export declare function withNavigationAdapter<P extends object>(Component: React.ComponentType<P & {
|
|
12
|
+
navigation: NavigationAdapter;
|
|
13
|
+
}>): React.FC<P>;
|
|
14
|
+
export declare function useRouteParams<T = any>(): T;
|
|
15
|
+
export declare function createScreenWrapper(Screen: React.ComponentType<any>, options?: {
|
|
16
|
+
title?: (params?: any) => string;
|
|
17
|
+
headerShown?: boolean;
|
|
18
|
+
}): (props: any) => any;
|
|
19
|
+
export declare function isExpoRouter(): boolean;
|
|
20
|
+
export type { NavigationAdapter as Navigation };
|