| 1 |
"use strict"; |
| 2 |
|
| 3 |
/** |
| 4 |
* @file: ../includes/page-form-builder/_out/export/builder-exporter.js |
| 5 |
*/ |
| 6 |
(function () { |
| 7 |
"use strict"; |
| 8 |
|
| 9 |
const core = window.WPBC_BFB_Core || {}; |
| 10 |
|
| 11 |
// == Helpers — Shared helper API for field packs ================================================================== |
| 12 |
// ================================================================================================= |
| 13 |
// == These are generic utilities that packs can call from their own exporters: |
| 14 |
// == - compute_name(), id_option(), class_options(), size_max_token(), emit_time_select(), etc. |
| 15 |
// == No field-type branching should live in the core exporter. |
| 16 |
// ================================================================================================= |
| 17 |
|
| 18 |
/** |
| 19 |
* Default skip list (can be extended/overridden at runtime). |
| 20 |
* - Only attribute NAMES here (case-insensitive). Values are removed with them. |
| 21 |
*/ |
| 22 |
const wpbc_export_skip_attrs_default = ['data-colstyles-active']; |
| 23 |
|
| 24 |
/** |
| 25 |
* Remove attributes by name from an HTML-like string. |
| 26 |
* Matches: |
| 27 |
* - name |
| 28 |
* - name="..."/name='...'/name=value |
| 29 |
* with any surrounding whitespace. |
| 30 |
* |
| 31 |
* @param {string} html |
| 32 |
* @param {string[]} attrs_lowercase attribute names (lowercase) |
| 33 |
* @return {string} |
| 34 |
*/ |
| 35 |
function strip_attributes_from_markup(html, attrs_lowercase) { |
| 36 |
if (!html || !attrs_lowercase?.length) return html; |
| 37 |
let out = String(html); |
| 38 |
for (const rawName of attrs_lowercase) { |
| 39 |
if (!rawName) continue; |
| 40 |
const name = String(rawName).toLowerCase().trim(); |
| 41 |
// Escape for regex |
| 42 |
const esc = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); |
| 43 |
// Match full attribute name only (next char is NOT a valid name char) |
| 44 |
const re = new RegExp(`\\s${esc}(?![A-Za-z0-9_:\\-])(?:=(?:"[^"]*"|'[^']*'|[^\\s>]*))?`, 'gi'); |
| 45 |
out = out.replace(re, ''); |
| 46 |
} |
| 47 |
return out; |
| 48 |
} |
| 49 |
|
| 50 |
// == Helpers – column styles parsing & CSS vars builder =========================================================== |
| 51 |
|
| 52 |
// Known keys we treat as real per-column style overrides. |
| 53 |
function has_non_default_col_styles(obj) { |
| 54 |
if (!obj || typeof obj !== 'object') { |
| 55 |
return false; |
| 56 |
} |
| 57 |
var keys = ['dir', 'wrap', 'jc', 'ai', 'gap', 'aself', 'ac']; |
| 58 |
for (var i = 0; i < keys.length; i++) { |
| 59 |
var k = keys[i]; |
| 60 |
if (obj[k] != null && String(obj[k]).trim() !== '') { |
| 61 |
return true; |
| 62 |
} |
| 63 |
} |
| 64 |
return false; |
| 65 |
} |
| 66 |
|
| 67 |
/** |
| 68 |
* Parse `col_styles` coming from a Section. |
| 69 |
* Accepts: JSON string or array of objects. |
| 70 |
* |
| 71 |
* @param {string|Array|undefined|null} raw |
| 72 |
* @returns {Array<Object>} array aligned to columns (may be empty) |
| 73 |
*/ |
| 74 |
function parse_col_styles_json(raw) { |
| 75 |
if (!raw) return []; |
| 76 |
if (Array.isArray(raw)) return raw.filter(function (x) { |
| 77 |
return x && typeof x === 'object'; |
| 78 |
}); |
| 79 |
if (typeof raw === 'string') { |
| 80 |
try { |
| 81 |
var arr = JSON.parse(raw); |
| 82 |
return Array.isArray(arr) ? arr.filter(function (x) { |
| 83 |
return x && typeof x === 'object'; |
| 84 |
}) : []; |
| 85 |
} catch (_e) { |
| 86 |
return []; |
| 87 |
} |
| 88 |
} |
| 89 |
return []; |
| 90 |
} |
| 91 |
|
| 92 |
/** |
| 93 |
* Build CSS variable declarations string for a column style object. |
| 94 |
* Known keys -> CSS vars: |
| 95 |
* - dir -> --wpbc-bfb-col-dir |
| 96 |
* - wrap -> --wpbc-bfb-col-wrap |
| 97 |
* - jc -> --wpbc-bfb-col-jc |
| 98 |
* - ai -> --wpbc-bfb-col-ai |
| 99 |
* - gap -> --wpbc-bfb-col-gap |
| 100 |
* - ac -> --wpbc-bfb-col-ac |
| 101 |
* - aself-> --wpbc-bfb-col-aself |
| 102 |
* |
| 103 |
* Unknown keys are exported as `--wpbc-bfb-col-${key}`. |
| 104 |
* |
| 105 |
* @param {Object|null|undefined} obj |
| 106 |
* @returns {string} e.g. "--wpbc-bfb-col-dir: row; --wpbc-bfb-col-wrap: wrap;" |
| 107 |
*/ |
| 108 |
function build_col_css_vars(obj) { |
| 109 |
if (!obj || typeof obj !== 'object') return ''; |
| 110 |
var map = { |
| 111 |
dir: '--wpbc-bfb-col-dir', |
| 112 |
wrap: '--wpbc-bfb-col-wrap', |
| 113 |
jc: '--wpbc-bfb-col-jc', |
| 114 |
ai: '--wpbc-bfb-col-ai', |
| 115 |
gap: '--wpbc-bfb-col-gap', |
| 116 |
ac: '--wpbc-bfb-col-ac', |
| 117 |
aself: '--wpbc-bfb-col-aself' |
| 118 |
}; |
| 119 |
var parts = []; |
| 120 |
for (var k in obj) { |
| 121 |
if (!Object.prototype.hasOwnProperty.call(obj, k)) continue; |
| 122 |
var v = obj[k]; |
| 123 |
if (v == null || v === '') continue; |
| 124 |
var var_name = map[k] || '--wpbc-bfb-col-' + String(k).replace(/[^a-z0-9_-]/gi, '').toLowerCase(); |
| 125 |
parts.push(var_name + ': ' + String(v)); |
| 126 |
} |
| 127 |
|
| 128 |
// Always include explicit min guard (requested): --wpbc-col-min: 0px; |
| 129 |
parts.push('--wpbc-col-min: 0px'); |
| 130 |
return parts.join(';') + (parts.length ? ';' : ''); |
| 131 |
} |
| 132 |
|
| 133 |
/** |
| 134 |
* Resolve numeric percent from a width token like "48.5%". |
| 135 |
* Falls back to `fallback_percent` if not in percent format. |
| 136 |
* |
| 137 |
* @param {string|number|undefined|null} width_token |
| 138 |
* @param {number} fallback_percent |
| 139 |
* @returns {number} |
| 140 |
*/ |
| 141 |
function resolve_flex_basis_percent(width_token, fallback_percent) { |
| 142 |
if (typeof width_token === 'string') { |
| 143 |
var s = width_token.trim(); |
| 144 |
if (s.endsWith('%')) { |
| 145 |
var p = parseFloat(s); |
| 146 |
if (isFinite(p)) return p; |
| 147 |
} |
| 148 |
} |
| 149 |
if (typeof width_token === 'number' && isFinite(width_token)) { |
| 150 |
return width_token; |
| 151 |
} |
| 152 |
return fallback_percent; |
| 153 |
} |
| 154 |
|
| 155 |
/** |
| 156 |
* Compute effective flex-basis values that respect inter-column gap |
| 157 |
* |
| 158 |
* @param columns |
| 159 |
* @param gap_percent |
| 160 |
* @returns {*} |
| 161 |
*/ |
| 162 |
function compute_effective_bases(columns, gap_percent = 3) { |
| 163 |
const n = columns && columns.length ? columns.length : 1; |
| 164 |
const raw = columns.map(col => { |
| 165 |
const w = col && col.width != null ? String(col.width).trim() : ''; |
| 166 |
const p = w.endsWith('%') ? parseFloat(w) : w ? parseFloat(w) : NaN; |
| 167 |
return Number.isFinite(p) ? p : 100 / n; |
| 168 |
}); |
| 169 |
const sum_raw = raw.reduce((a, b) => a + b, 0) || 100; |
| 170 |
const gp = Number.isFinite(+gap_percent) ? +gap_percent : 3; |
| 171 |
const total_gaps = Math.max(0, n - 1) * gp; |
| 172 |
const available = Math.max(0, 100 - total_gaps); |
| 173 |
const scale_ratio = available / sum_raw; |
| 174 |
return raw.map(p => Math.max(0, p * scale_ratio)); |
| 175 |
} |
| 176 |
|
| 177 |
// == adapter: builder (array-of-pages) > exporter shape { pages: [ { items:[ {kind,data} ] } ] } ================== |
| 178 |
function adapt_builder_structure_to_exporter(structure) { |
| 179 |
// if ( !Array.isArray( structure ) ) return { pages: [] }; |
| 180 |
|
| 181 |
// Ensure at least one page exists, even when Builder structure is empty `[]`. |
| 182 |
// This keeps exported Advanced Form valid (wizard step #1 exists). |
| 183 |
if (!Array.isArray(structure) || structure.length === 0) { |
| 184 |
return { |
| 185 |
pages: [{ |
| 186 |
items: [] |
| 187 |
}] |
| 188 |
}; |
| 189 |
} |
| 190 |
const normalize_options = opts => { |
| 191 |
if (!Array.isArray(opts)) return []; |
| 192 |
return opts.map(o => { |
| 193 |
if (typeof o === 'string') return { |
| 194 |
label: o, |
| 195 |
value: o, |
| 196 |
selected: false |
| 197 |
}; |
| 198 |
if (o && typeof o === 'object') { |
| 199 |
return { |
| 200 |
label: String(o.label ?? o.value ?? ''), |
| 201 |
value: String(o.value ?? o.label ?? ''), |
| 202 |
selected: !!o.selected |
| 203 |
}; |
| 204 |
} |
| 205 |
return { |
| 206 |
label: String(o), |
| 207 |
value: String(o), |
| 208 |
selected: false |
| 209 |
}; |
| 210 |
}); |
| 211 |
}; |
| 212 |
|
| 213 |
// ================================================================================================= |
| 214 |
// == Adapter – attach parsed per-column `col_styles` from Section into each column |
| 215 |
// ================================================================================================= |
| 216 |
const walk_section = sec => { |
| 217 |
const section_col_styles = parse_col_styles_json(sec && sec.col_styles); |
| 218 |
return { |
| 219 |
id: sec?.id, |
| 220 |
columns: (sec?.columns || []).map((col, col_index) => { |
| 221 |
const items = Array.isArray(col?.items) ? col.items : [...(col?.fields || []).map(f => ({ |
| 222 |
type: 'field', |
| 223 |
data: f |
| 224 |
})), ...(col?.sections || []).map(s => ({ |
| 225 |
type: 'section', |
| 226 |
data: s |
| 227 |
}))]; |
| 228 |
const fields = items.filter(it => it && it.type === 'field').map(it => ({ |
| 229 |
...it.data, |
| 230 |
options: normalize_options(it.data?.options) |
| 231 |
})); |
| 232 |
const sections = items.filter(it => it && it.type === 'section').map(it => walk_section(it.data)); |
| 233 |
return { |
| 234 |
width: col?.width || '100%', |
| 235 |
style: col?.style || null, |
| 236 |
col_styles: section_col_styles[col_index] || null, |
| 237 |
// <- attach style object per column |
| 238 |
fields, |
| 239 |
sections |
| 240 |
}; |
| 241 |
}) |
| 242 |
}; |
| 243 |
}; |
| 244 |
const pages = structure.map(page => { |
| 245 |
const items = []; |
| 246 |
(page?.content || []).forEach(item => { |
| 247 |
if (!item) return; |
| 248 |
if (item.type === 'section' && item.data) { |
| 249 |
items.push({ |
| 250 |
kind: 'section', |
| 251 |
data: walk_section(item.data) |
| 252 |
}); |
| 253 |
} else if (item.type === 'field' && item.data) { |
| 254 |
items.push({ |
| 255 |
kind: 'field', |
| 256 |
data: { |
| 257 |
...item.data, |
| 258 |
options: normalize_options(item.data.options) |
| 259 |
} |
| 260 |
}); |
| 261 |
} |
| 262 |
}); |
| 263 |
return { |
| 264 |
items |
| 265 |
}; |
| 266 |
}); |
| 267 |
return { |
| 268 |
pages |
| 269 |
}; |
| 270 |
} |
| 271 |
|
| 272 |
// == Booking From Exporter ======================================================================================== |
| 273 |
class WPBC_BFB_Exporter { |
| 274 |
/** |
| 275 |
* Mutable skip-list for attribute names (lowercase). |
| 276 |
* You can override it via set_skip_attrs() or add with add_skip_attrs(). |
| 277 |
* @type {Set<string>} |
| 278 |
*/ |
| 279 |
static skip_attrs = new Set(); |
| 280 |
|
| 281 |
/** |
| 282 |
* Replace the entire skip list. |
| 283 |
* @param {string[]} arr |
| 284 |
*/ |
| 285 |
static set_skip_attrs(arr) { |
| 286 |
this.skip_attrs = new Set((Array.isArray(arr) ? arr : []).map(n => String(n).toLowerCase().trim()).filter(Boolean)); |
| 287 |
} |
| 288 |
|
| 289 |
/** |
| 290 |
* Add one or many attributes to the skip list. |
| 291 |
* @param {string|string[]} names |
| 292 |
*/ |
| 293 |
static add_skip_attrs(names) { |
| 294 |
(Array.isArray(names) ? names : [names]).map(n => String(n).toLowerCase().trim()).filter(Boolean).forEach(n => this.skip_attrs.add(n)); |
| 295 |
} |
| 296 |
|
| 297 |
/** |
| 298 |
* Remove one attribute from the skip list. |
| 299 |
* @param {string} name |
| 300 |
*/ |
| 301 |
static remove_skip_attr(name) { |
| 302 |
if (!name) { |
| 303 |
return; |
| 304 |
} |
| 305 |
this.skip_attrs.delete(String(name).toLowerCase().trim()); |
| 306 |
} |
| 307 |
|
| 308 |
/** |
| 309 |
* Apply attribute skipping to a final HTML string. |
| 310 |
* @param {string} html |
| 311 |
* @return {string} |
| 312 |
*/ |
| 313 |
static sanitize_export(html) { |
| 314 |
return strip_attributes_from_markup(html, Array.from(this.skip_attrs)); |
| 315 |
} |
| 316 |
|
| 317 |
/** |
| 318 |
* Export adapted structure to advanced form text (with <r>/<c> layout and wizard wrapper). |
| 319 |
* |
| 320 |
* @param {Object} adapted |
| 321 |
* @param {Object} [options] |
| 322 |
* @param {string} [options.newline="\n"] |
| 323 |
* @param {boolean} [options.addLabels=true] |
| 324 |
* @param {number} [options.gapPercent=3] |
| 325 |
* @returns {string} |
| 326 |
*/ |
| 327 |
static export_form(adapted, options = {}) { |
| 328 |
// indent: use real TAB by default (can be overridden via options.indent) |
| 329 |
const cfg = { |
| 330 |
newline: '\n', |
| 331 |
addLabels: true, |
| 332 |
gapPercent: 3, |
| 333 |
indent: '\t', |
| 334 |
...options |
| 335 |
}; |
| 336 |
const IND = typeof cfg.indent === 'string' ? cfg.indent : '\t'; |
| 337 |
let depth = 0; |
| 338 |
const lines = []; |
| 339 |
const push = (s = '') => lines.push(IND.repeat(depth) + String(s)); |
| 340 |
const open = (s = '') => { |
| 341 |
push(s); |
| 342 |
depth++; |
| 343 |
}; |
| 344 |
const close = (s = '') => { |
| 345 |
depth = Math.max(0, depth - 1); |
| 346 |
push(s); |
| 347 |
}; |
| 348 |
const blank = () => { |
| 349 |
lines.push(''); |
| 350 |
}; |
| 351 |
if (!adapted || !Array.isArray(adapted.pages)) return ''; |
| 352 |
|
| 353 |
// Always export at least one wizard step to keep Advanced Form structure valid. |
| 354 |
const pages = adapted.pages.length ? adapted.pages : [{ |
| 355 |
items: [] |
| 356 |
}]; |
| 357 |
const ctx = { |
| 358 |
usedIds: new Set() |
| 359 |
}; |
| 360 |
open(`<div class="wpbc_bfb_form wpbc_wizard__border_container">`); |
| 361 |
|
| 362 |
// one-per-form guards (calendar is not gated here) |
| 363 |
const once = { |
| 364 |
captcha: 0, |
| 365 |
country: 0, |
| 366 |
coupon: 0, |
| 367 |
cost_corrections: 0, |
| 368 |
submit: 0 |
| 369 |
}; |
| 370 |
pages.forEach((page, page_index) => { |
| 371 |
const is_first = page_index === 0; |
| 372 |
const step_num = page_index + 1; |
| 373 |
const hidden_class = is_first ? '' : ' wpbc_wizard_step_hidden'; |
| 374 |
const hidden_style = is_first ? '' : ' style="display:none;clear:both;"'; |
| 375 |
open(`<div class="wpbc_wizard_step wpbc__form__div wpbc_wizard_step${step_num}${hidden_class}"${hidden_style}>`); |
| 376 |
(page.items || []).forEach(item => { |
| 377 |
if (item.kind === 'section') { |
| 378 |
WPBC_BFB_Exporter.render_section(item.data, { |
| 379 |
open, |
| 380 |
close, |
| 381 |
push, |
| 382 |
blank |
| 383 |
}, cfg, once, ctx); |
| 384 |
// blank(); |
| 385 |
} else if (item.kind === 'field') { |
| 386 |
open(`<r>`); |
| 387 |
open(`<c>`); |
| 388 |
WPBC_BFB_Exporter.render_field_node(item.data, { |
| 389 |
open, |
| 390 |
close, |
| 391 |
push, |
| 392 |
blank |
| 393 |
}, cfg, once, ctx); |
| 394 |
close(`</c>`); |
| 395 |
close(`</r>`); |
| 396 |
// blank(); |
| 397 |
} |
| 398 |
}); |
| 399 |
close(`</div>`); |
| 400 |
}); |
| 401 |
close(`</div>`); |
| 402 |
return WPBC_BFB_Exporter.sanitize_export(lines.join(cfg.newline)); |
| 403 |
} |
| 404 |
|
| 405 |
/** |
| 406 |
* High-level helper: export full package from raw Builder structure. |
| 407 |
* |
| 408 |
* - Adapts raw Builder structure (pages/sections/columns/items) for exporters. |
| 409 |
* - Builds: |
| 410 |
* • advanced_form -> “Advanced Form (export)” text. |
| 411 |
* • fields_data -> “Content of booking fields data (export)” text. |
| 412 |
* |
| 413 |
* @param {Array} structure Raw Builder structure from wpbc_bfb.get_structure(). |
| 414 |
* @param {Object} [options] |
| 415 |
* @param {number} [options.gapPercent=3] Column gap percent for layout math. |
| 416 |
* |
| 417 |
* @returns {{ |
| 418 |
* advanced_form: string, |
| 419 |
* fields_data: string, |
| 420 |
* structure: Array, |
| 421 |
* adapted: Object |
| 422 |
* }} |
| 423 |
*/ |
| 424 |
static export_all(structure, options = {}) { |
| 425 |
// 1) Adapt Builder JSON to exporter shape (pages[] -> items[]). |
| 426 |
const adapted = adapt_builder_structure_to_exporter(structure || []); |
| 427 |
|
| 428 |
// 2) Advanced Form text (same logic as debug panel). |
| 429 |
const gap_percent = options && typeof options.gapPercent === 'number' ? options.gapPercent : 3; |
| 430 |
const advanced_form = WPBC_BFB_Exporter.export_form(adapted, { |
| 431 |
addLabels: true, |
| 432 |
gapPercent: gap_percent |
| 433 |
}); |
| 434 |
|
| 435 |
// 3) Content of booking fields data (if content exporter is available). |
| 436 |
let fields_data = ''; |
| 437 |
if (window.WPBC_BFB_ContentExporter && typeof window.WPBC_BFB_ContentExporter.export_content === 'function') { |
| 438 |
fields_data = window.WPBC_BFB_ContentExporter.export_content(adapted, { |
| 439 |
addLabels: true, |
| 440 |
sep: ': ' |
| 441 |
}); |
| 442 |
} |
| 443 |
return { |
| 444 |
advanced_form: advanced_form || '', |
| 445 |
fields_data: fields_data || '', |
| 446 |
structure: structure || [], |
| 447 |
adapted: adapted |
| 448 |
}; |
| 449 |
} |
| 450 |
|
| 451 |
// ================================================================================================= |
| 452 |
// == Exporter – render_section() now injects per-column CSS vars from `col_styles` |
| 453 |
// ================================================================================================= |
| 454 |
static render_section(section, io, cfg, once, ctx) { |
| 455 |
once = once || { |
| 456 |
captcha: 0, |
| 457 |
country: 0, |
| 458 |
coupon: 0, |
| 459 |
cost_corrections: 0, |
| 460 |
submit: 0 |
| 461 |
}; |
| 462 |
ctx = ctx || { |
| 463 |
usedIds: new Set() |
| 464 |
}; |
| 465 |
const { |
| 466 |
open, |
| 467 |
close |
| 468 |
} = io; |
| 469 |
const cols = Array.isArray(section.columns) && section.columns.length ? section.columns : [{ |
| 470 |
width: '100%', |
| 471 |
fields: [], |
| 472 |
sections: [] |
| 473 |
}]; |
| 474 |
|
| 475 |
// Row is active if ANY column carries styles. |
| 476 |
var row_is_active = cols.some(function (col) { |
| 477 |
return has_non_default_col_styles(col && col.col_styles); |
| 478 |
}); |
| 479 |
var row_attr_active = row_is_active ? ' data-colstyles-active="1"' : ''; |
| 480 |
open(`<r${row_attr_active}>`); |
| 481 |
const bases = compute_effective_bases(cols, cfg.gapPercent); |
| 482 |
const esc_attr = core.WPBC_BFB_Sanitize.escape_html; |
| 483 |
cols.forEach((col, idx) => { |
| 484 |
// (1) Resolve flex-basis. |
| 485 |
var eff_basis = resolve_flex_basis_percent(col && col.width, Number.isFinite(bases[idx]) ? +bases[idx] : 100); |
| 486 |
|
| 487 |
// (2) Build inline style. |
| 488 |
var style_parts = []; |
| 489 |
if (col && typeof col.style === 'string' && col.style.trim()) { |
| 490 |
style_parts.push(col.style.trim().replace(/;+\s*$/, '')); |
| 491 |
} |
| 492 |
style_parts.push('flex-basis: ' + (Number.isFinite(eff_basis) ? eff_basis.toString() : '100') + '%'); |
| 493 |
var css_vars_str = build_col_css_vars(col && col.col_styles); |
| 494 |
if (css_vars_str) { |
| 495 |
style_parts.push(css_vars_str.replace(/^;|;$/g, '')); |
| 496 |
} |
| 497 |
var style_attr = ` style="${esc_attr(style_parts.join('; '))}"`; |
| 498 |
|
| 499 |
// (3) Column-level activation (more precise scoping) |
| 500 |
var col_is_active = has_non_default_col_styles(col && col.col_styles); |
| 501 |
var col_attr_active = col_is_active ? ' data-colstyles-active="1"' : ''; |
| 502 |
open(`<c${col_attr_active}${style_attr}>`); |
| 503 |
|
| 504 |
// Use the shared once/ctx objects so single-per-form guards work across the whole form. |
| 505 |
(col.fields || []).forEach(node => WPBC_BFB_Exporter.render_field_node(node, io, cfg, once, ctx)); |
| 506 |
|
| 507 |
// Recurse with the same once/ctx as well. |
| 508 |
(col.sections || []).forEach(nested => WPBC_BFB_Exporter.render_section(nested, io, cfg, once, ctx)); |
| 509 |
close(`</c>`); |
| 510 |
}); |
| 511 |
close(`</r>`); |
| 512 |
} |
| 513 |
|
| 514 |
/** |
| 515 |
* Build attribute string for the <item> wrapper. |
| 516 |
* Currently only used for CAPTCHA: pushes css classes and html_id to the wrapper. |
| 517 |
* Also ensures uniqueness of the html_id across the export (uses ctx.usedIds). |
| 518 |
* |
| 519 |
* @param {Object} field |
| 520 |
* @param {{usedIds:Set<string>}} ctx |
| 521 |
* @returns {string} e.g. ' class="x y" id="myId"' |
| 522 |
*/ |
| 523 |
static item_wrapper_attrs(field, ctx) { |
| 524 |
if (!field) { |
| 525 |
return ''; |
| 526 |
} |
| 527 |
const esc_html = core.WPBC_BFB_Sanitize.escape_html; |
| 528 |
const cls_sanit = core.WPBC_BFB_Sanitize.sanitize_css_classlist; |
| 529 |
const sid = core.WPBC_BFB_Sanitize.sanitize_html_id; |
| 530 |
let out = ''; |
| 531 |
const cls_raw = String(field.cssclass_extra || field.cssclass || field.class || ''); |
| 532 |
const cls = cls_sanit(cls_raw); |
| 533 |
let html_id = field.html_id ? sid(String(field.html_id)) : ''; |
| 534 |
if (html_id && ctx?.usedIds) { |
| 535 |
let unique = html_id, |
| 536 |
i = 2; |
| 537 |
while (ctx.usedIds.has(unique)) { |
| 538 |
unique = `${html_id}_${i++}`; |
| 539 |
} |
| 540 |
ctx.usedIds.add(unique); |
| 541 |
html_id = unique; |
| 542 |
} |
| 543 |
if (cls) { |
| 544 |
out += ` class="${esc_html(cls)}"`; |
| 545 |
} |
| 546 |
if (html_id) { |
| 547 |
out += ` id="${esc_html(html_id)}"`; |
| 548 |
} |
| 549 |
return out; |
| 550 |
} |
| 551 |
|
| 552 |
// ================================================================================================= |
| 553 |
// == Fields – pluggable, pack-driven export |
| 554 |
// == Wrap every exported field inside <item>…</item> and delegate actual shortcode export |
| 555 |
// == to per-pack callbacks registered via WPBC_BFB_Exporter.register(type, fn). |
| 556 |
// ================================================================================================= |
| 557 |
static render_field_node(field, io, cfg, once, ctx) { |
| 558 |
const { |
| 559 |
open, |
| 560 |
close, |
| 561 |
push |
| 562 |
} = io; |
| 563 |
if (!field || !field.type) { |
| 564 |
return; |
| 565 |
} |
| 566 |
|
| 567 |
// Shared context (usedIds, “once-per-form” guards, etc.). |
| 568 |
once = once || {}; |
| 569 |
ctx = ctx || { |
| 570 |
usedIds: new Set() |
| 571 |
}; |
| 572 |
const type = String(field.type).toLowerCase(); |
| 573 |
|
| 574 |
// Optional wrapper attrs for special types (currently only used by captcha). |
| 575 |
let item_attrs = ''; |
| 576 |
if (type === 'captcha') { |
| 577 |
item_attrs = WPBC_BFB_Exporter.item_wrapper_attrs(field, ctx); |
| 578 |
} |
| 579 |
open(`<item${item_attrs}>`); |
| 580 |
try { |
| 581 |
// 1) Let the corresponding field pack handle export. |
| 582 |
let handled = false; |
| 583 |
if (WPBC_BFB_Exporter.has_exporter(type)) { |
| 584 |
handled = WPBC_BFB_Exporter.run_registered_exporter(field, io, cfg, once, ctx); |
| 585 |
} |
| 586 |
|
| 587 |
// 2) Fallback: show a clear TODO comment if no exporter is registered. |
| 588 |
if (!handled) { |
| 589 |
const name = WPBC_BFB_Exporter.compute_name(type, field); |
| 590 |
push(`<!-- TODO: map field type "${type}" name="${name}" in a pack exporter -->`); |
| 591 |
} |
| 592 |
|
| 593 |
// 3) Append help text consistently (packs shouldn’t duplicate this). |
| 594 |
if (field.help) { |
| 595 |
push(`<div class="wpbc_field_description">${core.WPBC_BFB_Sanitize.escape_html(String(field.help))}</div>`); |
| 596 |
} |
| 597 |
} finally { |
| 598 |
// Always close wrapper. |
| 599 |
close(`</item>`); |
| 600 |
} |
| 601 |
} |
| 602 |
|
| 603 |
// ================================================================================================= |
| 604 |
// == Helpers == |
| 605 |
// ================================================================================================= |
| 606 |
static is_required(field) { |
| 607 |
const v = field && field.required; |
| 608 |
return v === true || v === 'true' || v === 1 || v === '1' || v === 'required'; |
| 609 |
} |
| 610 |
|
| 611 |
/** |
| 612 |
* Shared label emitter used by per-pack exporters. |
| 613 |
* |
| 614 |
* Emits optional <l>Label</l> + <br> before the provided body, |
| 615 |
* respecting cfg.addLabels. Help text is emitted centrally in |
| 616 |
* render_field_node(), so it is intentionally NOT handled here. |
| 617 |
* |
| 618 |
* @param {Object} field |
| 619 |
* @param {function(string): void} emit |
| 620 |
* @param {string} body |
| 621 |
* @param {{addLabels?: boolean}} [cfg] |
| 622 |
*/ |
| 623 |
static emit_label_then(field, emit, body, cfg) { |
| 624 |
if (typeof emit !== 'function') { |
| 625 |
return; |
| 626 |
} |
| 627 |
cfg = cfg || {}; |
| 628 |
const addLabels = cfg.addLabels !== false; |
| 629 |
const raw = field && typeof field.label === 'string' ? field.label : ''; |
| 630 |
const label = raw.trim(); |
| 631 |
var is_req = this.is_required(field); |
| 632 |
var req_mark = is_req ? '*' : ''; |
| 633 |
if (label && addLabels) { |
| 634 |
const esc_html = core.WPBC_BFB_Sanitize.escape_html; |
| 635 |
emit('<l>' + esc_html(label) + req_mark + '</l>'); |
| 636 |
emit('<br>' + body); |
| 637 |
} else { |
| 638 |
emit(body); |
| 639 |
} |
| 640 |
} |
| 641 |
|
| 642 |
// ================================================================================================= |
| 643 |
// == Helpers == |
| 644 |
// ================================================================================================= |
| 645 |
|
| 646 |
// -- Time Select Helpers -------------------------------------------------------------------------------------- |
| 647 |
static is_timeslot_picker_enabled() { |
| 648 |
try { |
| 649 |
return !!(window._wpbc && typeof window._wpbc.get_other_param === 'function' && window._wpbc.get_other_param('is_enabled_booking_timeslot_picker')); |
| 650 |
} catch (_) { |
| 651 |
return false; |
| 652 |
} |
| 653 |
} |
| 654 |
static time_placeholder_for(name, field) { |
| 655 |
// Prefer field-specific placeholder; else sensible default per field. |
| 656 |
if (typeof field.placeholder === 'string' && field.placeholder.trim()) { |
| 657 |
return field.placeholder.trim(); |
| 658 |
} |
| 659 |
if (name === 'durationtime') return '--- Select duration ---'; |
| 660 |
return '--- Select time ---'; |
| 661 |
} |
| 662 |
|
| 663 |
/** |
| 664 |
* Build tokens/default for a time-like select (start/end/range/duration). |
| 665 |
* - Adds an empty-value placeholder as the first option only when: |
| 666 |
* • time picker is OFF, and |
| 667 |
* • no option is selected by default, and |
| 668 |
* • there isn't already an empty-value option. |
| 669 |
*/ |
| 670 |
static build_time_select_tokens(field, name) { |
| 671 |
let tokens_str = this.option_tokens(field); |
| 672 |
let def_str = this.default_option_suffix(field, tokens_str); |
| 673 |
if (!this.is_timeslot_picker_enabled()) { |
| 674 |
const opts = Array.isArray(field.options) ? field.options : []; |
| 675 |
const has_selected_default = opts.some(o => o && (o.selected === true || o.selected === 'true' || o.selected === 1 || o.selected === '1')); |
| 676 |
if (!has_selected_default) { |
| 677 |
const has_empty_value_option = opts.some(o => o && typeof o.value !== 'undefined' && String(o.value).trim() === ''); |
| 678 |
if (!has_empty_value_option) { |
| 679 |
const phText = this.time_placeholder_for(name, field); |
| 680 |
const phTokenStr = '"' + core.WPBC_BFB_Sanitize.escape_for_shortcode(phText + '@@') + '"'; |
| 681 |
const other = this.option_tokens(field).trim(); // recompute, trim leading space |
| 682 |
tokens_str = ' ' + phTokenStr + (other ? ' ' + other : ''); |
| 683 |
|
| 684 |
// Ensure first option (our placeholder) becomes the default implicitly |
| 685 |
def_str = ''; |
| 686 |
} |
| 687 |
} |
| 688 |
} |
| 689 |
return { |
| 690 |
tokens_str, |
| 691 |
def_str |
| 692 |
}; |
| 693 |
} |
| 694 |
static emit_time_select(name, field, req_mark, id_opt, cls_opts, emit_label_then) { |
| 695 |
const { |
| 696 |
tokens_str, |
| 697 |
def_str |
| 698 |
} = this.build_time_select_tokens(field, name); |
| 699 |
// NOTE: No size/ph tokens here to mirror rangetime behavior exactly. |
| 700 |
emit_label_then(`[selectbox${req_mark} ${name}${id_opt}${cls_opts}${def_str}${tokens_str}]`); |
| 701 |
} |
| 702 |
|
| 703 |
// -- Other Helpers -------------------------------------------------------------------------------------------- |
| 704 |
// Return a field's default value (supports both camelCase and snake_case). |
| 705 |
static get_default_value(field) { |
| 706 |
const v = field?.default_value ?? field?.defaultValue ?? ''; |
| 707 |
return v == null ? '' : String(v); |
| 708 |
} |
| 709 |
|
| 710 |
// For text-like fields, the default is a final quoted token in the shortcode. |
| 711 |
static default_text_suffix(field) { |
| 712 |
const v = this.get_default_value(field); |
| 713 |
if (!v) return ''; |
| 714 |
return ` "${core.WPBC_BFB_Sanitize.escape_for_shortcode(v)}"`; |
| 715 |
} |
| 716 |
static class_options(field) { |
| 717 |
const raw = field.class || field.className || field.cssclass || ''; |
| 718 |
const cls = core.WPBC_BFB_Sanitize.sanitize_css_classlist(String(raw)); |
| 719 |
if (!cls) return ''; |
| 720 |
return cls.split(/\s+/).filter(Boolean).map(c => ` class:${core.WPBC_BFB_Sanitize.to_token(c)}`).join(''); |
| 721 |
} |
| 722 |
static id_option(field, ctx) { |
| 723 |
const raw_id = field.html_id || field.id_attr; |
| 724 |
if (!raw_id) return ''; |
| 725 |
const base = core.WPBC_BFB_Sanitize.to_token(raw_id); |
| 726 |
if (!base) return ''; |
| 727 |
let unique = base, |
| 728 |
i = 2; |
| 729 |
while (ctx.usedIds.has(unique)) unique = `${base}_${i++}`; |
| 730 |
ctx.usedIds.add(unique); |
| 731 |
return ` id:${unique}`; |
| 732 |
} |
| 733 |
static ph_attr(v) { |
| 734 |
if (v == null || v === '') return ''; |
| 735 |
return ` placeholder:"${core.WPBC_BFB_Sanitize.escape_for_attr_quoted(v)}"`; |
| 736 |
} |
| 737 |
|
| 738 |
// text-like size/maxlength token: "40/255" (or "40/" or "/255") |
| 739 |
static size_max_token(f) { |
| 740 |
const size = parseInt(f.size, 10); |
| 741 |
const max = parseInt(f.maxlength, 10); |
| 742 |
if (Number.isFinite(size) && Number.isFinite(max)) return ` ${size}/${max}`; |
| 743 |
if (Number.isFinite(size)) return ` ${size}/`; |
| 744 |
if (Number.isFinite(max)) return ` /${max}`; |
| 745 |
return ''; |
| 746 |
} |
| 747 |
|
| 748 |
// textarea cols/rows token: "60x4" (or "60x" or "x4") |
| 749 |
static cols_rows_token(f) { |
| 750 |
const cols = parseInt(f.cols, 10); |
| 751 |
const rows = parseInt(f.rows, 10); |
| 752 |
if (Number.isFinite(cols) && Number.isFinite(rows)) return ` ${cols}x${rows}`; |
| 753 |
if (Number.isFinite(cols)) return ` ${cols}x`; |
| 754 |
if (Number.isFinite(rows)) return ` x${rows}`; |
| 755 |
return ''; |
| 756 |
} |
| 757 |
static option_tokens(field) { |
| 758 |
const options = Array.isArray(field.options) ? field.options : []; |
| 759 |
if (options.length === 0) return ''; |
| 760 |
const parts = options.map(o => { |
| 761 |
const title = String(o.label ?? o.value ?? '').trim(); |
| 762 |
const value = String(o.value ?? o.label ?? '').trim(); |
| 763 |
return title && value && title !== value ? `"${core.WPBC_BFB_Sanitize.escape_for_shortcode(`${title}@@${value}`)}"` : `"${core.WPBC_BFB_Sanitize.escape_for_shortcode(title || value)}"`; |
| 764 |
}); |
| 765 |
return ' ' + parts.join(' '); |
| 766 |
} |
| 767 |
static default_option_suffix(field, tokens) { |
| 768 |
const options = Array.isArray(field.options) ? field.options : []; |
| 769 |
const selected = options.find(o => o.selected); |
| 770 |
const def_val = selected ? selected.value ?? selected.label : field.default_value ?? field.defaultValue ?? ''; |
| 771 |
if (!def_val) return ''; |
| 772 |
return ` default="${core.WPBC_BFB_Sanitize.escape_value_for_attr(def_val)}"`; |
| 773 |
} |
| 774 |
|
| 775 |
/** |
| 776 |
* SELECTBOX / RADIO - Build the final shortcode for choice-based fields. |
| 777 |
* |
| 778 |
* Responsibilities: |
| 779 |
* - Delegates option/default encoding to: |
| 780 |
* - WPBC_BFB_Exporter.option_tokens( field ) |
| 781 |
* - WPBC_BFB_Exporter.default_option_suffix( field, tokens ) |
| 782 |
* - For `radio`: |
| 783 |
* - ALWAYS appends a bare `use_label_element` token. |
| 784 |
* - For `selectbox`: |
| 785 |
* - Adds a bare `multiple` token when `field.multiple` is truthy |
| 786 |
* (true, "true", 1, "1", "multiple") -> `[selectbox services multiple "1" "2"]`. |
| 787 |
* - When single-select AND there is no `default="..."` attribute AND |
| 788 |
* a non-empty `field.placeholder` is present, encodes the placeholder |
| 789 |
* as the FIRST option with empty value via the `@@` syntax: |
| 790 |
* placeholder "---- Select ----" -> `"---- Select ----@@"` |
| 791 |
* and clears any default attribute: |
| 792 |
* [selectbox* services "--- Select ---@@" "Option 1" "Option 2"] |
| 793 |
* - Respects `field.use_label_element` (adds bare `use_label_element` when true). |
| 794 |
* - For both kinds: |
| 795 |
* - Honors `field.label_first` by appending `label_first:"1"` when truthy. |
| 796 |
* - Keeps the required star, id and cssclass tokens in the canonical order. |
| 797 |
* |
| 798 |
* Final shortcode layout (order is important): |
| 799 |
* [kind req name id cls use_label_element multiple default tokens label_first] |
| 800 |
* |
| 801 |
* @jDoc |
| 802 |
* @param {string} kind |
| 803 |
* Shortcode kind; typically "radio" or "selectbox". |
| 804 |
* |
| 805 |
* @param {string} req_mark |
| 806 |
* Required marker used by Contact Form 7 style shortcodes: |
| 807 |
* either "" (not required) or "*" (required). |
| 808 |
* |
| 809 |
* @param {string} name |
| 810 |
* Sanitized field name as exported into the shortcode, e.g. "services". |
| 811 |
* Must already be computed via WPBC_BFB_Exporter.compute_name(). |
| 812 |
* |
| 813 |
* @param {Object} field |
| 814 |
* Normalized field data object as stored in the Builder structure. Common keys: |
| 815 |
* - type {string} Field type, e.g. "radio" | "select". |
| 816 |
* - options {Array} Option objects: { label, value, selected }. |
| 817 |
* - placeholder {string} Placeholder text (single-select only). |
| 818 |
* - multiple {boolean|string|number} Enables multi-select when truthy. |
| 819 |
* - use_label_element {boolean} Request bare `use_label_element` token (non-radio). |
| 820 |
* - label_first {boolean} If true, appends `label_first:"1"` token. |
| 821 |
* - default_value {string} Optional default value (used by default_option_suffix()). |
| 822 |
* - html_id / cssclass / class / className {string} Used upstream in id_opt/cls_opts. |
| 823 |
* |
| 824 |
* @param {string} id_opt |
| 825 |
* Optional id token built by WPBC_BFB_Exporter.id_option(field, ctx), |
| 826 |
* e.g. " id:my_id" or empty string. |
| 827 |
* |
| 828 |
* @param {string} cls_opts |
| 829 |
* Class tokens built by WPBC_BFB_Exporter.class_options(field), |
| 830 |
* e.g. " class:my_class class:other". |
| 831 |
* |
| 832 |
* @returns {string} |
| 833 |
* Complete shortcode body for the choice field, for example: |
| 834 |
* "[radio* services use_label_element \"A\" \"B\"]" |
| 835 |
* "[selectbox services multiple \"1\" \"2\" \"3\"]" |
| 836 |
* "[selectbox* services \"--- Select ---@@\" \"Option 1\" \"Option 2\"]" |
| 837 |
*/ |
| 838 |
static choice_tag(kind, req_mark, name, field, id_opt, cls_opts) { |
| 839 |
// Start from the raw options/default as before. |
| 840 |
let tokens = WPBC_BFB_Exporter.option_tokens(field); |
| 841 |
let def = WPBC_BFB_Exporter.default_option_suffix(field, tokens); |
| 842 |
|
| 843 |
// For RADIO we must ALWAYS include a bare `use_label_element` token (no value/quotes). |
| 844 |
// For other kinds, keep backward compatibility: include only if explicitly set. |
| 845 |
let ule = ''; |
| 846 |
if (kind === 'radio') { |
| 847 |
ule = ' use_label_element'; |
| 848 |
} else if (field && field.use_label_element) { |
| 849 |
ule = ' use_label_element'; |
| 850 |
} |
| 851 |
|
| 852 |
// SELECTBOX-specific extras: |
| 853 |
// - "multiple" flag |
| 854 |
// - placeholder exported as FIRST OPTION when single-select and no default. |
| 855 |
let multiple_flag = ''; |
| 856 |
if (kind === 'selectbox' && field) { |
| 857 |
const multiple = field.multiple === true || field.multiple === 'true' || field.multiple === 1 || field.multiple === '1' || field.multiple === 'multiple'; |
| 858 |
if (multiple) { |
| 859 |
// Export bare "multiple" token as in: [selectbox services multiple "1" "2" "3"]. |
| 860 |
multiple_flag = ' multiple'; |
| 861 |
} else if (!def) { |
| 862 |
// Single-select + NO default selected: |
| 863 |
// export placeholder as the FIRST OPTION with empty value: |
| 864 |
// [selectbox* services "--- Select ---@@" "Option 1" "Option 2"] |
| 865 |
const rawPh = field.placeholder; |
| 866 |
const ph = typeof rawPh === 'string' ? rawPh.trim() : ''; |
| 867 |
if (ph) { |
| 868 |
const S = core.WPBC_BFB_Sanitize; |
| 869 |
const esc_sc = S && S.escape_for_shortcode ? S.escape_for_shortcode : v => String(v); |
| 870 |
const phToken = `"${esc_sc(ph + '@@')}"`; |
| 871 |
if (tokens && tokens.length) { |
| 872 |
// tokens already starts with a leading space. |
| 873 |
tokens = ' ' + phToken + tokens; |
| 874 |
} else { |
| 875 |
tokens = ' ' + phToken; |
| 876 |
} |
| 877 |
|
| 878 |
// Ensure there is still NO default attribute when using placeholder-as-option. |
| 879 |
def = ''; |
| 880 |
} |
| 881 |
} |
| 882 |
} |
| 883 |
|
| 884 |
// Optional: label_first stays as quoted flag when explicitly requested. |
| 885 |
const lf = field && field.label_first ? ' label_first:"1"' : ''; |
| 886 |
|
| 887 |
// IMPORTANT ORDER (per request): |
| 888 |
// [kind req name id cls use_label_element multiple default tokens label_first] |
| 889 |
// i.e. `use_label_element` (and select extras) come BEFORE default/tokens. |
| 890 |
return `[${kind}${req_mark} ${name}${id_opt}${cls_opts}${ule}${multiple_flag}${def}${tokens}${lf}]`; |
| 891 |
} |
| 892 |
static compute_name(type, field) { |
| 893 |
// Names are fully validated when the field is added to the canvas. |
| 894 |
// The exporter must therefore preserve them (apart from idempotent sanitization), otherwise existing forms can break. |
| 895 |
const Sanit = core.WPBC_BFB_Sanitize; |
| 896 |
const raw = field && (field.name || field.id) ? String(field.name || field.id) : String(type || 'field'); |
| 897 |
|
| 898 |
// Idempotent sanitization only – no auto-prefixing or renaming. |
| 899 |
const name = Sanit.sanitize_html_name(raw); |
| 900 |
|
| 901 |
// In the unlikely case sanitization returns an empty string, fall back to a sanitized type-based token. |
| 902 |
return name || Sanit.sanitize_html_name(String(type || 'field')); |
| 903 |
} |
| 904 |
|
| 905 |
/** |
| 906 |
* Register a per-field exporter. |
| 907 |
* |
| 908 |
* This is the ONLY place where field-specific shortcode markup should live. |
| 909 |
* Core stays generic; packs provide tiny plugins, for example: |
| 910 |
* |
| 911 |
* WPBC_BFB_Exporter.register( 'text', (field, emit, extras) => { ... } ); |
| 912 |
* |
| 913 |
* @jDoc |
| 914 |
* @param {string} type Field type key, e.g. 'steps_timeline' |
| 915 |
* @param {(field:any, emit:(code:string)=>void, extras?:{io?:any,cfg?:any,once?:any,ctx?:any,core?:any})=>void} |
| 916 |
* fn |
| 917 |
* @returns {void} |
| 918 |
*/ |
| 919 |
static register(type, fn) { |
| 920 |
if (!type || typeof fn !== 'function') { |
| 921 |
return; |
| 922 |
} |
| 923 |
if (!this.__registry) { |
| 924 |
this.__registry = new Map(); |
| 925 |
} |
| 926 |
this.__registry.set(String(type).toLowerCase(), fn); |
| 927 |
} |
| 928 |
|
| 929 |
/** |
| 930 |
* Unregister a previously registered exporter. |
| 931 |
* |
| 932 |
* @jDoc |
| 933 |
* @param {string} type |
| 934 |
* @returns {void} |
| 935 |
*/ |
| 936 |
static unregister(type) { |
| 937 |
if (!this.__registry || !type) { |
| 938 |
return; |
| 939 |
} |
| 940 |
this.__registry.delete(String(type).toLowerCase()); |
| 941 |
} |
| 942 |
|
| 943 |
/** |
| 944 |
* Check if an exporter exists for a given field type. |
| 945 |
* |
| 946 |
* @jDoc |
| 947 |
* @param {string} type |
| 948 |
* @returns {boolean} |
| 949 |
*/ |
| 950 |
static has_exporter(type) { |
| 951 |
return !!(this.__registry && this.__registry.has(String(type).toLowerCase())); |
| 952 |
} |
| 953 |
|
| 954 |
/** |
| 955 |
* Run a registered exporter for a field, if present. |
| 956 |
* Returns true if a registered exporter handled it. |
| 957 |
* |
| 958 |
* @jDoc |
| 959 |
* @param {any} field |
| 960 |
* @param {{open:Function,close:Function,push:Function,blank:Function}} io |
| 961 |
* @param {any} cfg |
| 962 |
* @param {any} once |
| 963 |
* @param {any} ctx |
| 964 |
* @returns {boolean} |
| 965 |
*/ |
| 966 |
static run_registered_exporter(field, io, cfg, once, ctx) { |
| 967 |
if (!field || !field.type || !this.__registry) { |
| 968 |
return false; |
| 969 |
} |
| 970 |
const key = String(field.type).toLowerCase(); |
| 971 |
const fn = this.__registry.get(key); |
| 972 |
if (typeof fn !== 'function') { |
| 973 |
return false; |
| 974 |
} |
| 975 |
try { |
| 976 |
// Minimal, consistent emit() bridge into our line buffer: |
| 977 |
const emit = code => { |
| 978 |
if (typeof code === 'string') { |
| 979 |
io.push(code); |
| 980 |
} |
| 981 |
}; |
| 982 |
fn(field, emit, { |
| 983 |
io, |
| 984 |
cfg, |
| 985 |
once, |
| 986 |
ctx, |
| 987 |
core |
| 988 |
}); |
| 989 |
return true; |
| 990 |
} catch (e) { |
| 991 |
_wpbc?.dev?.error?.('WPBC_BFB_Exporter.run_registered_exporter', e); |
| 992 |
return false; |
| 993 |
} |
| 994 |
} |
| 995 |
} |
| 996 |
|
| 997 |
// expose globally for packs (if not already). |
| 998 |
window.WPBC_BFB_Exporter = window.WPBC_BFB_Exporter || WPBC_BFB_Exporter; |
| 999 |
wpbc_bfb__dispatch_event_safe('wpbc:bfb:exporter-ready', {}); |
| 1000 |
|
| 1001 |
// Initialize default skip list; allow a global override array before export runs. |
| 1002 |
WPBC_BFB_Exporter.set_skip_attrs(window.WPBC_BFB_EXPORT_SKIP_ATTRS || wpbc_export_skip_attrs_default); |
| 1003 |
|
| 1004 |
// == "Content of booking fields data" Exporter ==================================================================== |
| 1005 |
|
| 1006 |
// – pack-extensible generator for "Content of booking fields data" ============================================ |
| 1007 |
// == Produces markup like: "<div class=\"standard-content-form\"><b>Title</b>: <f>[shortcode]</f><br> ... </div>" |
| 1008 |
// == Packs can override per type via: WPBC_BFB_ContentExporter.register('calendar', (field, emit, ctx)=>{...}) |
| 1009 |
// ================================================================================================= |
| 1010 |
class WPBC_BFB_ContentExporter { |
| 1011 |
static register(type, fn) { |
| 1012 |
if (!type || typeof fn !== 'function') return; |
| 1013 |
if (!this.__registry) this.__registry = new Map(); |
| 1014 |
this.__registry.set(String(type).toLowerCase(), fn); |
| 1015 |
} |
| 1016 |
static unregister(type) { |
| 1017 |
if (!this.__registry || !type) return; |
| 1018 |
this.__registry.delete(String(type).toLowerCase()); |
| 1019 |
} |
| 1020 |
static has_exporter(type) { |
| 1021 |
return !!(this.__registry && this.__registry.has(String(type).toLowerCase())); |
| 1022 |
} |
| 1023 |
static run_registered_exporter(field, emit, ctx) { |
| 1024 |
if (!field || !field.type || !this.__registry) return false; |
| 1025 |
const key = String(field.type).toLowerCase(); |
| 1026 |
const fn = this.__registry.get(key); |
| 1027 |
if (typeof fn !== 'function') return false; |
| 1028 |
try { |
| 1029 |
fn(field, emit, ctx || {}); |
| 1030 |
return true; |
| 1031 |
} catch (e) { |
| 1032 |
_wpbc?.dev?.error?.('WPBC_BFB_ContentExporter.run_registered_exporter', e); |
| 1033 |
return false; |
| 1034 |
} |
| 1035 |
} |
| 1036 |
|
| 1037 |
// === NEW: shared line formatter for "Content of booking fields data" === |
| 1038 |
static emit_line_bold_field(emit, label, token, cfg) { |
| 1039 |
const S = core.WPBC_BFB_Sanitize; |
| 1040 |
const sep = cfg && typeof cfg.sep === 'string' ? cfg.sep : ': '; |
| 1041 |
const addLabels = cfg && 'addLabels' in cfg ? !!cfg.addLabels : true; |
| 1042 |
const title = addLabels && label ? `<b>${S.escape_html(label)}</b>${sep}` : ''; |
| 1043 |
emit(`${title}<f>[${token}]</f><br>`); |
| 1044 |
} |
| 1045 |
|
| 1046 |
/** |
| 1047 |
* Export adapted structure to “content of booking fields data”. |
| 1048 |
* @param {{pages:Array}} adapted result of adapt_builder_structure_to_exporter() |
| 1049 |
* @param {{newline?:string, addLabels?:boolean, sep?:string}} options |
| 1050 |
* @returns {string} |
| 1051 |
*/ |
| 1052 |
static export_content(adapted, options = {}) { |
| 1053 |
const cfg = { |
| 1054 |
newline: '\n', |
| 1055 |
addLabels: true, |
| 1056 |
sep: ': ', |
| 1057 |
indent: '\t', |
| 1058 |
...options |
| 1059 |
}; |
| 1060 |
const IND = typeof cfg.indent === 'string' ? cfg.indent : '\t'; |
| 1061 |
let depth = 0; |
| 1062 |
const lines = []; |
| 1063 |
const push = (s = '') => lines.push(IND.repeat(depth) + String(s)); |
| 1064 |
const open = (s = '') => { |
| 1065 |
push(s); |
| 1066 |
depth++; |
| 1067 |
}; |
| 1068 |
const close = (s = '') => { |
| 1069 |
depth = Math.max(0, depth - 1); |
| 1070 |
push(s); |
| 1071 |
}; |
| 1072 |
const emit = s => { |
| 1073 |
if (typeof s !== 'string') { |
| 1074 |
return; |
| 1075 |
} |
| 1076 |
String(s).split(/\r?\n/).forEach(line => push(line)); |
| 1077 |
}; |
| 1078 |
if (!adapted || !Array.isArray(adapted.pages)) return ''; |
| 1079 |
const skipTypes = new Set(['captcha', 'submit', 'divider', 'wizard_nav', 'cost_corrections']); |
| 1080 |
const fallbackLine = field => { |
| 1081 |
const type = String(field.type || '').toLowerCase(); |
| 1082 |
const name = WPBC_BFB_Exporter.compute_name(type, field); |
| 1083 |
const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : name; |
| 1084 |
if (!name) return; |
| 1085 |
WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, name, cfg); |
| 1086 |
}; |
| 1087 |
|
| 1088 |
// Per-type sensible defaults (can be overridden by packs via register()) |
| 1089 |
const defaultContentFor = field => { |
| 1090 |
const type = String(field.type || '').toLowerCase(); |
| 1091 |
if (skipTypes.has(type)) return; |
| 1092 |
// Special cases out of the box: |
| 1093 |
if (type === 'calendar') { |
| 1094 |
const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : 'Dates'; |
| 1095 |
WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, 'dates', cfg); |
| 1096 |
return; |
| 1097 |
} |
| 1098 |
// time-like reserved names -> keep placeholder token equal to name |
| 1099 |
const reserved = String(field.name || field.id || '').toLowerCase(); |
| 1100 |
if (['rangetime', 'starttime', 'endtime', 'durationtime'].includes(reserved)) { |
| 1101 |
const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : reserved; |
| 1102 |
// Keep your special token for duration time in content: [durationtime_val] |
| 1103 |
const token = reserved === 'durationtime' ? 'durationtime_val' : reserved; |
| 1104 |
WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, token, cfg); |
| 1105 |
return; |
| 1106 |
} |
| 1107 |
// Fallback (text/email/tel/number/textarea/select/checkbox/radio etc.) |
| 1108 |
fallbackLine(field); |
| 1109 |
}; |
| 1110 |
|
| 1111 |
// Walk pages/sections/columns/fields (same order as form) |
| 1112 |
const walkSection = sec => { |
| 1113 |
(sec.columns || []).forEach(col => { |
| 1114 |
(col.fields || []).forEach(f => processField(f)); |
| 1115 |
(col.sections || []).forEach(s => walkSection(s)); |
| 1116 |
}); |
| 1117 |
}; |
| 1118 |
const processItem = item => { |
| 1119 |
if (!item) return; |
| 1120 |
if (item.kind === 'field') processField(item.data); |
| 1121 |
if (item.kind === 'section') walkSection(item.data); |
| 1122 |
}; |
| 1123 |
const processField = field => { |
| 1124 |
if (!field) return; |
| 1125 |
// allow packs to override: |
| 1126 |
if (WPBC_BFB_ContentExporter.run_registered_exporter(field, emit, { |
| 1127 |
cfg, |
| 1128 |
core |
| 1129 |
})) return; |
| 1130 |
defaultContentFor(field); |
| 1131 |
}; |
| 1132 |
|
| 1133 |
// Wrapper first -> inner lines will be TAB-indented |
| 1134 |
open(`<div class="standard-content-form">`); |
| 1135 |
adapted.pages.forEach(page => (page.items || []).forEach(processItem)); |
| 1136 |
close(`</div>`); |
| 1137 |
return lines.join(cfg.newline); |
| 1138 |
} |
| 1139 |
} |
| 1140 |
|
| 1141 |
// expose + ready event for packs to register their content exporters. |
| 1142 |
window.WPBC_BFB_ContentExporter = window.WPBC_BFB_ContentExporter || WPBC_BFB_ContentExporter; |
| 1143 |
wpbc_bfb__dispatch_event_safe('wpbc:bfb:content-exporter-ready', {}); |
| 1144 |
})(); |
| 1145 |
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvX291dC9leHBvcnQvYnVpbGRlci1leHBvcnRlci5qcyIsIm5hbWVzIjpbImNvcmUiLCJ3aW5kb3ciLCJXUEJDX0JGQl9Db3JlIiwid3BiY19leHBvcnRfc2tpcF9hdHRyc19kZWZhdWx0Iiwic3RyaXBfYXR0cmlidXRlc19mcm9tX21hcmt1cCIsImh0bWwiLCJhdHRyc19sb3dlcmNhc2UiLCJsZW5ndGgiLCJvdXQiLCJTdHJpbmciLCJyYXdOYW1lIiwibmFtZSIsInRvTG93ZXJDYXNlIiwidHJpbSIsImVzYyIsInJlcGxhY2UiLCJyZSIsIlJlZ0V4cCIsImhhc19ub25fZGVmYXVsdF9jb2xfc3R5bGVzIiwib2JqIiwia2V5cyIsImkiLCJrIiwicGFyc2VfY29sX3N0eWxlc19qc29uIiwicmF3IiwiQXJyYXkiLCJpc0FycmF5IiwiZmlsdGVyIiwieCIsImFyciIsIkpTT04iLCJwYXJzZSIsIl9lIiwiYnVpbGRfY29sX2Nzc192YXJzIiwibWFwIiwiZGlyIiwid3JhcCIsImpjIiwiYWkiLCJnYXAiLCJhYyIsImFzZWxmIiwicGFydHMiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ2IiwidmFyX25hbWUiLCJwdXNoIiwiam9pbiIsInJlc29sdmVfZmxleF9iYXNpc19wZXJjZW50Iiwid2lkdGhfdG9rZW4iLCJmYWxsYmFja19wZXJjZW50IiwicyIsImVuZHNXaXRoIiwicCIsInBhcnNlRmxvYXQiLCJpc0Zpbml0ZSIsImNvbXB1dGVfZWZmZWN0aXZlX2Jhc2VzIiwiY29sdW1ucyIsImdhcF9wZXJjZW50IiwibiIsImNvbCIsInciLCJ3aWR0aCIsIk5hTiIsIk51bWJlciIsInN1bV9yYXciLCJyZWR1Y2UiLCJhIiwiYiIsImdwIiwidG90YWxfZ2FwcyIsIk1hdGgiLCJtYXgiLCJhdmFpbGFibGUiLCJzY2FsZV9yYXRpbyIsImFkYXB0X2J1aWxkZXJfc3RydWN0dXJlX3RvX2V4cG9ydGVyIiwic3RydWN0dXJlIiwicGFnZXMiLCJpdGVtcyIsIm5vcm1hbGl6ZV9vcHRpb25zIiwib3B0cyIsIm8iLCJsYWJlbCIsInZhbHVlIiwic2VsZWN0ZWQiLCJ3YWxrX3NlY3Rpb24iLCJzZWMiLCJzZWN0aW9uX2NvbF9zdHlsZXMiLCJjb2xfc3R5bGVzIiwiaWQiLCJjb2xfaW5kZXgiLCJmaWVsZHMiLCJmIiwidHlwZSIsImRhdGEiLCJzZWN0aW9ucyIsIml0Iiwib3B0aW9ucyIsInN0eWxlIiwicGFnZSIsImNvbnRlbnQiLCJmb3JFYWNoIiwiaXRlbSIsImtpbmQiLCJXUEJDX0JGQl9FeHBvcnRlciIsInNraXBfYXR0cnMiLCJTZXQiLCJzZXRfc2tpcF9hdHRycyIsIkJvb2xlYW4iLCJhZGRfc2tpcF9hdHRycyIsIm5hbWVzIiwiYWRkIiwicmVtb3ZlX3NraXBfYXR0ciIsImRlbGV0ZSIsInNhbml0aXplX2V4cG9ydCIsImZyb20iLCJleHBvcnRfZm9ybSIsImFkYXB0ZWQiLCJjZmciLCJuZXdsaW5lIiwiYWRkTGFiZWxzIiwiZ2FwUGVyY2VudCIsImluZGVudCIsIklORCIsImRlcHRoIiwibGluZXMiLCJyZXBlYXQiLCJvcGVuIiwiY2xvc2UiLCJibGFuayIsImN0eCIsInVzZWRJZHMiLCJvbmNlIiwiY2FwdGNoYSIsImNvdW50cnkiLCJjb3Vwb24iLCJjb3N0X2NvcnJlY3Rpb25zIiwic3VibWl0IiwicGFnZV9pbmRleCIsImlzX2ZpcnN0Iiwic3RlcF9udW0iLCJoaWRkZW5fY2xhc3MiLCJoaWRkZW5fc3R5bGUiLCJyZW5kZXJfc2VjdGlvbiIsInJlbmRlcl9maWVsZF9ub2RlIiwiZXhwb3J0X2FsbCIsImFkdmFuY2VkX2Zvcm0iLCJmaWVsZHNfZGF0YSIsIldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlciIsImV4cG9ydF9jb250ZW50Iiwic2VwIiwic2VjdGlvbiIsImlvIiwiY29scyIsInJvd19pc19hY3RpdmUiLCJzb21lIiwicm93X2F0dHJfYWN0aXZlIiwiYmFzZXMiLCJlc2NfYXR0ciIsIldQQkNfQkZCX1Nhbml0aXplIiwiZXNjYXBlX2h0bWwiLCJpZHgiLCJlZmZfYmFzaXMiLCJzdHlsZV9wYXJ0cyIsInRvU3RyaW5nIiwiY3NzX3ZhcnNfc3RyIiwic3R5bGVfYXR0ciIsImNvbF9pc19hY3RpdmUiLCJjb2xfYXR0cl9hY3RpdmUiLCJub2RlIiwibmVzdGVkIiwiaXRlbV93cmFwcGVyX2F0dHJzIiwiZmllbGQiLCJlc2NfaHRtbCIsImNsc19zYW5pdCIsInNhbml0aXplX2Nzc19jbGFzc2xpc3QiLCJzaWQiLCJzYW5pdGl6ZV9odG1sX2lkIiwiY2xzX3JhdyIsImNzc2NsYXNzX2V4dHJhIiwiY3NzY2xhc3MiLCJjbGFzcyIsImNscyIsImh0bWxfaWQiLCJ1bmlxdWUiLCJoYXMiLCJpdGVtX2F0dHJzIiwiaGFuZGxlZCIsImhhc19leHBvcnRlciIsInJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyIiwiY29tcHV0ZV9uYW1lIiwiaGVscCIsImlzX3JlcXVpcmVkIiwicmVxdWlyZWQiLCJlbWl0X2xhYmVsX3RoZW4iLCJlbWl0IiwiYm9keSIsImlzX3JlcSIsInJlcV9tYXJrIiwiaXNfdGltZXNsb3RfcGlja2VyX2VuYWJsZWQiLCJfd3BiYyIsImdldF9vdGhlcl9wYXJhbSIsIl8iLCJ0aW1lX3BsYWNlaG9sZGVyX2ZvciIsInBsYWNlaG9sZGVyIiwiYnVpbGRfdGltZV9zZWxlY3RfdG9rZW5zIiwidG9rZW5zX3N0ciIsIm9wdGlvbl90b2tlbnMiLCJkZWZfc3RyIiwiZGVmYXVsdF9vcHRpb25fc3VmZml4IiwiaGFzX3NlbGVjdGVkX2RlZmF1bHQiLCJoYXNfZW1wdHlfdmFsdWVfb3B0aW9uIiwicGhUZXh0IiwicGhUb2tlblN0ciIsImVzY2FwZV9mb3Jfc2hvcnRjb2RlIiwib3RoZXIiLCJlbWl0X3RpbWVfc2VsZWN0IiwiaWRfb3B0IiwiY2xzX29wdHMiLCJnZXRfZGVmYXVsdF92YWx1ZSIsImRlZmF1bHRfdmFsdWUiLCJkZWZhdWx0VmFsdWUiLCJkZWZhdWx0X3RleHRfc3VmZml4IiwiY2xhc3Nfb3B0aW9ucyIsImNsYXNzTmFtZSIsInNwbGl0IiwiYyIsInRvX3Rva2VuIiwiaWRfb3B0aW9uIiwicmF3X2lkIiwiaWRfYXR0ciIsImJhc2UiLCJwaF9hdHRyIiwiZXNjYXBlX2Zvcl9hdHRyX3F1b3RlZCIsInNpemVfbWF4X3Rva2VuIiwic2l6ZSIsInBhcnNlSW50IiwibWF4bGVuZ3RoIiwiY29sc19yb3dzX3Rva2VuIiwicm93cyIsInRpdGxlIiwidG9rZW5zIiwiZmluZCIsImRlZl92YWwiLCJlc2NhcGVfdmFsdWVfZm9yX2F0dHIiLCJjaG9pY2VfdGFnIiwiZGVmIiwidWxlIiwidXNlX2xhYmVsX2VsZW1lbnQiLCJtdWx0aXBsZV9mbGFnIiwibXVsdGlwbGUiLCJyYXdQaCIsInBoIiwiUyIsImVzY19zYyIsInBoVG9rZW4iLCJsZiIsImxhYmVsX2ZpcnN0IiwiU2FuaXQiLCJzYW5pdGl6ZV9odG1sX25hbWUiLCJyZWdpc3RlciIsImZuIiwiX19yZWdpc3RyeSIsIk1hcCIsInNldCIsInVucmVnaXN0ZXIiLCJrZXkiLCJnZXQiLCJjb2RlIiwiZSIsImRldiIsImVycm9yIiwid3BiY19iZmJfX2Rpc3BhdGNoX2V2ZW50X3NhZmUiLCJXUEJDX0JGQl9FWFBPUlRfU0tJUF9BVFRSUyIsImVtaXRfbGluZV9ib2xkX2ZpZWxkIiwidG9rZW4iLCJsaW5lIiwic2tpcFR5cGVzIiwiZmFsbGJhY2tMaW5lIiwiZGVmYXVsdENvbnRlbnRGb3IiLCJyZXNlcnZlZCIsImluY2x1ZGVzIiwid2Fsa1NlY3Rpb24iLCJwcm9jZXNzRmllbGQiLCJwcm9jZXNzSXRlbSJdLCJzb3VyY2VzIjpbImluY2x1ZGVzL3BhZ2UtZm9ybS1idWlsZGVyL19zcmMvZXhwb3J0L2J1aWxkZXItZXhwb3J0ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBmaWxlOiAuLi9pbmNsdWRlcy9wYWdlLWZvcm0tYnVpbGRlci9fb3V0L2V4cG9ydC9idWlsZGVyLWV4cG9ydGVyLmpzXHJcbiAqL1xyXG4oZnVuY3Rpb24gKCkge1xyXG5cdFwidXNlIHN0cmljdFwiO1xyXG5cclxuXHRjb25zdCBjb3JlID0gd2luZG93LldQQkNfQkZCX0NvcmUgfHwge307XHJcblxyXG5cdC8vID09IEhlbHBlcnMg4oCUIFNoYXJlZCBoZWxwZXIgQVBJIGZvciBmaWVsZCBwYWNrcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0Ly8gPT0gVGhlc2UgYXJlIGdlbmVyaWMgdXRpbGl0aWVzIHRoYXQgcGFja3MgY2FuIGNhbGwgZnJvbSB0aGVpciBvd24gZXhwb3J0ZXJzOlxyXG5cdC8vID09ICAtIGNvbXB1dGVfbmFtZSgpLCBpZF9vcHRpb24oKSwgY2xhc3Nfb3B0aW9ucygpLCBzaXplX21heF90b2tlbigpLCBlbWl0X3RpbWVfc2VsZWN0KCksIGV0Yy5cclxuXHQvLyA9PSBObyBmaWVsZC10eXBlIGJyYW5jaGluZyBzaG91bGQgbGl2ZSBpbiB0aGUgY29yZSBleHBvcnRlci5cclxuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG5cdC8qKlxyXG5cdCAqIERlZmF1bHQgc2tpcCBsaXN0IChjYW4gYmUgZXh0ZW5kZWQvb3ZlcnJpZGRlbiBhdCBydW50aW1lKS5cclxuXHQgKiAtIE9ubHkgYXR0cmlidXRlIE5BTUVTIGhlcmUgKGNhc2UtaW5zZW5zaXRpdmUpLiBWYWx1ZXMgYXJlIHJlbW92ZWQgd2l0aCB0aGVtLlxyXG5cdCAqL1xyXG5cdGNvbnN0IHdwYmNfZXhwb3J0X3NraXBfYXR0cnNfZGVmYXVsdCA9IFsgJ2RhdGEtY29sc3R5bGVzLWFjdGl2ZScgXTtcclxuXHJcblx0LyoqXHJcblx0ICogUmVtb3ZlIGF0dHJpYnV0ZXMgYnkgbmFtZSBmcm9tIGFuIEhUTUwtbGlrZSBzdHJpbmcuXHJcblx0ICogTWF0Y2hlczpcclxuXHQgKiAgIC0gbmFtZVxyXG5cdCAqICAgLSBuYW1lPVwiLi4uXCIvbmFtZT0nLi4uJy9uYW1lPXZhbHVlXHJcblx0ICogd2l0aCBhbnkgc3Vycm91bmRpbmcgd2hpdGVzcGFjZS5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXHJcblx0ICogQHBhcmFtIHtzdHJpbmdbXX0gYXR0cnNfbG93ZXJjYXNlICAgYXR0cmlidXRlIG5hbWVzIChsb3dlcmNhc2UpXHJcblx0ICogQHJldHVybiB7c3RyaW5nfVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHN0cmlwX2F0dHJpYnV0ZXNfZnJvbV9tYXJrdXAoaHRtbCwgYXR0cnNfbG93ZXJjYXNlKSB7XHJcblx0XHRpZiAoIWh0bWwgfHwgIWF0dHJzX2xvd2VyY2FzZT8ubGVuZ3RoKSByZXR1cm4gaHRtbDtcclxuXHRcdGxldCBvdXQgPSBTdHJpbmcoaHRtbCk7XHJcblx0XHRmb3IgKGNvbnN0IHJhd05hbWUgb2YgYXR0cnNfbG93ZXJjYXNlKSB7XHJcblx0XHRcdGlmICghcmF3TmFtZSkgY29udGludWU7XHJcblx0XHRcdGNvbnN0IG5hbWUgPSBTdHJpbmcocmF3TmFtZSkudG9Mb3dlckNhc2UoKS50cmltKCk7XHJcblx0XHRcdC8vIEVzY2FwZSBmb3IgcmVnZXhcclxuXHRcdFx0Y29uc3QgZXNjID0gbmFtZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpO1xyXG5cdFx0XHQvLyBNYXRjaCBmdWxsIGF0dHJpYnV0ZSBuYW1lIG9ubHkgKG5leHQgY2hhciBpcyBOT1QgYSB2YWxpZCBuYW1lIGNoYXIpXHJcblx0XHRcdGNvbnN0IHJlID0gbmV3IFJlZ0V4cChcclxuXHRcdFx0XHRgXFxcXHMke2VzY30oPyFbQS1aYS16MC05XzpcXFxcLV0pKD86PSg/OlwiW15cIl0qXCJ8J1teJ10qJ3xbXlxcXFxzPl0qKSk/YCxcclxuXHRcdFx0XHQnZ2knXHJcblx0XHRcdCk7XHJcblx0XHRcdG91dCA9IG91dC5yZXBsYWNlKHJlLCAnJyk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gb3V0O1xyXG5cdH1cclxuXHJcblx0Ly8gPT0gSGVscGVycyDigJMgY29sdW1uIHN0eWxlcyBwYXJzaW5nICYgQ1NTIHZhcnMgYnVpbGRlciA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuXHQvLyBLbm93biBrZXlzIHdlIHRyZWF0IGFzIHJlYWwgcGVyLWNvbHVtbiBzdHlsZSBvdmVycmlkZXMuXHJcblx0ZnVuY3Rpb24gaGFzX25vbl9kZWZhdWx0X2NvbF9zdHlsZXMob2JqKSB7XHJcblx0XHRpZiAoICFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHRcdHZhciBrZXlzID0gWyAnZGlyJywgJ3dyYXAnLCAnamMnLCAnYWknLCAnZ2FwJywgJ2FzZWxmJywgJ2FjJyBdO1xyXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0dmFyIGsgPSBrZXlzW2ldO1xyXG5cdFx0XHRpZiAoIG9ialtrXSAhPSBudWxsICYmIFN0cmluZyggb2JqW2tdICkudHJpbSgpICE9PSAnJyApIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUGFyc2UgYGNvbF9zdHlsZXNgIGNvbWluZyBmcm9tIGEgU2VjdGlvbi5cclxuXHQgKiBBY2NlcHRzOiBKU09OIHN0cmluZyBvciBhcnJheSBvZiBvYmplY3RzLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8QXJyYXl8dW5kZWZpbmVkfG51bGx9IHJhd1xyXG5cdCAqIEByZXR1cm5zIHtBcnJheTxPYmplY3Q+fSBhcnJheSBhbGlnbmVkIHRvIGNvbHVtbnMgKG1heSBiZSBlbXB0eSlcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBwYXJzZV9jb2xfc3R5bGVzX2pzb24ocmF3KSB7XHJcblx0XHRpZiAoICFyYXcgKSByZXR1cm4gW107XHJcblx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHJhdyApICkgcmV0dXJuIHJhdy5maWx0ZXIoIGZ1bmN0aW9uICh4KSB7XHJcblx0XHRcdHJldHVybiB4ICYmIHR5cGVvZiB4ID09PSAnb2JqZWN0JztcclxuXHRcdH0gKTtcclxuXHJcblx0XHRpZiAoIHR5cGVvZiByYXcgPT09ICdzdHJpbmcnICkge1xyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdHZhciBhcnIgPSBKU09OLnBhcnNlKCByYXcgKTtcclxuXHRcdFx0XHRyZXR1cm4gQXJyYXkuaXNBcnJheSggYXJyICkgPyBhcnIuZmlsdGVyKCBmdW5jdGlvbiAoeCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHggJiYgdHlwZW9mIHggPT09ICdvYmplY3QnO1xyXG5cdFx0XHRcdH0gKSA6IFtdO1xyXG5cdFx0XHR9IGNhdGNoICggX2UgKSB7XHJcblx0XHRcdFx0cmV0dXJuIFtdO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gW107XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBCdWlsZCBDU1MgdmFyaWFibGUgZGVjbGFyYXRpb25zIHN0cmluZyBmb3IgYSBjb2x1bW4gc3R5bGUgb2JqZWN0LlxyXG5cdCAqIEtub3duIGtleXMgLT4gQ1NTIHZhcnM6XHJcblx0ICogIC0gZGlyICAtPiAtLXdwYmMtYmZiLWNvbC1kaXJcclxuXHQgKiAgLSB3cmFwIC0+IC0td3BiYy1iZmItY29sLXdyYXBcclxuXHQgKiAgLSBqYyAgIC0+IC0td3BiYy1iZmItY29sLWpjXHJcblx0ICogIC0gYWkgICAtPiAtLXdwYmMtYmZiLWNvbC1haVxyXG5cdCAqICAtIGdhcCAgLT4gLS13cGJjLWJmYi1jb2wtZ2FwXHJcblx0ICogIC0gYWMgICAtPiAtLXdwYmMtYmZiLWNvbC1hY1xyXG5cdCAqICAtIGFzZWxmLT4gLS13cGJjLWJmYi1jb2wtYXNlbGZcclxuXHQgKlxyXG5cdCAqIFVua25vd24ga2V5cyBhcmUgZXhwb3J0ZWQgYXMgYC0td3BiYy1iZmItY29sLSR7a2V5fWAuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge09iamVjdHxudWxsfHVuZGVmaW5lZH0gb2JqXHJcblx0ICogQHJldHVybnMge3N0cmluZ30gZS5nLiBcIi0td3BiYy1iZmItY29sLWRpcjogcm93OyAtLXdwYmMtYmZiLWNvbC13cmFwOiB3cmFwO1wiXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gYnVpbGRfY29sX2Nzc192YXJzKG9iaikge1xyXG5cdFx0aWYgKCAhb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnICkgcmV0dXJuICcnO1xyXG5cclxuXHRcdHZhciBtYXAgPSB7XHJcblx0XHRcdGRpciAgOiAnLS13cGJjLWJmYi1jb2wtZGlyJyxcclxuXHRcdFx0d3JhcCA6ICctLXdwYmMtYmZiLWNvbC13cmFwJyxcclxuXHRcdFx0amMgICA6ICctLXdwYmMtYmZiLWNvbC1qYycsXHJcblx0XHRcdGFpICAgOiAnLS13cGJjLWJmYi1jb2wtYWknLFxyXG5cdFx0XHRnYXAgIDogJy0td3BiYy1iZmItY29sLWdhcCcsXHJcblx0XHRcdGFjICAgOiAnLS13cGJjLWJmYi1jb2wtYWMnLFxyXG5cdFx0XHRhc2VsZjogJy0td3BiYy1iZmItY29sLWFzZWxmJ1xyXG5cdFx0fTtcclxuXHJcblx0XHR2YXIgcGFydHMgPSBbXTtcclxuXHJcblx0XHRmb3IgKCB2YXIgayBpbiBvYmogKSB7XHJcblx0XHRcdGlmICggIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCggb2JqLCBrICkgKSBjb250aW51ZTtcclxuXHRcdFx0dmFyIHYgPSBvYmpba107XHJcblx0XHRcdGlmICggdiA9PSBudWxsIHx8IHYgPT09ICcnICkgY29udGludWU7XHJcblxyXG5cdFx0XHR2YXIgdmFyX25hbWUgPSBtYXBba10gfHwgKCctLXdwYmMtYmZiLWNvbC0nICsgU3RyaW5nKCBrICkucmVwbGFjZSggL1teYS16MC05Xy1dL2dpLCAnJyApLnRvTG93ZXJDYXNlKCkpO1xyXG5cdFx0XHRwYXJ0cy5wdXNoKCB2YXJfbmFtZSArICc6ICcgKyBTdHJpbmcoIHYgKSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEFsd2F5cyBpbmNsdWRlIGV4cGxpY2l0IG1pbiBndWFyZCAocmVxdWVzdGVkKTogLS13cGJjLWNvbC1taW46IDBweDtcclxuXHRcdHBhcnRzLnB1c2goICctLXdwYmMtY29sLW1pbjogMHB4JyApO1xyXG5cclxuXHRcdHJldHVybiBwYXJ0cy5qb2luKCAnOycgKSArIChwYXJ0cy5sZW5ndGggPyAnOycgOiAnJyk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXNvbHZlIG51bWVyaWMgcGVyY2VudCBmcm9tIGEgd2lkdGggdG9rZW4gbGlrZSBcIjQ4LjUlXCIuXHJcblx0ICogRmFsbHMgYmFjayB0byBgZmFsbGJhY2tfcGVyY2VudGAgaWYgbm90IGluIHBlcmNlbnQgZm9ybWF0LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfHVuZGVmaW5lZHxudWxsfSB3aWR0aF90b2tlblxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBmYWxsYmFja19wZXJjZW50XHJcblx0ICogQHJldHVybnMge251bWJlcn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiByZXNvbHZlX2ZsZXhfYmFzaXNfcGVyY2VudCh3aWR0aF90b2tlbiwgZmFsbGJhY2tfcGVyY2VudCkge1xyXG5cdFx0aWYgKCB0eXBlb2Ygd2lkdGhfdG9rZW4gPT09ICdzdHJpbmcnICkge1xyXG5cdFx0XHR2YXIgcyA9IHdpZHRoX3Rva2VuLnRyaW0oKTtcclxuXHRcdFx0aWYgKCBzLmVuZHNXaXRoKCAnJScgKSApIHtcclxuXHRcdFx0XHR2YXIgcCA9IHBhcnNlRmxvYXQoIHMgKTtcclxuXHRcdFx0XHRpZiAoIGlzRmluaXRlKCBwICkgKSByZXR1cm4gcDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0aWYgKCB0eXBlb2Ygd2lkdGhfdG9rZW4gPT09ICdudW1iZXInICYmIGlzRmluaXRlKCB3aWR0aF90b2tlbiApICkge1xyXG5cdFx0XHRyZXR1cm4gd2lkdGhfdG9rZW47XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZmFsbGJhY2tfcGVyY2VudDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbXB1dGUgZWZmZWN0aXZlIGZsZXgtYmFzaXMgdmFsdWVzIHRoYXQgcmVzcGVjdCBpbnRlci1jb2x1bW4gZ2FwXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gY29sdW1uc1xyXG5cdCAqIEBwYXJhbSBnYXBfcGVyY2VudFxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIGNvbXB1dGVfZWZmZWN0aXZlX2Jhc2VzKGNvbHVtbnMsIGdhcF9wZXJjZW50ID0gMykge1xyXG5cclxuXHRcdGNvbnN0IG4gPSBjb2x1bW5zICYmIGNvbHVtbnMubGVuZ3RoID8gY29sdW1ucy5sZW5ndGggOiAxO1xyXG5cclxuXHRcdGNvbnN0IHJhdyA9IGNvbHVtbnMubWFwKCAoY29sKSA9PiB7XHJcblx0XHRcdGNvbnN0IHcgPSBjb2wgJiYgY29sLndpZHRoICE9IG51bGwgPyBTdHJpbmcoIGNvbC53aWR0aCApLnRyaW0oKSA6ICcnO1xyXG5cdFx0XHRjb25zdCBwID0gdy5lbmRzV2l0aCggJyUnICkgPyBwYXJzZUZsb2F0KCB3ICkgOiB3ID8gcGFyc2VGbG9hdCggdyApIDogTmFOO1xyXG5cdFx0XHRyZXR1cm4gTnVtYmVyLmlzRmluaXRlKCBwICkgPyBwIDogMTAwIC8gbjtcclxuXHRcdH0gKTtcclxuXHJcblx0XHRjb25zdCBzdW1fcmF3ICAgICA9IHJhdy5yZWR1Y2UoIChhLCBiKSA9PiBhICsgYiwgMCApIHx8IDEwMDtcclxuXHRcdGNvbnN0IGdwICAgICAgICAgID0gTnVtYmVyLmlzRmluaXRlKCArZ2FwX3BlcmNlbnQgKSA/ICtnYXBfcGVyY2VudCA6IDM7XHJcblx0XHRjb25zdCB0b3RhbF9nYXBzICA9IE1hdGgubWF4KCAwLCBuIC0gMSApICogZ3A7XHJcblx0XHRjb25zdCBhdmFpbGFibGUgICA9IE1hdGgubWF4KCAwLCAxMDAgLSB0b3RhbF9nYXBzICk7XHJcblx0XHRjb25zdCBzY2FsZV9yYXRpbyA9IGF2YWlsYWJsZSAvIHN1bV9yYXc7XHJcblxyXG5cdFx0cmV0dXJuIHJhdy5tYXAoIChwKSA9PiBNYXRoLm1heCggMCwgcCAqIHNjYWxlX3JhdGlvICkgKTtcclxuXHR9XHJcblxyXG5cdC8vID09IGFkYXB0ZXI6IGJ1aWxkZXIgKGFycmF5LW9mLXBhZ2VzKSA+IGV4cG9ydGVyIHNoYXBlIHsgcGFnZXM6IFsgeyBpdGVtczpbIHtraW5kLGRhdGF9IF0gfSBdIH0gPT09PT09PT09PT09PT09PT09XHJcblx0ZnVuY3Rpb24gYWRhcHRfYnVpbGRlcl9zdHJ1Y3R1cmVfdG9fZXhwb3J0ZXIoc3RydWN0dXJlKSB7XHJcblxyXG4vL1x0XHRpZiAoICFBcnJheS5pc0FycmF5KCBzdHJ1Y3R1cmUgKSApIHJldHVybiB7IHBhZ2VzOiBbXSB9O1xyXG5cclxuXHRcdC8vIEVuc3VyZSBhdCBsZWFzdCBvbmUgcGFnZSBleGlzdHMsIGV2ZW4gd2hlbiBCdWlsZGVyIHN0cnVjdHVyZSBpcyBlbXB0eSBgW11gLlxyXG5cdFx0Ly8gVGhpcyBrZWVwcyBleHBvcnRlZCBBZHZhbmNlZCBGb3JtIHZhbGlkICh3aXphcmQgc3RlcCAjMSBleGlzdHMpLlxyXG5cdFx0aWYgKCAhIEFycmF5LmlzQXJyYXkoIHN0cnVjdHVyZSApIHx8IHN0cnVjdHVyZS5sZW5ndGggPT09IDAgKSB7XHJcblx0XHRcdHJldHVybiB7IHBhZ2VzOiBbIHsgaXRlbXM6IFtdIH0gXSB9O1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IG5vcm1hbGl6ZV9vcHRpb25zID0gKG9wdHMpID0+IHtcclxuXHRcdFx0aWYgKCAhQXJyYXkuaXNBcnJheSggb3B0cyApICkgcmV0dXJuIFtdO1xyXG5cdFx0XHRyZXR1cm4gb3B0cy5tYXAoIChvKSA9PiB7XHJcblx0XHRcdFx0aWYgKCB0eXBlb2YgbyA9PT0gJ3N0cmluZycgKSByZXR1cm4geyBsYWJlbDogbywgdmFsdWU6IG8sIHNlbGVjdGVkOiBmYWxzZSB9O1xyXG5cdFx0XHRcdGlmICggbyAmJiB0eXBlb2YgbyA9PT0gJ29iamVjdCcgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0XHRsYWJlbCAgIDogU3RyaW5nKCBvLmxhYmVsID8/IG8udmFsdWUgPz8gJycgKSxcclxuXHRcdFx0XHRcdFx0dmFsdWUgICA6IFN0cmluZyggby52YWx1ZSA/PyBvLmxhYmVsID8/ICcnICksXHJcblx0XHRcdFx0XHRcdHNlbGVjdGVkOiAhIW8uc2VsZWN0ZWRcclxuXHRcdFx0XHRcdH07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB7IGxhYmVsOiBTdHJpbmcoIG8gKSwgdmFsdWU6IFN0cmluZyggbyApLCBzZWxlY3RlZDogZmFsc2UgfTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHQvLyA9PSBBZGFwdGVyIOKAkyBhdHRhY2ggcGFyc2VkIHBlci1jb2x1bW4gYGNvbF9zdHlsZXNgIGZyb20gU2VjdGlvbiBpbnRvIGVhY2ggY29sdW1uXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHRjb25zdCB3YWxrX3NlY3Rpb24gPSAoc2VjKSA9PiB7XHJcblx0XHRcdGNvbnN0IHNlY3Rpb25fY29sX3N0eWxlcyA9IHBhcnNlX2NvbF9zdHlsZXNfanNvbiggc2VjICYmIHNlYy5jb2xfc3R5bGVzICk7XHJcblxyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdGlkICAgICA6IHNlYz8uaWQsXHJcblx0XHRcdFx0Y29sdW1uczogKHNlYz8uY29sdW1ucyB8fCBbXSkubWFwKCAoY29sLCBjb2xfaW5kZXgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGl0ZW1zID0gQXJyYXkuaXNBcnJheSggY29sPy5pdGVtcyApXHJcblx0XHRcdFx0XHRcdD8gY29sLml0ZW1zXHJcblx0XHRcdFx0XHRcdDogW1xyXG5cdFx0XHRcdFx0XHRcdC4uLihjb2w/LmZpZWxkcyB8fCBbXSkubWFwKCAoZikgPT4gKHsgdHlwZTogJ2ZpZWxkJywgZGF0YTogZiB9KSApLFxyXG5cdFx0XHRcdFx0XHRcdC4uLihjb2w/LnNlY3Rpb25zIHx8IFtdKS5tYXAoIChzKSA9PiAoeyB0eXBlOiAnc2VjdGlvbicsIGRhdGE6IHMgfSkgKVxyXG5cdFx0XHRcdFx0XHRdO1xyXG5cclxuXHRcdFx0XHRcdGNvbnN0IGZpZWxkcyA9IGl0ZW1zXHJcblx0XHRcdFx0XHRcdC5maWx0ZXIoIChpdCkgPT4gaXQgJiYgaXQudHlwZSA9PT0gJ2ZpZWxkJyApXHJcblx0XHRcdFx0XHRcdC5tYXAoIChpdCkgPT4gKHsgLi4uaXQuZGF0YSwgb3B0aW9uczogbm9ybWFsaXplX29wdGlvbnMoIGl0LmRhdGE/Lm9wdGlvbnMgKSB9KSApO1xyXG5cclxuXHRcdFx0XHRcdGNvbnN0IHNlY3Rpb25zID0gaXRlbXNcclxuXHRcdFx0XHRcdFx0LmZpbHRlciggKGl0KSA9PiBpdCAmJiBpdC50eXBlID09PSAnc2VjdGlvbicgKVxyXG5cdFx0XHRcdFx0XHQubWFwKCAoaXQpID0+IHdhbGtfc2VjdGlvbiggaXQuZGF0YSApICk7XHJcblxyXG5cdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0d2lkdGggICAgICA6IGNvbD8ud2lkdGggfHwgJzEwMCUnLFxyXG5cdFx0XHRcdFx0XHRzdHlsZSAgICAgIDogY29sPy5zdHlsZSB8fCBudWxsLFxyXG5cdFx0XHRcdFx0XHRjb2xfc3R5bGVzIDogc2VjdGlvbl9jb2xfc3R5bGVzWyBjb2xfaW5kZXggXSB8fCBudWxsLCAgIC8vIDwtIGF0dGFjaCBzdHlsZSBvYmplY3QgcGVyIGNvbHVtblxyXG5cdFx0XHRcdFx0XHRmaWVsZHMsXHJcblx0XHRcdFx0XHRcdHNlY3Rpb25zXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0gKVxyXG5cdFx0XHR9O1xyXG5cdFx0fTtcclxuXHJcblxyXG5cdFx0Y29uc3QgcGFnZXMgPSBzdHJ1Y3R1cmUubWFwKCAocGFnZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBpdGVtcyA9IFtdO1xyXG5cdFx0XHQocGFnZT8uY29udGVudCB8fCBbXSkuZm9yRWFjaCggKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoICFpdGVtICkgcmV0dXJuO1xyXG5cdFx0XHRcdGlmICggaXRlbS50eXBlID09PSAnc2VjdGlvbicgJiYgaXRlbS5kYXRhICkge1xyXG5cdFx0XHRcdFx0aXRlbXMucHVzaCggeyBraW5kOiAnc2VjdGlvbicsIGRhdGE6IHdhbGtfc2VjdGlvbiggaXRlbS5kYXRhICkgfSApO1xyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGl0ZW0udHlwZSA9PT0gJ2ZpZWxkJyAmJiBpdGVtLmRhdGEgKSB7XHJcblx0XHRcdFx0XHRpdGVtcy5wdXNoKCB7XHJcblx0XHRcdFx0XHRcdGtpbmQ6ICdmaWVsZCcsXHJcblx0XHRcdFx0XHRcdGRhdGE6IHsgLi4uaXRlbS5kYXRhLCBvcHRpb25zOiBub3JtYWxpemVfb3B0aW9ucyggaXRlbS5kYXRhLm9wdGlvbnMgKSB9XHJcblx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9ICk7XHJcblx0XHRcdHJldHVybiB7IGl0ZW1zIH07XHJcblx0XHR9ICk7XHJcblxyXG5cdFx0cmV0dXJuIHsgcGFnZXMgfTtcclxuXHR9XHJcblxyXG5cclxuXHQvLyA9PSBCb29raW5nIEZyb20gRXhwb3J0ZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdGNsYXNzIFdQQkNfQkZCX0V4cG9ydGVyIHtcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIE11dGFibGUgc2tpcC1saXN0IGZvciBhdHRyaWJ1dGUgbmFtZXMgKGxvd2VyY2FzZSkuXHJcblx0XHQgKiBZb3UgY2FuIG92ZXJyaWRlIGl0IHZpYSBzZXRfc2tpcF9hdHRycygpIG9yIGFkZCB3aXRoIGFkZF9za2lwX2F0dHJzKCkuXHJcblx0XHQgKiBAdHlwZSB7U2V0PHN0cmluZz59XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBza2lwX2F0dHJzID0gbmV3IFNldCgpO1xyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmVwbGFjZSB0aGUgZW50aXJlIHNraXAgbGlzdC5cclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nW119IGFyclxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgc2V0X3NraXBfYXR0cnMoIGFyciApIHtcclxuXHRcdFx0dGhpcy5za2lwX2F0dHJzID0gbmV3IFNldChcclxuXHRcdFx0XHQoQXJyYXkuaXNBcnJheSggYXJyICkgPyBhcnIgOiBbXSkubWFwKCAobikgPT4gU3RyaW5nKCBuICkudG9Mb3dlckNhc2UoKS50cmltKCkgKS5maWx0ZXIoIEJvb2xlYW4gKVxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQWRkIG9uZSBvciBtYW55IGF0dHJpYnV0ZXMgdG8gdGhlIHNraXAgbGlzdC5cclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfHN0cmluZ1tdfSBuYW1lc1xyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgYWRkX3NraXBfYXR0cnMoIG5hbWVzICkge1xyXG5cdFx0XHQoIEFycmF5LmlzQXJyYXkoIG5hbWVzICkgPyBuYW1lcyA6IFsgbmFtZXMgXSApXHJcblx0XHRcdFx0Lm1hcCggKG4pID0+IFN0cmluZyggbiApLnRvTG93ZXJDYXNlKCkudHJpbSgpIClcclxuXHRcdFx0XHQuZmlsdGVyKCBCb29sZWFuIClcclxuXHRcdFx0XHQuZm9yRWFjaCggKG4pID0+IHRoaXMuc2tpcF9hdHRycy5hZGQoIG4gKSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmVtb3ZlIG9uZSBhdHRyaWJ1dGUgZnJvbSB0aGUgc2tpcCBsaXN0LlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHJlbW92ZV9za2lwX2F0dHIoIG5hbWUgKSB7XHJcblx0XHRcdGlmICggISBuYW1lICkgeyByZXR1cm47IH1cclxuXHRcdFx0dGhpcy5za2lwX2F0dHJzLmRlbGV0ZSggU3RyaW5nKCBuYW1lICkudG9Mb3dlckNhc2UoKS50cmltKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEFwcGx5IGF0dHJpYnV0ZSBza2lwcGluZyB0byBhIGZpbmFsIEhUTUwgc3RyaW5nLlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGh0bWxcclxuXHRcdCAqIEByZXR1cm4ge3N0cmluZ31cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHNhbml0aXplX2V4cG9ydCggaHRtbCApIHtcclxuXHRcdFx0cmV0dXJuIHN0cmlwX2F0dHJpYnV0ZXNfZnJvbV9tYXJrdXAoIGh0bWwsIEFycmF5LmZyb20oIHRoaXMuc2tpcF9hdHRycyApICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogRXhwb3J0IGFkYXB0ZWQgc3RydWN0dXJlIHRvIGFkdmFuY2VkIGZvcm0gdGV4dCAod2l0aCA8cj4vPGM+IGxheW91dCBhbmQgd2l6YXJkIHdyYXBwZXIpLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBhZGFwdGVkXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gIFtvcHRpb25zLm5ld2xpbmU9XCJcXG5cIl1cclxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuYWRkTGFiZWxzPXRydWVdXHJcblx0XHQgKiBAcGFyYW0ge251bWJlcn0gIFtvcHRpb25zLmdhcFBlcmNlbnQ9M11cclxuXHRcdCAqIEByZXR1cm5zIHtzdHJpbmd9XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBleHBvcnRfZm9ybShhZGFwdGVkLCBvcHRpb25zID0ge30pIHtcclxuXHRcdFx0Ly8gaW5kZW50OiB1c2UgcmVhbCBUQUIgYnkgZGVmYXVsdCAoY2FuIGJlIG92ZXJyaWRkZW4gdmlhIG9wdGlvbnMuaW5kZW50KVxyXG5cdFx0XHRjb25zdCBjZmcgPSB7IG5ld2xpbmU6ICdcXG4nLCBhZGRMYWJlbHM6IHRydWUsIGdhcFBlcmNlbnQ6IDMsIGluZGVudDogJ1xcdCcsIC4uLm9wdGlvbnMgfTtcclxuXHRcdFx0Y29uc3QgSU5EID0gKHR5cGVvZiBjZmcuaW5kZW50ID09PSAnc3RyaW5nJykgPyBjZmcuaW5kZW50IDogJ1xcdCc7XHJcblxyXG5cdFx0XHRsZXQgZGVwdGggICA9IDA7XHJcblx0XHRcdGNvbnN0IGxpbmVzID0gW107XHJcblx0XHRcdGNvbnN0IHB1c2ggID0gKHMgPSAnJykgPT4gbGluZXMucHVzaCggSU5ELnJlcGVhdCggZGVwdGggKSArIFN0cmluZyggcyApICk7XHJcblx0XHRcdGNvbnN0IG9wZW4gID0gKHMgPSAnJykgPT4ge1xyXG5cdFx0XHRcdHB1c2goIHMgKTtcclxuXHRcdFx0XHRkZXB0aCsrO1xyXG5cdFx0XHR9O1xyXG5cdFx0XHRjb25zdCBjbG9zZSA9IChzID0gJycpID0+IHtcclxuXHRcdFx0XHRkZXB0aCA9IE1hdGgubWF4KCAwLCBkZXB0aCAtIDEgKTtcclxuXHRcdFx0XHRwdXNoKCBzICk7XHJcblx0XHRcdH07XHJcblx0XHRcdGNvbnN0IGJsYW5rID0gKCkgPT4ge1xyXG5cdFx0XHRcdGxpbmVzLnB1c2goICcnICk7XHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHRpZiAoICFhZGFwdGVkIHx8ICFBcnJheS5pc0FycmF5KCBhZGFwdGVkLnBhZ2VzICkgKSByZXR1cm4gJyc7XHJcblxyXG5cdFx0XHQvLyBBbHdheXMgZXhwb3J0IGF0IGxlYXN0IG9uZSB3aXphcmQgc3RlcCB0byBrZWVwIEFkdmFuY2VkIEZvcm0gc3RydWN0dXJlIHZhbGlkLlxyXG5cdFx0XHRjb25zdCBwYWdlcyA9IGFkYXB0ZWQucGFnZXMubGVuZ3RoID8gYWRhcHRlZC5wYWdlcyA6IFsgeyBpdGVtczogW10gfSBdO1xyXG5cclxuXHRcdFx0Y29uc3QgY3R4ID0geyB1c2VkSWRzOiBuZXcgU2V0KCkgfTtcclxuXHJcblx0XHRcdG9wZW4oIGA8ZGl2IGNsYXNzPVwid3BiY19iZmJfZm9ybSB3cGJjX3dpemFyZF9fYm9yZGVyX2NvbnRhaW5lclwiPmAgKTtcclxuXHJcblx0XHRcdC8vIG9uZS1wZXItZm9ybSBndWFyZHMgKGNhbGVuZGFyIGlzIG5vdCBnYXRlZCBoZXJlKVxyXG5cdFx0XHRjb25zdCBvbmNlID0geyBjYXB0Y2hhOiAwLCBjb3VudHJ5OiAwLCBjb3Vwb246IDAsIGNvc3RfY29ycmVjdGlvbnM6IDAsIHN1Ym1pdDogMCB9O1xyXG5cclxuXHRcdFx0cGFnZXMuZm9yRWFjaCggKHBhZ2UsIHBhZ2VfaW5kZXgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBpc19maXJzdCA9IHBhZ2VfaW5kZXggPT09IDA7XHJcblx0XHRcdFx0Y29uc3Qgc3RlcF9udW0gPSBwYWdlX2luZGV4ICsgMTtcclxuXHJcblx0XHRcdFx0Y29uc3QgaGlkZGVuX2NsYXNzID0gaXNfZmlyc3QgPyAnJyA6ICcgd3BiY193aXphcmRfc3RlcF9oaWRkZW4nO1xyXG5cdFx0XHRcdGNvbnN0IGhpZGRlbl9zdHlsZSA9IGlzX2ZpcnN0ID8gJycgOiAnIHN0eWxlPVwiZGlzcGxheTpub25lO2NsZWFyOmJvdGg7XCInO1xyXG5cdFx0XHRcdG9wZW4oIGA8ZGl2IGNsYXNzPVwid3BiY193aXphcmRfc3RlcCB3cGJjX19mb3JtX19kaXYgd3BiY193aXphcmRfc3RlcCR7c3RlcF9udW19JHtoaWRkZW5fY2xhc3N9XCIke2hpZGRlbl9zdHlsZX0+YCApO1xyXG5cclxuXHRcdFx0XHQocGFnZS5pdGVtcyB8fCBbXSkuZm9yRWFjaCggKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdGlmICggaXRlbS5raW5kID09PSAnc2VjdGlvbicgKSB7XHJcblx0XHRcdFx0XHRcdFdQQkNfQkZCX0V4cG9ydGVyLnJlbmRlcl9zZWN0aW9uKCBpdGVtLmRhdGEsIHsgb3BlbiwgY2xvc2UsIHB1c2gsIGJsYW5rIH0sIGNmZywgb25jZSwgY3R4ICk7XHJcblx0XHRcdFx0XHRcdC8vIGJsYW5rKCk7XHJcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBpdGVtLmtpbmQgPT09ICdmaWVsZCcgKSB7XHJcblx0XHRcdFx0XHRcdG9wZW4oIGA8cj5gICk7XHJcblx0XHRcdFx0XHRcdG9wZW4oIGA8Yz5gICk7XHJcblx0XHRcdFx0XHRcdFdQQkNfQkZCX0V4cG9ydGVyLnJlbmRlcl9maWVsZF9ub2RlKCBpdGVtLmRhdGEsIHsgb3BlbiwgY2xvc2UsIHB1c2gsIGJsYW5rIH0sIGNmZywgb25jZSwgY3R4ICk7XHJcblx0XHRcdFx0XHRcdGNsb3NlKCBgPC9jPmAgKTtcclxuXHRcdFx0XHRcdFx0Y2xvc2UoIGA8L3I+YCApO1xyXG5cdFx0XHRcdFx0XHQvLyBibGFuaygpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0gKTtcclxuXHJcblx0XHRcdFx0Y2xvc2UoIGA8L2Rpdj5gICk7XHJcblx0XHRcdH0gKTtcclxuXHJcblx0XHRcdGNsb3NlKCBgPC9kaXY+YCApO1xyXG5cdFx0XHRyZXR1cm4gV1BCQ19CRkJfRXhwb3J0ZXIuc2FuaXRpemVfZXhwb3J0KCBsaW5lcy5qb2luKCBjZmcubmV3bGluZSApICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogSGlnaC1sZXZlbCBoZWxwZXI6IGV4cG9ydCBmdWxsIHBhY2thZ2UgZnJvbSByYXcgQnVpbGRlciBzdHJ1Y3R1cmUuXHJcblx0XHQgKlxyXG5cdFx0ICogLSBBZGFwdHMgcmF3IEJ1aWxkZXIgc3RydWN0dXJlIChwYWdlcy9zZWN0aW9ucy9jb2x1bW5zL2l0ZW1zKSBmb3IgZXhwb3J0ZXJzLlxyXG5cdFx0ICogLSBCdWlsZHM6XHJcblx0XHQgKiAgICAgIOKAoiBhZHZhbmNlZF9mb3JtICAtPiDigJxBZHZhbmNlZCBGb3JtIChleHBvcnQp4oCdIHRleHQuXHJcblx0XHQgKiAgICAgIOKAoiBmaWVsZHNfZGF0YSAgICAtPiDigJxDb250ZW50IG9mIGJvb2tpbmcgZmllbGRzIGRhdGEgKGV4cG9ydCnigJ0gdGV4dC5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge0FycmF5fSAgc3RydWN0dXJlICBSYXcgQnVpbGRlciBzdHJ1Y3R1cmUgZnJvbSB3cGJjX2JmYi5nZXRfc3RydWN0dXJlKCkuXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXHJcblx0XHQgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuZ2FwUGVyY2VudD0zXSAgQ29sdW1uIGdhcCBwZXJjZW50IGZvciBsYXlvdXQgbWF0aC5cclxuXHRcdCAqXHJcblx0XHQgKiBAcmV0dXJucyB7e1xyXG5cdFx0ICogICBhZHZhbmNlZF9mb3JtOiBzdHJpbmcsXHJcblx0XHQgKiAgIGZpZWxkc19kYXRhOiBzdHJpbmcsXHJcblx0XHQgKiAgIHN0cnVjdHVyZTogQXJyYXksXHJcblx0XHQgKiAgIGFkYXB0ZWQ6IE9iamVjdFxyXG5cdFx0ICogfX1cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIGV4cG9ydF9hbGwoIHN0cnVjdHVyZSwgb3B0aW9ucyA9IHt9ICkge1xyXG5cclxuXHRcdFx0Ly8gMSkgQWRhcHQgQnVpbGRlciBKU09OIHRvIGV4cG9ydGVyIHNoYXBlIChwYWdlc1tdIC0+IGl0ZW1zW10pLlxyXG5cdFx0XHRjb25zdCBhZGFwdGVkID0gYWRhcHRfYnVpbGRlcl9zdHJ1Y3R1cmVfdG9fZXhwb3J0ZXIoIHN0cnVjdHVyZSB8fCBbXSApO1xyXG5cclxuXHRcdFx0Ly8gMikgQWR2YW5jZWQgRm9ybSB0ZXh0IChzYW1lIGxvZ2ljIGFzIGRlYnVnIHBhbmVsKS5cclxuXHRcdFx0Y29uc3QgZ2FwX3BlcmNlbnQgICA9ICggb3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5nYXBQZXJjZW50ID09PSAnbnVtYmVyJyApID8gb3B0aW9ucy5nYXBQZXJjZW50IDogMztcclxuXHRcdFx0Y29uc3QgYWR2YW5jZWRfZm9ybSA9IFdQQkNfQkZCX0V4cG9ydGVyLmV4cG9ydF9mb3JtKFxyXG5cdFx0XHRcdGFkYXB0ZWQsXHJcblx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0YWRkTGFiZWxzIDogdHJ1ZSxcclxuXHRcdFx0XHRcdGdhcFBlcmNlbnQ6IGdhcF9wZXJjZW50XHJcblx0XHRcdFx0fVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdFx0Ly8gMykgQ29udGVudCBvZiBib29raW5nIGZpZWxkcyBkYXRhIChpZiBjb250ZW50IGV4cG9ydGVyIGlzIGF2YWlsYWJsZSkuXHJcblx0XHRcdGxldCBmaWVsZHNfZGF0YSA9ICcnO1xyXG5cdFx0XHRpZiAoXHJcblx0XHRcdFx0d2luZG93LldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlciAmJlxyXG5cdFx0XHRcdHR5cGVvZiB3aW5kb3cuV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLmV4cG9ydF9jb250ZW50ID09PSAnZnVuY3Rpb24nXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdGZpZWxkc19kYXRhID0gd2luZG93LldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5leHBvcnRfY29udGVudChcclxuXHRcdFx0XHRcdGFkYXB0ZWQsXHJcblx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdGFkZExhYmVsczogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0c2VwICAgICAgOiAnOiAnXHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRhZHZhbmNlZF9mb3JtOiBhZHZhbmNlZF9mb3JtIHx8ICcnLFxyXG5cdFx0XHRcdGZpZWxkc19kYXRhICA6IGZpZWxkc19kYXRhIHx8ICcnLFxyXG5cdFx0XHRcdHN0cnVjdHVyZSAgICA6IHN0cnVjdHVyZSB8fCBbXSxcclxuXHRcdFx0XHRhZGFwdGVkICAgICAgOiBhZGFwdGVkXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0Ly8gPT0gRXhwb3J0ZXIg4oCTIHJlbmRlcl9zZWN0aW9uKCkgbm93IGluamVjdHMgcGVyLWNvbHVtbiBDU1MgdmFycyBmcm9tIGBjb2xfc3R5bGVzYFxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0c3RhdGljIHJlbmRlcl9zZWN0aW9uKHNlY3Rpb24sIGlvLCBjZmcsIG9uY2UsIGN0eCkge1xyXG5cclxuXHRcdFx0b25jZSA9IG9uY2UgfHwgeyBjYXB0Y2hhOiAwLCBjb3VudHJ5OiAwLCBjb3Vwb246IDAsIGNvc3RfY29ycmVjdGlvbnM6IDAsIHN1Ym1pdDogMCB9O1xyXG5cdFx0XHRjdHggID0gY3R4IHx8IHsgdXNlZElkczogbmV3IFNldCgpIH07XHJcblxyXG5cdFx0XHRjb25zdCB7IG9wZW4sIGNsb3NlIH0gPSBpbztcclxuXHJcblx0XHRcdGNvbnN0IGNvbHMgPSBBcnJheS5pc0FycmF5KCBzZWN0aW9uLmNvbHVtbnMgKSAmJiBzZWN0aW9uLmNvbHVtbnMubGVuZ3RoXHJcblx0XHRcdFx0PyBzZWN0aW9uLmNvbHVtbnNcclxuXHRcdFx0XHQ6IFsgeyB3aWR0aDogJzEwMCUnLCBmaWVsZHM6IFtdLCBzZWN0aW9uczogW10gfSBdO1xyXG5cclxuXHRcdFx0Ly8gUm93IGlzIGFjdGl2ZSBpZiBBTlkgY29sdW1uIGNhcnJpZXMgc3R5bGVzLlxyXG5cdFx0XHR2YXIgcm93X2lzX2FjdGl2ZSA9IGNvbHMuc29tZSggZnVuY3Rpb24gKGNvbCkgeyByZXR1cm4gaGFzX25vbl9kZWZhdWx0X2NvbF9zdHlsZXMoIGNvbCAmJiBjb2wuY29sX3N0eWxlcyApOyB9ICk7XHJcblx0XHRcdHZhciByb3dfYXR0cl9hY3RpdmUgPSByb3dfaXNfYWN0aXZlID8gJyBkYXRhLWNvbHN0eWxlcy1hY3RpdmU9XCIxXCInIDogJyc7XHJcblxyXG5cdFx0XHRvcGVuKCBgPHIke3Jvd19hdHRyX2FjdGl2ZX0+YCApO1xyXG5cclxuXHRcdFx0Y29uc3QgYmFzZXMgICAgPSBjb21wdXRlX2VmZmVjdGl2ZV9iYXNlcyggY29scywgY2ZnLmdhcFBlcmNlbnQgKTtcclxuXHRcdFx0Y29uc3QgZXNjX2F0dHIgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9odG1sO1xyXG5cclxuXHRcdFx0Y29scy5mb3JFYWNoKCAoY29sLCBpZHgpID0+IHtcclxuXHRcdFx0XHQvLyAoMSkgUmVzb2x2ZSBmbGV4LWJhc2lzLlxyXG5cdFx0XHRcdHZhciBlZmZfYmFzaXMgPSByZXNvbHZlX2ZsZXhfYmFzaXNfcGVyY2VudCggY29sICYmIGNvbC53aWR0aCwgTnVtYmVyLmlzRmluaXRlKCBiYXNlc1tpZHhdICkgPyArYmFzZXNbaWR4XSA6IDEwMCApO1xyXG5cclxuXHRcdFx0XHQvLyAoMikgQnVpbGQgaW5saW5lIHN0eWxlLlxyXG5cdFx0XHRcdHZhciBzdHlsZV9wYXJ0cyA9IFtdO1xyXG5cclxuXHRcdFx0XHRpZiAoIGNvbCAmJiB0eXBlb2YgY29sLnN0eWxlID09PSAnc3RyaW5nJyAmJiBjb2wuc3R5bGUudHJpbSgpICkge1xyXG5cdFx0XHRcdFx0c3R5bGVfcGFydHMucHVzaCggY29sLnN0eWxlLnRyaW0oKS5yZXBsYWNlKCAvOytcXHMqJC8sICcnICkgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0c3R5bGVfcGFydHMucHVzaCggJ2ZsZXgtYmFzaXM6ICcgKyAoIE51bWJlci5pc0Zpbml0ZSggZWZmX2Jhc2lzICkgPyBlZmZfYmFzaXMudG9TdHJpbmcoKSA6ICcxMDAnICkgKyAnJScgKTtcclxuXHJcblx0XHRcdFx0dmFyIGNzc192YXJzX3N0ciA9IGJ1aWxkX2NvbF9jc3NfdmFycyggY29sICYmIGNvbC5jb2xfc3R5bGVzICk7XHJcblx0XHRcdFx0aWYgKCBjc3NfdmFyc19zdHIgKSB7XHJcblx0XHRcdFx0XHRzdHlsZV9wYXJ0cy5wdXNoKCBjc3NfdmFyc19zdHIucmVwbGFjZSggL147fDskL2csICcnICkgKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHZhciBzdHlsZV9hdHRyID0gYCBzdHlsZT1cIiR7ZXNjX2F0dHIoIHN0eWxlX3BhcnRzLmpvaW4oICc7ICcgKSApfVwiYDtcclxuXHJcblx0XHRcdFx0Ly8gKDMpIENvbHVtbi1sZXZlbCBhY3RpdmF0aW9uIChtb3JlIHByZWNpc2Ugc2NvcGluZylcclxuXHRcdFx0XHR2YXIgY29sX2lzX2FjdGl2ZSAgID0gaGFzX25vbl9kZWZhdWx0X2NvbF9zdHlsZXMoIGNvbCAmJiBjb2wuY29sX3N0eWxlcyApO1xyXG5cdFx0XHRcdHZhciBjb2xfYXR0cl9hY3RpdmUgPSBjb2xfaXNfYWN0aXZlID8gJyBkYXRhLWNvbHN0eWxlcy1hY3RpdmU9XCIxXCInIDogJyc7XHJcblxyXG5cdFx0XHRcdG9wZW4oIGA8YyR7Y29sX2F0dHJfYWN0aXZlfSR7c3R5bGVfYXR0cn0+YCApO1xyXG5cclxuXHRcdFx0XHQvLyBVc2UgdGhlIHNoYXJlZCBvbmNlL2N0eCBvYmplY3RzIHNvIHNpbmdsZS1wZXItZm9ybSBndWFyZHMgd29yayBhY3Jvc3MgdGhlIHdob2xlIGZvcm0uXHJcblx0XHRcdFx0KGNvbC5maWVsZHMgfHwgW10pLmZvckVhY2goIChub2RlKSA9PlxyXG5cdFx0XHRcdFx0V1BCQ19CRkJfRXhwb3J0ZXIucmVuZGVyX2ZpZWxkX25vZGUoIG5vZGUsIGlvLCBjZmcsIG9uY2UsIGN0eCApXHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdFx0Ly8gUmVjdXJzZSB3aXRoIHRoZSBzYW1lIG9uY2UvY3R4IGFzIHdlbGwuXHJcblx0XHRcdFx0KGNvbC5zZWN0aW9ucyB8fCBbXSkuZm9yRWFjaCggKG5lc3RlZCkgPT5cclxuXHRcdFx0XHRcdFdQQkNfQkZCX0V4cG9ydGVyLnJlbmRlcl9zZWN0aW9uKCBuZXN0ZWQsIGlvLCBjZmcsIG9uY2UsIGN0eCApXHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdFx0Y2xvc2UoIGA8L2M+YCApO1xyXG5cdFx0XHR9ICk7XHJcblxyXG5cdFx0XHRjbG9zZSggYDwvcj5gICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQnVpbGQgYXR0cmlidXRlIHN0cmluZyBmb3IgdGhlIDxpdGVtPiB3cmFwcGVyLlxyXG5cdFx0ICogQ3VycmVudGx5IG9ubHkgdXNlZCBmb3IgQ0FQVENIQTogcHVzaGVzIGNzcyBjbGFzc2VzIGFuZCBodG1sX2lkIHRvIHRoZSB3cmFwcGVyLlxyXG5cdFx0ICogQWxzbyBlbnN1cmVzIHVuaXF1ZW5lc3Mgb2YgdGhlIGh0bWxfaWQgYWNyb3NzIHRoZSBleHBvcnQgKHVzZXMgY3R4LnVzZWRJZHMpLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBmaWVsZFxyXG5cdFx0ICogQHBhcmFtIHt7dXNlZElkczpTZXQ8c3RyaW5nPn19IGN0eFxyXG5cdFx0ICogQHJldHVybnMge3N0cmluZ30gZS5nLiAnIGNsYXNzPVwieCB5XCIgaWQ9XCJteUlkXCInXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBpdGVtX3dyYXBwZXJfYXR0cnMoZmllbGQsIGN0eCkge1xyXG5cdFx0XHRpZiAoICEgZmllbGQgKSB7XHJcblx0XHRcdFx0cmV0dXJuICcnO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGVzY19odG1sICA9IGNvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2h0bWw7XHJcblx0XHRcdGNvbnN0IGNsc19zYW5pdCA9IGNvcmUuV1BCQ19CRkJfU2FuaXRpemUuc2FuaXRpemVfY3NzX2NsYXNzbGlzdDtcclxuXHRcdFx0Y29uc3Qgc2lkICAgICAgID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5zYW5pdGl6ZV9odG1sX2lkO1xyXG5cclxuXHRcdFx0bGV0IG91dCA9ICcnO1xyXG5cclxuXHRcdFx0Y29uc3QgY2xzX3JhdyA9IFN0cmluZyggZmllbGQuY3NzY2xhc3NfZXh0cmEgfHwgZmllbGQuY3NzY2xhc3MgfHwgZmllbGQuY2xhc3MgfHwgJycgKTtcclxuXHRcdFx0Y29uc3QgY2xzICAgICA9IGNsc19zYW5pdCggY2xzX3JhdyApO1xyXG5cdFx0XHRsZXQgaHRtbF9pZCAgID0gZmllbGQuaHRtbF9pZCA/IHNpZCggU3RyaW5nKCBmaWVsZC5odG1sX2lkICkgKSA6ICcnO1xyXG5cdFx0XHRpZiAoIGh0bWxfaWQgJiYgY3R4Py51c2VkSWRzICkge1xyXG5cdFx0XHRcdGxldCB1bmlxdWUgPSBodG1sX2lkLCBpID0gMjtcclxuXHRcdFx0XHR3aGlsZSAoIGN0eC51c2VkSWRzLmhhcyggdW5pcXVlICkgKSB7XHJcblx0XHRcdFx0XHR1bmlxdWUgPSBgJHtodG1sX2lkfV8ke2krK31gO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRjdHgudXNlZElkcy5hZGQoIHVuaXF1ZSApO1xyXG5cdFx0XHRcdGh0bWxfaWQgPSB1bmlxdWU7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCBjbHMgKSB7XHJcblx0XHRcdFx0b3V0ICs9IGAgY2xhc3M9XCIke2VzY19odG1sKCBjbHMgKX1cImA7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCBodG1sX2lkICkge1xyXG5cdFx0XHRcdG91dCArPSBgIGlkPVwiJHtlc2NfaHRtbCggaHRtbF9pZCApfVwiYDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG91dDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHQvLyA9PSBGaWVsZHMg4oCTIHBsdWdnYWJsZSwgcGFjay1kcml2ZW4gZXhwb3J0XHJcblx0XHQvLyA9PSBXcmFwIGV2ZXJ5IGV4cG9ydGVkIGZpZWxkIGluc2lkZSA8aXRlbT7igKY8L2l0ZW0+IGFuZCBkZWxlZ2F0ZSBhY3R1YWwgc2hvcnRjb2RlIGV4cG9ydFxyXG5cdFx0Ly8gPT0gdG8gcGVyLXBhY2sgY2FsbGJhY2tzIHJlZ2lzdGVyZWQgdmlhIFdQQkNfQkZCX0V4cG9ydGVyLnJlZ2lzdGVyKHR5cGUsIGZuKS5cclxuXHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHRcdHN0YXRpYyByZW5kZXJfZmllbGRfbm9kZShmaWVsZCwgaW8sIGNmZywgb25jZSwgY3R4KSB7XHJcblxyXG5cdFx0XHRjb25zdCB7IG9wZW4sIGNsb3NlLCBwdXNoIH0gPSBpbztcclxuXHRcdFx0aWYgKCAhIGZpZWxkIHx8ICEgZmllbGQudHlwZSApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNoYXJlZCBjb250ZXh0ICh1c2VkSWRzLCDigJxvbmNlLXBlci1mb3Jt4oCdIGd1YXJkcywgZXRjLikuXHJcblx0XHRcdG9uY2UgPSBvbmNlIHx8IHt9O1xyXG5cdFx0XHRjdHggID0gY3R4ICB8fCB7IHVzZWRJZHM6IG5ldyBTZXQoKSB9O1xyXG5cclxuXHRcdFx0Y29uc3QgdHlwZSA9IFN0cmluZyggZmllbGQudHlwZSApLnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdFx0XHQvLyBPcHRpb25hbCB3cmFwcGVyIGF0dHJzIGZvciBzcGVjaWFsIHR5cGVzIChjdXJyZW50bHkgb25seSB1c2VkIGJ5IGNhcHRjaGEpLlxyXG5cdFx0XHRsZXQgaXRlbV9hdHRycyA9ICcnO1xyXG5cdFx0XHRpZiAoIHR5cGUgPT09ICdjYXB0Y2hhJyApIHtcclxuXHRcdFx0XHRpdGVtX2F0dHJzID0gV1BCQ19CRkJfRXhwb3J0ZXIuaXRlbV93cmFwcGVyX2F0dHJzKCBmaWVsZCwgY3R4ICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdG9wZW4oIGA8aXRlbSR7aXRlbV9hdHRyc30+YCApO1xyXG5cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHQvLyAxKSBMZXQgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgcGFjayBoYW5kbGUgZXhwb3J0LlxyXG5cdFx0XHRcdGxldCBoYW5kbGVkID0gZmFsc2U7XHJcblx0XHRcdFx0aWYgKCBXUEJDX0JGQl9FeHBvcnRlci5oYXNfZXhwb3J0ZXIoIHR5cGUgKSApIHtcclxuXHRcdFx0XHRcdGhhbmRsZWQgPSBXUEJDX0JGQl9FeHBvcnRlci5ydW5fcmVnaXN0ZXJlZF9leHBvcnRlciggZmllbGQsIGlvLCBjZmcsIG9uY2UsIGN0eCApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gMikgRmFsbGJhY2s6IHNob3cgYSBjbGVhciBUT0RPIGNvbW1lbnQgaWYgbm8gZXhwb3J0ZXIgaXMgcmVnaXN0ZXJlZC5cclxuXHRcdFx0XHRpZiAoICEgaGFuZGxlZCApIHtcclxuXHRcdFx0XHRcdGNvbnN0IG5hbWUgPSBXUEJDX0JGQl9FeHBvcnRlci5jb21wdXRlX25hbWUoIHR5cGUsIGZpZWxkICk7XHJcblx0XHRcdFx0XHRwdXNoKCBgPCEtLSBUT0RPOiBtYXAgZmllbGQgdHlwZSBcIiR7dHlwZX1cIiBuYW1lPVwiJHtuYW1lfVwiIGluIGEgcGFjayBleHBvcnRlciAtLT5gICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyAzKSBBcHBlbmQgaGVscCB0ZXh0IGNvbnNpc3RlbnRseSAocGFja3Mgc2hvdWxkbuKAmXQgZHVwbGljYXRlIHRoaXMpLlxyXG5cdFx0XHRcdGlmICggZmllbGQuaGVscCApIHtcclxuXHRcdFx0XHRcdHB1c2goXHJcblx0XHRcdFx0XHRcdGA8ZGl2IGNsYXNzPVwid3BiY19maWVsZF9kZXNjcmlwdGlvblwiPiR7Y29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfaHRtbChcclxuXHRcdFx0XHRcdFx0XHRTdHJpbmcoIGZpZWxkLmhlbHAgKVxyXG5cdFx0XHRcdFx0XHQpfTwvZGl2PmBcclxuXHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGZpbmFsbHkge1xyXG5cdFx0XHRcdC8vIEFsd2F5cyBjbG9zZSB3cmFwcGVyLlxyXG5cdFx0XHRcdGNsb3NlKCBgPC9pdGVtPmAgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHRcdC8vID09IEhlbHBlcnMgPT1cclxuXHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHRcdHN0YXRpYyBpc19yZXF1aXJlZChmaWVsZCkge1xyXG5cdFx0XHRjb25zdCB2ID0gZmllbGQgJiYgZmllbGQucmVxdWlyZWQ7XHJcblx0XHRcdHJldHVybiAoXHJcblx0XHRcdFx0diA9PT0gdHJ1ZSB8fFxyXG5cdFx0XHRcdHYgPT09ICd0cnVlJyB8fFxyXG5cdFx0XHRcdHYgPT09IDEgfHxcclxuXHRcdFx0XHR2ID09PSAnMScgfHxcclxuXHRcdFx0XHR2ID09PSAncmVxdWlyZWQnXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogU2hhcmVkIGxhYmVsIGVtaXR0ZXIgdXNlZCBieSBwZXItcGFjayBleHBvcnRlcnMuXHJcblx0XHQgKlxyXG5cdFx0ICogRW1pdHMgb3B0aW9uYWwgPGw+TGFiZWw8L2w+ICsgPGJyPiBiZWZvcmUgdGhlIHByb3ZpZGVkIGJvZHksXHJcblx0XHQgKiByZXNwZWN0aW5nIGNmZy5hZGRMYWJlbHMuIEhlbHAgdGV4dCBpcyBlbWl0dGVkIGNlbnRyYWxseSBpblxyXG5cdFx0ICogcmVuZGVyX2ZpZWxkX25vZGUoKSwgc28gaXQgaXMgaW50ZW50aW9uYWxseSBOT1QgaGFuZGxlZCBoZXJlLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgIGZpZWxkXHJcblx0XHQgKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZyk6IHZvaWR9ICBlbWl0XHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gICAgICAgICAgICAgICAgICBib2R5XHJcblx0XHQgKiBAcGFyYW0ge3thZGRMYWJlbHM/OiBib29sZWFufX0gIFtjZmddXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBlbWl0X2xhYmVsX3RoZW4oZmllbGQsIGVtaXQsIGJvZHksIGNmZykge1xyXG5cdFx0XHRpZiAoIHR5cGVvZiBlbWl0ICE9PSAnZnVuY3Rpb24nICkgeyByZXR1cm47IH1cclxuXHJcblx0XHRcdGNmZyA9IGNmZyB8fCB7fTtcclxuXHRcdFx0Y29uc3QgYWRkTGFiZWxzID0gY2ZnLmFkZExhYmVscyAhPT0gZmFsc2U7XHJcblxyXG5cdFx0XHRjb25zdCByYXcgICA9IChmaWVsZCAmJiB0eXBlb2YgZmllbGQubGFiZWwgPT09ICdzdHJpbmcnKSA/IGZpZWxkLmxhYmVsIDogJyc7XHJcblx0XHRcdGNvbnN0IGxhYmVsID0gcmF3LnRyaW0oKTtcclxuXHJcblx0XHRcdHZhciBpc19yZXEgICA9IHRoaXMuaXNfcmVxdWlyZWQoIGZpZWxkICk7XHJcblx0XHRcdHZhciByZXFfbWFyayA9IGlzX3JlcSA/ICcqJyA6ICcnO1xyXG5cclxuXHRcdFx0aWYgKCBsYWJlbCAmJiBhZGRMYWJlbHMgKSB7XHJcblx0XHRcdFx0Y29uc3QgZXNjX2h0bWwgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9odG1sO1xyXG5cdFx0XHRcdGVtaXQoICc8bD4nICsgZXNjX2h0bWwoIGxhYmVsICkgKyByZXFfbWFyayArICc8L2w+JyApO1xyXG5cdFx0XHRcdGVtaXQoICc8YnI+JyArIGJvZHkgKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRlbWl0KCBib2R5ICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0Ly8gPT0gSGVscGVycyA9PVxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuXHRcdC8vIC0tIFRpbWUgU2VsZWN0IEhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdHN0YXRpYyBpc190aW1lc2xvdF9waWNrZXJfZW5hYmxlZCgpIHtcclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRyZXR1cm4gISEod2luZG93Ll93cGJjICYmIHR5cGVvZiB3aW5kb3cuX3dwYmMuZ2V0X290aGVyX3BhcmFtID09PSAnZnVuY3Rpb24nXHJcblx0XHRcdFx0XHQmJiB3aW5kb3cuX3dwYmMuZ2V0X290aGVyX3BhcmFtKCdpc19lbmFibGVkX2Jvb2tpbmdfdGltZXNsb3RfcGlja2VyJykpO1xyXG5cdFx0XHR9IGNhdGNoIChfKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyB0aW1lX3BsYWNlaG9sZGVyX2ZvcihuYW1lLCBmaWVsZCkge1xyXG5cdFx0XHQvLyBQcmVmZXIgZmllbGQtc3BlY2lmaWMgcGxhY2Vob2xkZXI7IGVsc2Ugc2Vuc2libGUgZGVmYXVsdCBwZXIgZmllbGQuXHJcblx0XHRcdGlmICh0eXBlb2YgZmllbGQucGxhY2Vob2xkZXIgPT09ICdzdHJpbmcnICYmIGZpZWxkLnBsYWNlaG9sZGVyLnRyaW0oKSkge1xyXG5cdFx0XHRcdHJldHVybiBmaWVsZC5wbGFjZWhvbGRlci50cmltKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKG5hbWUgPT09ICdkdXJhdGlvbnRpbWUnKSByZXR1cm4gJy0tLSBTZWxlY3QgZHVyYXRpb24gLS0tJztcclxuXHRcdFx0cmV0dXJuICctLS0gU2VsZWN0IHRpbWUgLS0tJztcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEJ1aWxkIHRva2Vucy9kZWZhdWx0IGZvciBhIHRpbWUtbGlrZSBzZWxlY3QgKHN0YXJ0L2VuZC9yYW5nZS9kdXJhdGlvbikuXHJcblx0XHQgKiAtIEFkZHMgYW4gZW1wdHktdmFsdWUgcGxhY2Vob2xkZXIgYXMgdGhlIGZpcnN0IG9wdGlvbiBvbmx5IHdoZW46XHJcblx0XHQgKiAgIOKAoiB0aW1lIHBpY2tlciBpcyBPRkYsIGFuZFxyXG5cdFx0ICogICDigKIgbm8gb3B0aW9uIGlzIHNlbGVjdGVkIGJ5IGRlZmF1bHQsIGFuZFxyXG5cdFx0ICogICDigKIgdGhlcmUgaXNuJ3QgYWxyZWFkeSBhbiBlbXB0eS12YWx1ZSBvcHRpb24uXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBidWlsZF90aW1lX3NlbGVjdF90b2tlbnMoZmllbGQsIG5hbWUpIHtcclxuXHRcdFx0bGV0IHRva2Vuc19zdHIgPSB0aGlzLm9wdGlvbl90b2tlbnMoZmllbGQpO1xyXG5cdFx0XHRsZXQgZGVmX3N0ciAgICA9IHRoaXMuZGVmYXVsdF9vcHRpb25fc3VmZml4KGZpZWxkLCB0b2tlbnNfc3RyKTtcclxuXHJcblx0XHRcdGlmICghdGhpcy5pc190aW1lc2xvdF9waWNrZXJfZW5hYmxlZCgpKSB7XHJcblx0XHRcdFx0Y29uc3Qgb3B0cyA9IEFycmF5LmlzQXJyYXkoZmllbGQub3B0aW9ucykgPyBmaWVsZC5vcHRpb25zIDogW107XHJcblxyXG5cdFx0XHRcdGNvbnN0IGhhc19zZWxlY3RlZF9kZWZhdWx0ID0gb3B0cy5zb21lKG8gPT5cclxuXHRcdFx0XHRcdG8gJiYgKG8uc2VsZWN0ZWQgPT09IHRydWUgfHwgby5zZWxlY3RlZCA9PT0gJ3RydWUnIHx8IG8uc2VsZWN0ZWQgPT09IDEgfHwgby5zZWxlY3RlZCA9PT0gJzEnKVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdGlmICghaGFzX3NlbGVjdGVkX2RlZmF1bHQpIHtcclxuXHRcdFx0XHRcdGNvbnN0IGhhc19lbXB0eV92YWx1ZV9vcHRpb24gPSBvcHRzLnNvbWUobyA9PlxyXG5cdFx0XHRcdFx0XHRvICYmIHR5cGVvZiBvLnZhbHVlICE9PSAndW5kZWZpbmVkJyAmJiBTdHJpbmcoby52YWx1ZSkudHJpbSgpID09PSAnJ1xyXG5cdFx0XHRcdFx0KTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIWhhc19lbXB0eV92YWx1ZV9vcHRpb24pIHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgcGhUZXh0ICAgICA9IHRoaXMudGltZV9wbGFjZWhvbGRlcl9mb3IobmFtZSwgZmllbGQpO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBwaFRva2VuU3RyID0gJ1wiJyArIGNvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2Zvcl9zaG9ydGNvZGUocGhUZXh0ICsgJ0BAJykgKyAnXCInO1xyXG5cclxuXHRcdFx0XHRcdFx0Y29uc3Qgb3RoZXIgPSB0aGlzLm9wdGlvbl90b2tlbnMoZmllbGQpLnRyaW0oKTsgLy8gcmVjb21wdXRlLCB0cmltIGxlYWRpbmcgc3BhY2VcclxuXHRcdFx0XHRcdFx0dG9rZW5zX3N0ciAgPSAnICcgKyBwaFRva2VuU3RyICsgKG90aGVyID8gKCcgJyArIG90aGVyKSA6ICcnKTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIEVuc3VyZSBmaXJzdCBvcHRpb24gKG91ciBwbGFjZWhvbGRlcikgYmVjb21lcyB0aGUgZGVmYXVsdCBpbXBsaWNpdGx5XHJcblx0XHRcdFx0XHRcdGRlZl9zdHIgPSAnJztcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHsgdG9rZW5zX3N0ciwgZGVmX3N0ciB9O1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBlbWl0X3RpbWVfc2VsZWN0KG5hbWUsIGZpZWxkLCByZXFfbWFyaywgaWRfb3B0LCBjbHNfb3B0cywgZW1pdF9sYWJlbF90aGVuKSB7XHJcblx0XHRcdGNvbnN0IHsgdG9rZW5zX3N0ciwgZGVmX3N0ciB9ID0gdGhpcy5idWlsZF90aW1lX3NlbGVjdF90b2tlbnMoZmllbGQsIG5hbWUpO1xyXG5cdFx0XHQvLyBOT1RFOiBObyBzaXplL3BoIHRva2VucyBoZXJlIHRvIG1pcnJvciByYW5nZXRpbWUgYmVoYXZpb3IgZXhhY3RseS5cclxuXHRcdFx0ZW1pdF9sYWJlbF90aGVuKGBbc2VsZWN0Ym94JHtyZXFfbWFya30gJHtuYW1lfSR7aWRfb3B0fSR7Y2xzX29wdHN9JHtkZWZfc3RyfSR7dG9rZW5zX3N0cn1dYCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gLS0gT3RoZXIgSGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0Ly8gUmV0dXJuIGEgZmllbGQncyBkZWZhdWx0IHZhbHVlIChzdXBwb3J0cyBib3RoIGNhbWVsQ2FzZSBhbmQgc25ha2VfY2FzZSkuXHJcblx0XHRzdGF0aWMgZ2V0X2RlZmF1bHRfdmFsdWUoZmllbGQpIHtcclxuXHRcdFx0Y29uc3QgdiA9IGZpZWxkPy5kZWZhdWx0X3ZhbHVlID8/IGZpZWxkPy5kZWZhdWx0VmFsdWUgPz8gJyc7XHJcblx0XHRcdHJldHVybiAodiA9PSBudWxsKSA/ICcnIDogU3RyaW5nKCB2ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRm9yIHRleHQtbGlrZSBmaWVsZHMsIHRoZSBkZWZhdWx0IGlzIGEgZmluYWwgcXVvdGVkIHRva2VuIGluIHRoZSBzaG9ydGNvZGUuXHJcblx0XHRzdGF0aWMgZGVmYXVsdF90ZXh0X3N1ZmZpeChmaWVsZCkge1xyXG5cdFx0XHRjb25zdCB2ID0gdGhpcy5nZXRfZGVmYXVsdF92YWx1ZSggZmllbGQgKTtcclxuXHRcdFx0aWYgKCAhdiApIHJldHVybiAnJztcclxuXHRcdFx0cmV0dXJuIGAgXCIke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2Zvcl9zaG9ydGNvZGUoIHYgKX1cImA7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIGNsYXNzX29wdGlvbnMoZmllbGQpIHtcclxuXHRcdFx0Y29uc3QgcmF3ID0gZmllbGQuY2xhc3MgfHwgZmllbGQuY2xhc3NOYW1lIHx8IGZpZWxkLmNzc2NsYXNzIHx8ICcnO1xyXG5cdFx0XHRjb25zdCBjbHMgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplLnNhbml0aXplX2Nzc19jbGFzc2xpc3QoIFN0cmluZyggcmF3ICkgKTtcclxuXHRcdFx0aWYgKCAhY2xzICkgcmV0dXJuICcnO1xyXG5cdFx0XHRyZXR1cm4gY2xzXHJcblx0XHRcdFx0LnNwbGl0KCAvXFxzKy8gKVxyXG5cdFx0XHRcdC5maWx0ZXIoIEJvb2xlYW4gKVxyXG5cdFx0XHRcdC5tYXAoIChjKSA9PiBgIGNsYXNzOiR7Y29yZS5XUEJDX0JGQl9TYW5pdGl6ZS50b190b2tlbiggYyApfWAgKVxyXG5cdFx0XHRcdC5qb2luKCAnJyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBpZF9vcHRpb24oZmllbGQsIGN0eCkge1xyXG5cdFx0XHRjb25zdCByYXdfaWQgPSBmaWVsZC5odG1sX2lkIHx8IGZpZWxkLmlkX2F0dHI7XHJcblx0XHRcdGlmICggIXJhd19pZCApIHJldHVybiAnJztcclxuXHRcdFx0Y29uc3QgYmFzZSA9IGNvcmUuV1BCQ19CRkJfU2FuaXRpemUudG9fdG9rZW4oIHJhd19pZCApO1xyXG5cdFx0XHRpZiAoICFiYXNlICkgcmV0dXJuICcnO1xyXG5cdFx0XHRsZXQgdW5pcXVlID0gYmFzZSwgaSA9IDI7XHJcblx0XHRcdHdoaWxlICggY3R4LnVzZWRJZHMuaGFzKCB1bmlxdWUgKSApIHVuaXF1ZSA9IGAke2Jhc2V9XyR7aSsrfWA7XHJcblx0XHRcdGN0eC51c2VkSWRzLmFkZCggdW5pcXVlICk7XHJcblx0XHRcdHJldHVybiBgIGlkOiR7dW5pcXVlfWA7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIHBoX2F0dHIodikge1xyXG5cdFx0XHRpZiAoIHYgPT0gbnVsbCB8fCB2ID09PSAnJyApIHJldHVybiAnJztcclxuXHRcdFx0cmV0dXJuIGAgcGxhY2Vob2xkZXI6XCIke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2Zvcl9hdHRyX3F1b3RlZCggdiApfVwiYDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyB0ZXh0LWxpa2Ugc2l6ZS9tYXhsZW5ndGggdG9rZW46IFwiNDAvMjU1XCIgKG9yIFwiNDAvXCIgb3IgXCIvMjU1XCIpXHJcblx0XHRzdGF0aWMgc2l6ZV9tYXhfdG9rZW4oZikge1xyXG5cdFx0XHRjb25zdCBzaXplID0gcGFyc2VJbnQoIGYuc2l6ZSwgMTAgKTtcclxuXHRcdFx0Y29uc3QgbWF4ICA9IHBhcnNlSW50KCBmLm1heGxlbmd0aCwgMTAgKTtcclxuXHRcdFx0aWYgKCBOdW1iZXIuaXNGaW5pdGUoIHNpemUgKSAmJiBOdW1iZXIuaXNGaW5pdGUoIG1heCApICkgcmV0dXJuIGAgJHtzaXplfS8ke21heH1gO1xyXG5cdFx0XHRpZiAoIE51bWJlci5pc0Zpbml0ZSggc2l6ZSApICkgcmV0dXJuIGAgJHtzaXplfS9gO1xyXG5cdFx0XHRpZiAoIE51bWJlci5pc0Zpbml0ZSggbWF4ICkgKSByZXR1cm4gYCAvJHttYXh9YDtcclxuXHRcdFx0cmV0dXJuICcnO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIHRleHRhcmVhIGNvbHMvcm93cyB0b2tlbjogXCI2MHg0XCIgKG9yIFwiNjB4XCIgb3IgXCJ4NFwiKVxyXG5cdFx0c3RhdGljIGNvbHNfcm93c190b2tlbihmKSB7XHJcblx0XHRcdGNvbnN0IGNvbHMgPSBwYXJzZUludCggZi5jb2xzLCAxMCApO1xyXG5cdFx0XHRjb25zdCByb3dzID0gcGFyc2VJbnQoIGYucm93cywgMTAgKTtcclxuXHRcdFx0aWYgKCBOdW1iZXIuaXNGaW5pdGUoIGNvbHMgKSAmJiBOdW1iZXIuaXNGaW5pdGUoIHJvd3MgKSApIHJldHVybiBgICR7Y29sc314JHtyb3dzfWA7XHJcblx0XHRcdGlmICggTnVtYmVyLmlzRmluaXRlKCBjb2xzICkgKSByZXR1cm4gYCAke2NvbHN9eGA7XHJcblx0XHRcdGlmICggTnVtYmVyLmlzRmluaXRlKCByb3dzICkgKSByZXR1cm4gYCB4JHtyb3dzfWA7XHJcblx0XHRcdHJldHVybiAnJztcclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgb3B0aW9uX3Rva2VucyhmaWVsZCkge1xyXG5cdFx0XHRjb25zdCBvcHRpb25zID0gQXJyYXkuaXNBcnJheSggZmllbGQub3B0aW9ucyApID8gZmllbGQub3B0aW9ucyA6IFtdO1xyXG5cdFx0XHRpZiAoIG9wdGlvbnMubGVuZ3RoID09PSAwICkgcmV0dXJuICcnO1xyXG5cdFx0XHRjb25zdCBwYXJ0cyA9IG9wdGlvbnMubWFwKCAobykgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRpdGxlID0gU3RyaW5nKCBvLmxhYmVsID8/IG8udmFsdWUgPz8gJycgKS50cmltKCk7XHJcblx0XHRcdFx0Y29uc3QgdmFsdWUgPSBTdHJpbmcoIG8udmFsdWUgPz8gby5sYWJlbCA/PyAnJyApLnRyaW0oKTtcclxuXHRcdFx0XHRyZXR1cm4gdGl0bGUgJiYgdmFsdWUgJiYgdGl0bGUgIT09IHZhbHVlXHJcblx0XHRcdFx0XHQ/IGBcIiR7Y29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfZm9yX3Nob3J0Y29kZSggYCR7dGl0bGV9QEAke3ZhbHVlfWAgKX1cImBcclxuXHRcdFx0XHRcdDogYFwiJHtjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9mb3Jfc2hvcnRjb2RlKCB0aXRsZSB8fCB2YWx1ZSApfVwiYDtcclxuXHRcdFx0fSApO1xyXG5cdFx0XHRyZXR1cm4gJyAnICsgcGFydHMuam9pbiggJyAnICk7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIGRlZmF1bHRfb3B0aW9uX3N1ZmZpeChmaWVsZCwgdG9rZW5zKSB7XHJcblx0XHRcdGNvbnN0IG9wdGlvbnMgID0gQXJyYXkuaXNBcnJheSggZmllbGQub3B0aW9ucyApID8gZmllbGQub3B0aW9ucyA6IFtdO1xyXG5cdFx0XHRjb25zdCBzZWxlY3RlZCA9IG9wdGlvbnMuZmluZCggKG8pID0+IG8uc2VsZWN0ZWQgKTtcclxuXHRcdFx0Y29uc3QgZGVmX3ZhbCA9IHNlbGVjdGVkID8gKHNlbGVjdGVkLnZhbHVlID8/IHNlbGVjdGVkLmxhYmVsKSA6IChmaWVsZC5kZWZhdWx0X3ZhbHVlID8/IGZpZWxkLmRlZmF1bHRWYWx1ZSA/PyAnJyk7XHJcblx0XHRcdGlmICggIWRlZl92YWwgKSByZXR1cm4gJyc7XHJcblx0XHRcdHJldHVybiBgIGRlZmF1bHQ9XCIke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX3ZhbHVlX2Zvcl9hdHRyKCBkZWZfdmFsICl9XCJgO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogU0VMRUNUQk9YIC8gUkFESU8gLSBCdWlsZCB0aGUgZmluYWwgc2hvcnRjb2RlIGZvciBjaG9pY2UtYmFzZWQgZmllbGRzLlxyXG5cdFx0ICpcclxuXHRcdCAqIFJlc3BvbnNpYmlsaXRpZXM6XHJcblx0XHQgKiAgLSBEZWxlZ2F0ZXMgb3B0aW9uL2RlZmF1bHQgZW5jb2RpbmcgdG86XHJcblx0XHQgKiAgICAgIC0gV1BCQ19CRkJfRXhwb3J0ZXIub3B0aW9uX3Rva2VucyggZmllbGQgKVxyXG5cdFx0ICogICAgICAtIFdQQkNfQkZCX0V4cG9ydGVyLmRlZmF1bHRfb3B0aW9uX3N1ZmZpeCggZmllbGQsIHRva2VucyApXHJcblx0XHQgKiAgLSBGb3IgYHJhZGlvYDpcclxuXHRcdCAqICAgICAgLSBBTFdBWVMgYXBwZW5kcyBhIGJhcmUgYHVzZV9sYWJlbF9lbGVtZW50YCB0b2tlbi5cclxuXHRcdCAqICAtIEZvciBgc2VsZWN0Ym94YDpcclxuXHRcdCAqICAgICAgLSBBZGRzIGEgYmFyZSBgbXVsdGlwbGVgIHRva2VuIHdoZW4gYGZpZWxkLm11bHRpcGxlYCBpcyB0cnV0aHlcclxuXHRcdCAqICAgICAgICAodHJ1ZSwgXCJ0cnVlXCIsIDEsIFwiMVwiLCBcIm11bHRpcGxlXCIpIC0+IGBbc2VsZWN0Ym94IHNlcnZpY2VzIG11bHRpcGxlIFwiMVwiIFwiMlwiXWAuXHJcblx0XHQgKiAgICAgIC0gV2hlbiBzaW5nbGUtc2VsZWN0IEFORCB0aGVyZSBpcyBubyBgZGVmYXVsdD1cIi4uLlwiYCBhdHRyaWJ1dGUgQU5EXHJcblx0XHQgKiAgICAgICAgYSBub24tZW1wdHkgYGZpZWxkLnBsYWNlaG9sZGVyYCBpcyBwcmVzZW50LCBlbmNvZGVzIHRoZSBwbGFjZWhvbGRlclxyXG5cdFx0ICogICAgICAgIGFzIHRoZSBGSVJTVCBvcHRpb24gd2l0aCBlbXB0eSB2YWx1ZSB2aWEgdGhlIGBAQGAgc3ludGF4OlxyXG5cdFx0ICogICAgICAgICAgIHBsYWNlaG9sZGVyIFwiLS0tLSBTZWxlY3QgLS0tLVwiICAtPiAgYFwiLS0tLSBTZWxlY3QgLS0tLUBAXCJgXHJcblx0XHQgKiAgICAgICAgYW5kIGNsZWFycyBhbnkgZGVmYXVsdCBhdHRyaWJ1dGU6XHJcblx0XHQgKiAgICAgICAgICAgW3NlbGVjdGJveCogc2VydmljZXMgXCItLS0gU2VsZWN0IC0tLUBAXCIgXCJPcHRpb24gMVwiIFwiT3B0aW9uIDJcIl1cclxuXHRcdCAqICAgICAgLSBSZXNwZWN0cyBgZmllbGQudXNlX2xhYmVsX2VsZW1lbnRgIChhZGRzIGJhcmUgYHVzZV9sYWJlbF9lbGVtZW50YCB3aGVuIHRydWUpLlxyXG5cdFx0ICogIC0gRm9yIGJvdGgga2luZHM6XHJcblx0XHQgKiAgICAgIC0gSG9ub3JzIGBmaWVsZC5sYWJlbF9maXJzdGAgYnkgYXBwZW5kaW5nIGBsYWJlbF9maXJzdDpcIjFcImAgd2hlbiB0cnV0aHkuXHJcblx0XHQgKiAgICAgIC0gS2VlcHMgdGhlIHJlcXVpcmVkIHN0YXIsIGlkIGFuZCBjc3NjbGFzcyB0b2tlbnMgaW4gdGhlIGNhbm9uaWNhbCBvcmRlci5cclxuXHRcdCAqXHJcblx0XHQgKiBGaW5hbCBzaG9ydGNvZGUgbGF5b3V0IChvcmRlciBpcyBpbXBvcnRhbnQpOlxyXG5cdFx0ICogICBba2luZCByZXEgbmFtZSBpZCBjbHMgdXNlX2xhYmVsX2VsZW1lbnQgbXVsdGlwbGUgZGVmYXVsdCB0b2tlbnMgbGFiZWxfZmlyc3RdXHJcblx0XHQgKlxyXG5cdFx0ICogQGpEb2NcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBraW5kXHJcblx0XHQgKiAgIFNob3J0Y29kZSBraW5kOyB0eXBpY2FsbHkgXCJyYWRpb1wiIG9yIFwic2VsZWN0Ym94XCIuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHJlcV9tYXJrXHJcblx0XHQgKiAgIFJlcXVpcmVkIG1hcmtlciB1c2VkIGJ5IENvbnRhY3QgRm9ybSA3IHN0eWxlIHNob3J0Y29kZXM6XHJcblx0XHQgKiAgIGVpdGhlciBcIlwiIChub3QgcmVxdWlyZWQpIG9yIFwiKlwiIChyZXF1aXJlZCkuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcclxuXHRcdCAqICAgU2FuaXRpemVkIGZpZWxkIG5hbWUgYXMgZXhwb3J0ZWQgaW50byB0aGUgc2hvcnRjb2RlLCBlLmcuIFwic2VydmljZXNcIi5cclxuXHRcdCAqICAgTXVzdCBhbHJlYWR5IGJlIGNvbXB1dGVkIHZpYSBXUEJDX0JGQl9FeHBvcnRlci5jb21wdXRlX25hbWUoKS5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZmllbGRcclxuXHRcdCAqICAgTm9ybWFsaXplZCBmaWVsZCBkYXRhIG9iamVjdCBhcyBzdG9yZWQgaW4gdGhlIEJ1aWxkZXIgc3RydWN0dXJlLiBDb21tb24ga2V5czpcclxuXHRcdCAqICAgICAtIHR5cGUgICAgICAgICAgIHtzdHJpbmd9ICAgRmllbGQgdHlwZSwgZS5nLiBcInJhZGlvXCIgfCBcInNlbGVjdFwiLlxyXG5cdFx0ICogICAgIC0gb3B0aW9ucyAgICAgICAge0FycmF5fSAgICBPcHRpb24gb2JqZWN0czogeyBsYWJlbCwgdmFsdWUsIHNlbGVjdGVkIH0uXHJcblx0XHQgKiAgICAgLSBwbGFjZWhvbGRlciAgICB7c3RyaW5nfSAgIFBsYWNlaG9sZGVyIHRleHQgKHNpbmdsZS1zZWxlY3Qgb25seSkuXHJcblx0XHQgKiAgICAgLSBtdWx0aXBsZSAgICAgICB7Ym9vbGVhbnxzdHJpbmd8bnVtYmVyfSAgRW5hYmxlcyBtdWx0aS1zZWxlY3Qgd2hlbiB0cnV0aHkuXHJcblx0XHQgKiAgICAgLSB1c2VfbGFiZWxfZWxlbWVudCB7Ym9vbGVhbn0gIFJlcXVlc3QgYmFyZSBgdXNlX2xhYmVsX2VsZW1lbnRgIHRva2VuIChub24tcmFkaW8pLlxyXG5cdFx0ICogICAgIC0gbGFiZWxfZmlyc3QgICAge2Jvb2xlYW59ICBJZiB0cnVlLCBhcHBlbmRzIGBsYWJlbF9maXJzdDpcIjFcImAgdG9rZW4uXHJcblx0XHQgKiAgICAgLSBkZWZhdWx0X3ZhbHVlICB7c3RyaW5nfSAgIE9wdGlvbmFsIGRlZmF1bHQgdmFsdWUgKHVzZWQgYnkgZGVmYXVsdF9vcHRpb25fc3VmZml4KCkpLlxyXG5cdFx0ICogICAgIC0gaHRtbF9pZCAvIGNzc2NsYXNzIC8gY2xhc3MgLyBjbGFzc05hbWUgIHtzdHJpbmd9ICBVc2VkIHVwc3RyZWFtIGluIGlkX29wdC9jbHNfb3B0cy5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gaWRfb3B0XHJcblx0XHQgKiAgIE9wdGlvbmFsIGlkIHRva2VuIGJ1aWx0IGJ5IFdQQkNfQkZCX0V4cG9ydGVyLmlkX29wdGlvbihmaWVsZCwgY3R4KSxcclxuXHRcdCAqICAgZS5nLiBcIiBpZDpteV9pZFwiIG9yIGVtcHR5IHN0cmluZy5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gY2xzX29wdHNcclxuXHRcdCAqICAgQ2xhc3MgdG9rZW5zIGJ1aWx0IGJ5IFdQQkNfQkZCX0V4cG9ydGVyLmNsYXNzX29wdGlvbnMoZmllbGQpLFxyXG5cdFx0ICogICBlLmcuIFwiIGNsYXNzOm15X2NsYXNzIGNsYXNzOm90aGVyXCIuXHJcblx0XHQgKlxyXG5cdFx0ICogQHJldHVybnMge3N0cmluZ31cclxuXHRcdCAqICAgQ29tcGxldGUgc2hvcnRjb2RlIGJvZHkgZm9yIHRoZSBjaG9pY2UgZmllbGQsIGZvciBleGFtcGxlOlxyXG5cdFx0ICogICAgIFwiW3JhZGlvKiBzZXJ2aWNlcyB1c2VfbGFiZWxfZWxlbWVudCBcXFwiQVxcXCIgXFxcIkJcXFwiXVwiXHJcblx0XHQgKiAgICAgXCJbc2VsZWN0Ym94IHNlcnZpY2VzIG11bHRpcGxlIFxcXCIxXFxcIiBcXFwiMlxcXCIgXFxcIjNcXFwiXVwiXHJcblx0XHQgKiAgICAgXCJbc2VsZWN0Ym94KiBzZXJ2aWNlcyBcXFwiLS0tIFNlbGVjdCAtLS1AQFxcXCIgXFxcIk9wdGlvbiAxXFxcIiBcXFwiT3B0aW9uIDJcXFwiXVwiXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBjaG9pY2VfdGFnKGtpbmQsIHJlcV9tYXJrLCBuYW1lLCBmaWVsZCwgaWRfb3B0LCBjbHNfb3B0cykge1xyXG5cdFx0XHQvLyBTdGFydCBmcm9tIHRoZSByYXcgb3B0aW9ucy9kZWZhdWx0IGFzIGJlZm9yZS5cclxuXHRcdFx0bGV0IHRva2VucyA9IFdQQkNfQkZCX0V4cG9ydGVyLm9wdGlvbl90b2tlbnMoIGZpZWxkICk7XHJcblx0XHRcdGxldCBkZWYgICAgPSBXUEJDX0JGQl9FeHBvcnRlci5kZWZhdWx0X29wdGlvbl9zdWZmaXgoIGZpZWxkLCB0b2tlbnMgKTtcclxuXHJcblx0XHRcdC8vIEZvciBSQURJTyB3ZSBtdXN0IEFMV0FZUyBpbmNsdWRlIGEgYmFyZSBgdXNlX2xhYmVsX2VsZW1lbnRgIHRva2VuIChubyB2YWx1ZS9xdW90ZXMpLlxyXG5cdFx0XHQvLyBGb3Igb3RoZXIga2luZHMsIGtlZXAgYmFja3dhcmQgY29tcGF0aWJpbGl0eTogaW5jbHVkZSBvbmx5IGlmIGV4cGxpY2l0bHkgc2V0LlxyXG5cdFx0XHRsZXQgdWxlID0gJyc7XHJcblx0XHRcdGlmICgga2luZCA9PT0gJ3JhZGlvJyApIHtcclxuXHRcdFx0XHR1bGUgPSAnIHVzZV9sYWJlbF9lbGVtZW50JztcclxuXHRcdFx0fSBlbHNlIGlmICggZmllbGQgJiYgZmllbGQudXNlX2xhYmVsX2VsZW1lbnQgKSB7XHJcblx0XHRcdFx0dWxlID0gJyB1c2VfbGFiZWxfZWxlbWVudCc7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNFTEVDVEJPWC1zcGVjaWZpYyBleHRyYXM6XHJcblx0XHRcdC8vICAtIFwibXVsdGlwbGVcIiBmbGFnXHJcblx0XHRcdC8vICAtIHBsYWNlaG9sZGVyIGV4cG9ydGVkIGFzIEZJUlNUIE9QVElPTiB3aGVuIHNpbmdsZS1zZWxlY3QgYW5kIG5vIGRlZmF1bHQuXHJcblx0XHRcdGxldCBtdWx0aXBsZV9mbGFnID0gJyc7XHJcblxyXG5cdFx0XHRpZiAoIGtpbmQgPT09ICdzZWxlY3Rib3gnICYmIGZpZWxkICkge1xyXG5cdFx0XHRcdGNvbnN0IG11bHRpcGxlID1cclxuXHRcdFx0XHRcdGZpZWxkLm11bHRpcGxlID09PSB0cnVlICAgfHxcclxuXHRcdFx0XHRcdGZpZWxkLm11bHRpcGxlID09PSAndHJ1ZScgfHxcclxuXHRcdFx0XHRcdGZpZWxkLm11bHRpcGxlID09PSAxICAgICAgfHxcclxuXHRcdFx0XHRcdGZpZWxkLm11bHRpcGxlID09PSAnMScgICAgfHxcclxuXHRcdFx0XHRcdGZpZWxkLm11bHRpcGxlID09PSAnbXVsdGlwbGUnO1xyXG5cclxuXHRcdFx0XHRpZiAoIG11bHRpcGxlICkge1xyXG5cdFx0XHRcdFx0Ly8gRXhwb3J0IGJhcmUgXCJtdWx0aXBsZVwiIHRva2VuIGFzIGluOiBbc2VsZWN0Ym94IHNlcnZpY2VzIG11bHRpcGxlIFwiMVwiIFwiMlwiIFwiM1wiXS5cclxuXHRcdFx0XHRcdG11bHRpcGxlX2ZsYWcgPSAnIG11bHRpcGxlJztcclxuXHRcdFx0XHR9IGVsc2UgaWYgKCAhZGVmICkge1xyXG5cdFx0XHRcdFx0Ly8gU2luZ2xlLXNlbGVjdCArIE5PIGRlZmF1bHQgc2VsZWN0ZWQ6XHJcblx0XHRcdFx0XHQvLyBleHBvcnQgcGxhY2Vob2xkZXIgYXMgdGhlIEZJUlNUIE9QVElPTiB3aXRoIGVtcHR5IHZhbHVlOlxyXG5cdFx0XHRcdFx0Ly8gICBbc2VsZWN0Ym94KiBzZXJ2aWNlcyBcIi0tLSBTZWxlY3QgLS0tQEBcIiBcIk9wdGlvbiAxXCIgXCJPcHRpb24gMlwiXVxyXG5cdFx0XHRcdFx0Y29uc3QgcmF3UGggPSBmaWVsZC5wbGFjZWhvbGRlcjtcclxuXHRcdFx0XHRcdGNvbnN0IHBoICAgID0gKHR5cGVvZiByYXdQaCA9PT0gJ3N0cmluZycpID8gcmF3UGgudHJpbSgpIDogJyc7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCBwaCApIHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgUyAgICAgID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZTtcclxuXHRcdFx0XHRcdFx0Y29uc3QgZXNjX3NjID0gKFMgJiYgUy5lc2NhcGVfZm9yX3Nob3J0Y29kZSkgPyBTLmVzY2FwZV9mb3Jfc2hvcnRjb2RlIDogKHYpID0+IFN0cmluZyggdiApO1xyXG5cclxuXHRcdFx0XHRcdFx0Y29uc3QgcGhUb2tlbiA9IGBcIiR7ZXNjX3NjKCBwaCArICdAQCcgKX1cImA7XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoIHRva2VucyAmJiB0b2tlbnMubGVuZ3RoICkge1xyXG5cdFx0XHRcdFx0XHRcdC8vIHRva2VucyBhbHJlYWR5IHN0YXJ0cyB3aXRoIGEgbGVhZGluZyBzcGFjZS5cclxuXHRcdFx0XHRcdFx0XHR0b2tlbnMgPSAnICcgKyBwaFRva2VuICsgdG9rZW5zO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdHRva2VucyA9ICcgJyArIHBoVG9rZW47XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdC8vIEVuc3VyZSB0aGVyZSBpcyBzdGlsbCBOTyBkZWZhdWx0IGF0dHJpYnV0ZSB3aGVuIHVzaW5nIHBsYWNlaG9sZGVyLWFzLW9wdGlvbi5cclxuXHRcdFx0XHRcdFx0ZGVmID0gJyc7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBPcHRpb25hbDogbGFiZWxfZmlyc3Qgc3RheXMgYXMgcXVvdGVkIGZsYWcgd2hlbiBleHBsaWNpdGx5IHJlcXVlc3RlZC5cclxuXHRcdFx0Y29uc3QgbGYgPSAoZmllbGQgJiYgZmllbGQubGFiZWxfZmlyc3QpID8gJyBsYWJlbF9maXJzdDpcIjFcIicgOiAnJztcclxuXHJcblx0XHRcdC8vIElNUE9SVEFOVCBPUkRFUiAocGVyIHJlcXVlc3QpOlxyXG5cdFx0XHQvLyBba2luZCByZXEgbmFtZSBpZCBjbHMgdXNlX2xhYmVsX2VsZW1lbnQgbXVsdGlwbGUgZGVmYXVsdCB0b2tlbnMgbGFiZWxfZmlyc3RdXHJcblx0XHRcdC8vIGkuZS4gYHVzZV9sYWJlbF9lbGVtZW50YCAoYW5kIHNlbGVjdCBleHRyYXMpIGNvbWUgQkVGT1JFIGRlZmF1bHQvdG9rZW5zLlxyXG5cdFx0XHRyZXR1cm4gYFske2tpbmR9JHtyZXFfbWFya30gJHtuYW1lfSR7aWRfb3B0fSR7Y2xzX29wdHN9JHt1bGV9JHttdWx0aXBsZV9mbGFnfSR7ZGVmfSR7dG9rZW5zfSR7bGZ9XWA7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIGNvbXB1dGVfbmFtZSh0eXBlLCBmaWVsZCkge1xyXG5cdFx0XHQvLyBOYW1lcyBhcmUgZnVsbHkgdmFsaWRhdGVkIHdoZW4gdGhlIGZpZWxkIGlzIGFkZGVkIHRvIHRoZSBjYW52YXMuXHJcblx0XHRcdC8vIFRoZSBleHBvcnRlciBtdXN0IHRoZXJlZm9yZSBwcmVzZXJ2ZSB0aGVtIChhcGFydCBmcm9tIGlkZW1wb3RlbnQgc2FuaXRpemF0aW9uKSwgb3RoZXJ3aXNlIGV4aXN0aW5nIGZvcm1zIGNhbiBicmVhay5cclxuXHRcdFx0Y29uc3QgU2FuaXQgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplO1xyXG5cclxuXHRcdFx0Y29uc3QgcmF3ID0gKGZpZWxkICYmIChmaWVsZC5uYW1lIHx8IGZpZWxkLmlkKSkgPyBTdHJpbmcoZmllbGQubmFtZSB8fCBmaWVsZC5pZCkgOiBTdHJpbmcodHlwZSB8fCAnZmllbGQnKTtcclxuXHJcblx0XHRcdC8vIElkZW1wb3RlbnQgc2FuaXRpemF0aW9uIG9ubHkg4oCTIG5vIGF1dG8tcHJlZml4aW5nIG9yIHJlbmFtaW5nLlxyXG5cdFx0XHRjb25zdCBuYW1lID0gU2FuaXQuc2FuaXRpemVfaHRtbF9uYW1lKCByYXcgKTtcclxuXHJcblx0XHRcdC8vIEluIHRoZSB1bmxpa2VseSBjYXNlIHNhbml0aXphdGlvbiByZXR1cm5zIGFuIGVtcHR5IHN0cmluZywgZmFsbCBiYWNrIHRvIGEgc2FuaXRpemVkIHR5cGUtYmFzZWQgdG9rZW4uXHJcblx0XHRcdHJldHVybiBuYW1lIHx8IFNhbml0LnNhbml0aXplX2h0bWxfbmFtZSggU3RyaW5nKHR5cGUgfHwgJ2ZpZWxkJykgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJlZ2lzdGVyIGEgcGVyLWZpZWxkIGV4cG9ydGVyLlxyXG5cdFx0ICpcclxuXHRcdCAqIFRoaXMgaXMgdGhlIE9OTFkgcGxhY2Ugd2hlcmUgZmllbGQtc3BlY2lmaWMgc2hvcnRjb2RlIG1hcmt1cCBzaG91bGQgbGl2ZS5cclxuXHRcdCAqIENvcmUgc3RheXMgZ2VuZXJpYzsgcGFja3MgcHJvdmlkZSB0aW55IHBsdWdpbnMsIGZvciBleGFtcGxlOlxyXG5cdFx0ICpcclxuXHRcdCAqICAgV1BCQ19CRkJfRXhwb3J0ZXIucmVnaXN0ZXIoICd0ZXh0JywgKGZpZWxkLCBlbWl0LCBleHRyYXMpID0+IHsgLi4uIH0gKTtcclxuXHRcdCAqXHJcblx0XHQgKiBAakRvY1xyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgIEZpZWxkIHR5cGUga2V5LCBlLmcuICdzdGVwc190aW1lbGluZSdcclxuXHRcdCAqIEBwYXJhbSB7KGZpZWxkOmFueSwgZW1pdDooY29kZTpzdHJpbmcpPT52b2lkLCBleHRyYXM/Ontpbz86YW55LGNmZz86YW55LG9uY2U/OmFueSxjdHg/OmFueSxjb3JlPzphbnl9KT0+dm9pZH1cclxuXHRcdCAqICAgICBmblxyXG5cdFx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyByZWdpc3Rlcih0eXBlLCBmbikge1xyXG5cdFx0XHRpZiAoICEgdHlwZSB8fCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicgKSB7IHJldHVybjsgfVxyXG5cdFx0XHRpZiAoICEgdGhpcy5fX3JlZ2lzdHJ5ICkgeyB0aGlzLl9fcmVnaXN0cnkgPSBuZXcgTWFwKCk7IH1cclxuXHRcdFx0dGhpcy5fX3JlZ2lzdHJ5LnNldCggU3RyaW5nKCB0eXBlICkudG9Mb3dlckNhc2UoKSwgZm4gKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFVucmVnaXN0ZXIgYSBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgZXhwb3J0ZXIuXHJcblx0XHQgKlxyXG5cdFx0ICogQGpEb2NcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHVucmVnaXN0ZXIodHlwZSkge1xyXG5cdFx0XHRpZiAoICEgdGhpcy5fX3JlZ2lzdHJ5IHx8ICEgdHlwZSApIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMuX19yZWdpc3RyeS5kZWxldGUoIFN0cmluZyggdHlwZSApLnRvTG93ZXJDYXNlKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIENoZWNrIGlmIGFuIGV4cG9ydGVyIGV4aXN0cyBmb3IgYSBnaXZlbiBmaWVsZCB0eXBlLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBqRG9jXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxyXG5cdFx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBoYXNfZXhwb3J0ZXIodHlwZSkge1xyXG5cdFx0XHRyZXR1cm4gISEoIHRoaXMuX19yZWdpc3RyeSAmJiB0aGlzLl9fcmVnaXN0cnkuaGFzKCBTdHJpbmcoIHR5cGUgKS50b0xvd2VyQ2FzZSgpICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJ1biBhIHJlZ2lzdGVyZWQgZXhwb3J0ZXIgZm9yIGEgZmllbGQsIGlmIHByZXNlbnQuXHJcblx0XHQgKiBSZXR1cm5zIHRydWUgaWYgYSByZWdpc3RlcmVkIGV4cG9ydGVyIGhhbmRsZWQgaXQuXHJcblx0XHQgKlxyXG5cdFx0ICogQGpEb2NcclxuXHRcdCAqIEBwYXJhbSB7YW55fSBmaWVsZFxyXG5cdFx0ICogQHBhcmFtIHt7b3BlbjpGdW5jdGlvbixjbG9zZTpGdW5jdGlvbixwdXNoOkZ1bmN0aW9uLGJsYW5rOkZ1bmN0aW9ufX0gaW9cclxuXHRcdCAqIEBwYXJhbSB7YW55fSBjZmdcclxuXHRcdCAqIEBwYXJhbSB7YW55fSBvbmNlXHJcblx0XHQgKiBAcGFyYW0ge2FueX0gY3R4XHJcblx0XHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyKGZpZWxkLCBpbywgY2ZnLCBvbmNlLCBjdHgpIHtcclxuXHRcdFx0aWYgKCAhIGZpZWxkIHx8ICEgZmllbGQudHlwZSB8fCAhIHRoaXMuX19yZWdpc3RyeSApIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRcdGNvbnN0IGtleSA9IFN0cmluZyggZmllbGQudHlwZSApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdGNvbnN0IGZuICA9IHRoaXMuX19yZWdpc3RyeS5nZXQoIGtleSApO1xyXG5cdFx0XHRpZiAoIHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJyApIHsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdC8vIE1pbmltYWwsIGNvbnNpc3RlbnQgZW1pdCgpIGJyaWRnZSBpbnRvIG91ciBsaW5lIGJ1ZmZlcjpcclxuXHRcdFx0XHRjb25zdCBlbWl0ID0gKGNvZGUpID0+IHsgaWYgKCB0eXBlb2YgY29kZSA9PT0gJ3N0cmluZycgKSB7IGlvLnB1c2goIGNvZGUgKTsgfSB9O1xyXG5cdFx0XHRcdGZuKCBmaWVsZCwgZW1pdCwgeyBpbywgY2ZnLCBvbmNlLCBjdHgsIGNvcmUgfSApO1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9IGNhdGNoIChlKSB7XHJcblx0XHRcdFx0X3dwYmM/LmRldj8uZXJyb3I/LiggJ1dQQkNfQkZCX0V4cG9ydGVyLnJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyJywgZSApO1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHR9XHJcblxyXG5cdC8vIGV4cG9zZSBnbG9iYWxseSBmb3IgcGFja3MgKGlmIG5vdCBhbHJlYWR5KS5cclxuXHR3aW5kb3cuV1BCQ19CRkJfRXhwb3J0ZXIgPSB3aW5kb3cuV1BCQ19CRkJfRXhwb3J0ZXIgfHwgV1BCQ19CRkJfRXhwb3J0ZXI7XHJcblx0d3BiY19iZmJfX2Rpc3BhdGNoX2V2ZW50X3NhZmUoICd3cGJjOmJmYjpleHBvcnRlci1yZWFkeScsIHt9ICk7XHJcblxyXG5cdC8vIEluaXRpYWxpemUgZGVmYXVsdCBza2lwIGxpc3Q7IGFsbG93IGEgZ2xvYmFsIG92ZXJyaWRlIGFycmF5IGJlZm9yZSBleHBvcnQgcnVucy5cclxuXHRXUEJDX0JGQl9FeHBvcnRlci5zZXRfc2tpcF9hdHRycyggd2luZG93LldQQkNfQkZCX0VYUE9SVF9TS0lQX0FUVFJTIHx8IHdwYmNfZXhwb3J0X3NraXBfYXR0cnNfZGVmYXVsdCApO1xyXG5cclxuXHQvLyA9PSBcIkNvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YVwiIEV4cG9ydGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG5cdC8vIOKAkyBwYWNrLWV4dGVuc2libGUgZ2VuZXJhdG9yIGZvciBcIkNvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YVwiID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0Ly8gPT0gUHJvZHVjZXMgbWFya3VwIGxpa2U6ICBcIjxkaXYgY2xhc3M9XFxcInN0YW5kYXJkLWNvbnRlbnQtZm9ybVxcXCI+PGI+VGl0bGU8L2I+OiA8Zj5bc2hvcnRjb2RlXTwvZj48YnI+IC4uLiA8L2Rpdj5cIlxyXG5cdC8vID09IFBhY2tzIGNhbiBvdmVycmlkZSBwZXIgdHlwZSB2aWE6IFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5yZWdpc3RlcignY2FsZW5kYXInLCAoZmllbGQsIGVtaXQsIGN0eCk9PnsuLi59KVxyXG5cdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHRjbGFzcyBXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIge1xyXG5cclxuXHRcdHN0YXRpYyByZWdpc3Rlcih0eXBlLCBmbikge1xyXG5cdFx0XHRpZiAoICF0eXBlIHx8IHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJyApIHJldHVybjtcclxuXHRcdFx0aWYgKCAhdGhpcy5fX3JlZ2lzdHJ5ICkgdGhpcy5fX3JlZ2lzdHJ5ID0gbmV3IE1hcCgpO1xyXG5cdFx0XHR0aGlzLl9fcmVnaXN0cnkuc2V0KCBTdHJpbmcoIHR5cGUgKS50b0xvd2VyQ2FzZSgpLCBmbiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyB1bnJlZ2lzdGVyKHR5cGUpIHtcclxuXHRcdFx0aWYgKCAhdGhpcy5fX3JlZ2lzdHJ5IHx8ICF0eXBlICkgcmV0dXJuO1xyXG5cdFx0XHR0aGlzLl9fcmVnaXN0cnkuZGVsZXRlKCBTdHJpbmcoIHR5cGUgKS50b0xvd2VyQ2FzZSgpICk7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIGhhc19leHBvcnRlcih0eXBlKSB7XHJcblx0XHRcdHJldHVybiAhISh0aGlzLl9fcmVnaXN0cnkgJiYgdGhpcy5fX3JlZ2lzdHJ5LmhhcyggU3RyaW5nKCB0eXBlICkudG9Mb3dlckNhc2UoKSApKTtcclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgcnVuX3JlZ2lzdGVyZWRfZXhwb3J0ZXIoZmllbGQsIGVtaXQsIGN0eCkge1xyXG5cdFx0XHRpZiAoICFmaWVsZCB8fCAhZmllbGQudHlwZSB8fCAhdGhpcy5fX3JlZ2lzdHJ5ICkgcmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRjb25zdCBrZXkgPSBTdHJpbmcoIGZpZWxkLnR5cGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRjb25zdCBmbiAgPSB0aGlzLl9fcmVnaXN0cnkuZ2V0KCBrZXkgKTtcclxuXHRcdFx0aWYgKCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicgKSByZXR1cm4gZmFsc2U7XHJcblx0XHRcdHRyeSB7XHJcblx0XHRcdFx0Zm4oIGZpZWxkLCBlbWl0LCBjdHggfHwge30gKTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XHJcblx0XHRcdFx0X3dwYmM/LmRldj8uZXJyb3I/LiggJ1dQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5ydW5fcmVnaXN0ZXJlZF9leHBvcnRlcicsIGUgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyA9PT0gTkVXOiBzaGFyZWQgbGluZSBmb3JtYXR0ZXIgZm9yIFwiQ29udGVudCBvZiBib29raW5nIGZpZWxkcyBkYXRhXCIgPT09XHJcblx0XHRzdGF0aWMgZW1pdF9saW5lX2JvbGRfZmllbGQoZW1pdCwgbGFiZWwsIHRva2VuLCBjZmcpIHtcclxuXHRcdFx0Y29uc3QgUyAgICAgICAgID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZTtcclxuXHRcdFx0Y29uc3Qgc2VwICAgICAgID0gKGNmZyAmJiB0eXBlb2YgY2ZnLnNlcCA9PT0gJ3N0cmluZycpID8gY2ZnLnNlcCA6ICc6ICc7XHJcblx0XHRcdGNvbnN0IGFkZExhYmVscyA9IChjZmcgJiYgJ2FkZExhYmVscycgaW4gY2ZnKSA/ICEhY2ZnLmFkZExhYmVscyA6IHRydWU7XHJcblxyXG5cdFx0XHRjb25zdCB0aXRsZSA9IChhZGRMYWJlbHMgJiYgbGFiZWwpID8gYDxiPiR7Uy5lc2NhcGVfaHRtbChsYWJlbCl9PC9iPiR7c2VwfWAgOiAnJztcclxuXHJcblx0XHRcdGVtaXQoYCR7dGl0bGV9PGY+WyR7dG9rZW59XTwvZj48YnI+YCk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBFeHBvcnQgYWRhcHRlZCBzdHJ1Y3R1cmUgdG8g4oCcY29udGVudCBvZiBib29raW5nIGZpZWxkcyBkYXRh4oCdLlxyXG5cdFx0ICogQHBhcmFtIHt7cGFnZXM6QXJyYXl9fSBhZGFwdGVkICByZXN1bHQgb2YgYWRhcHRfYnVpbGRlcl9zdHJ1Y3R1cmVfdG9fZXhwb3J0ZXIoKVxyXG5cdFx0ICogQHBhcmFtIHt7bmV3bGluZT86c3RyaW5nLCBhZGRMYWJlbHM/OmJvb2xlYW4sIHNlcD86c3RyaW5nfX0gb3B0aW9uc1xyXG5cdFx0ICogQHJldHVybnMge3N0cmluZ31cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIGV4cG9ydF9jb250ZW50KGFkYXB0ZWQsIG9wdGlvbnMgPSB7fSkge1xyXG5cclxuXHRcdFx0Y29uc3QgY2ZnICAgPSB7IG5ld2xpbmU6ICdcXG4nLCBhZGRMYWJlbHM6IHRydWUsIHNlcDogJzogJywgaW5kZW50OiAnXFx0JywgLi4ub3B0aW9ucyB9O1xyXG5cdFx0XHRjb25zdCBJTkQgICA9ICh0eXBlb2YgY2ZnLmluZGVudCA9PT0gJ3N0cmluZycpID8gY2ZnLmluZGVudCA6ICdcXHQnO1xyXG5cdFx0XHRsZXQgZGVwdGggICA9IDA7XHJcblx0XHRcdGNvbnN0IGxpbmVzID0gW107XHJcblxyXG5cdFx0XHRjb25zdCBwdXNoICA9IChzID0gJycpID0+IGxpbmVzLnB1c2goIElORC5yZXBlYXQoIGRlcHRoICkgKyBTdHJpbmcoIHMgKSApO1xyXG5cdFx0XHRjb25zdCBvcGVuICA9IChzID0gJycpID0+IHsgcHVzaCggcyApOyBkZXB0aCsrOyB9O1xyXG5cdFx0XHRjb25zdCBjbG9zZSA9IChzID0gJycpID0+IHsgZGVwdGggPSBNYXRoLm1heCggMCwgZGVwdGggLSAxICk7IHB1c2goIHMgKTsgfTtcclxuXHJcblx0XHRcdGNvbnN0IGVtaXQgPSAocykgPT4ge1xyXG5cdFx0XHRcdGlmICggdHlwZW9mIHMgIT09ICdzdHJpbmcnICkgeyByZXR1cm47IH1cclxuXHRcdFx0XHRTdHJpbmcoIHMgKS5zcGxpdCggL1xccj9cXG4vICkuZm9yRWFjaCggKGxpbmUpID0+IHB1c2goIGxpbmUgKSApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdFx0aWYgKCAhYWRhcHRlZCB8fCAhQXJyYXkuaXNBcnJheSggYWRhcHRlZC5wYWdlcyApICkgcmV0dXJuICcnO1xyXG5cclxuXHRcdFx0Y29uc3Qgc2tpcFR5cGVzID0gbmV3IFNldCggWyAnY2FwdGNoYScsICdzdWJtaXQnLCAnZGl2aWRlcicsICd3aXphcmRfbmF2JywgJ2Nvc3RfY29ycmVjdGlvbnMnIF0gKTtcclxuXHJcblx0XHRcdGNvbnN0IGZhbGxiYWNrTGluZSA9IChmaWVsZCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHR5cGUgID0gU3RyaW5nKCBmaWVsZC50eXBlIHx8ICcnICkudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHRjb25zdCBuYW1lICA9IFdQQkNfQkZCX0V4cG9ydGVyLmNvbXB1dGVfbmFtZSggdHlwZSwgZmllbGQgKTtcclxuXHRcdFx0XHRjb25zdCBsYWJlbCA9ICh0eXBlb2YgZmllbGQubGFiZWwgPT09ICdzdHJpbmcnICYmIGZpZWxkLmxhYmVsLnRyaW0oKSkgPyBmaWVsZC5sYWJlbC50cmltKCkgOiBuYW1lO1xyXG5cdFx0XHRcdGlmICggIW5hbWUgKSByZXR1cm47XHJcblx0XHRcdFx0V1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLmVtaXRfbGluZV9ib2xkX2ZpZWxkKCBlbWl0LCBsYWJlbCwgbmFtZSwgY2ZnICk7XHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHQvLyBQZXItdHlwZSBzZW5zaWJsZSBkZWZhdWx0cyAoY2FuIGJlIG92ZXJyaWRkZW4gYnkgcGFja3MgdmlhIHJlZ2lzdGVyKCkpXHJcblx0XHRcdGNvbnN0IGRlZmF1bHRDb250ZW50Rm9yID0gKGZpZWxkKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgdHlwZSA9IFN0cmluZyggZmllbGQudHlwZSB8fCAnJyApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdFx0aWYgKCBza2lwVHlwZXMuaGFzKCB0eXBlICkgKSByZXR1cm47XHJcblx0XHRcdFx0Ly8gU3BlY2lhbCBjYXNlcyBvdXQgb2YgdGhlIGJveDpcclxuXHRcdFx0XHRpZiAoIHR5cGUgPT09ICdjYWxlbmRhcicgKSB7XHJcblx0XHRcdFx0XHRjb25zdCBsYWJlbCA9ICh0eXBlb2YgZmllbGQubGFiZWwgPT09ICdzdHJpbmcnICYmIGZpZWxkLmxhYmVsLnRyaW0oKSkgPyBmaWVsZC5sYWJlbC50cmltKCkgOiAnRGF0ZXMnO1xyXG5cdFx0XHRcdFx0V1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLmVtaXRfbGluZV9ib2xkX2ZpZWxkKCBlbWl0LCBsYWJlbCwgJ2RhdGVzJywgY2ZnICk7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdC8vIHRpbWUtbGlrZSByZXNlcnZlZCBuYW1lcyAtPiBrZWVwIHBsYWNlaG9sZGVyIHRva2VuIGVxdWFsIHRvIG5hbWVcclxuXHRcdFx0XHRjb25zdCByZXNlcnZlZCA9IFN0cmluZyggZmllbGQubmFtZSB8fCBmaWVsZC5pZCB8fCAnJyApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdFx0aWYgKCBbICdyYW5nZXRpbWUnLCAnc3RhcnR0aW1lJywgJ2VuZHRpbWUnLCAnZHVyYXRpb250aW1lJyBdLmluY2x1ZGVzKCByZXNlcnZlZCApICkge1xyXG5cdFx0XHRcdFx0Y29uc3QgbGFiZWwgPSAodHlwZW9mIGZpZWxkLmxhYmVsID09PSAnc3RyaW5nJyAmJiBmaWVsZC5sYWJlbC50cmltKCkpID8gZmllbGQubGFiZWwudHJpbSgpIDogcmVzZXJ2ZWQ7XHJcblx0XHRcdFx0XHQvLyBLZWVwIHlvdXIgc3BlY2lhbCB0b2tlbiBmb3IgZHVyYXRpb24gdGltZSBpbiBjb250ZW50OiBbZHVyYXRpb250aW1lX3ZhbF1cclxuXHRcdFx0XHRcdGNvbnN0IHRva2VuID0gKHJlc2VydmVkID09PSAnZHVyYXRpb250aW1lJykgPyAnZHVyYXRpb250aW1lX3ZhbCcgOiByZXNlcnZlZDtcclxuXHRcdFx0XHRcdFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5lbWl0X2xpbmVfYm9sZF9maWVsZCggZW1pdCwgbGFiZWwsIHRva2VuLCBjZmcgKTtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Ly8gRmFsbGJhY2sgKHRleHQvZW1haWwvdGVsL251bWJlci90ZXh0YXJlYS9zZWxlY3QvY2hlY2tib3gvcmFkaW8gZXRjLilcclxuXHRcdFx0XHRmYWxsYmFja0xpbmUoIGZpZWxkICk7XHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHQvLyBXYWxrIHBhZ2VzL3NlY3Rpb25zL2NvbHVtbnMvZmllbGRzIChzYW1lIG9yZGVyIGFzIGZvcm0pXHJcblx0XHRcdGNvbnN0IHdhbGtTZWN0aW9uICA9IChzZWMpID0+IHtcclxuXHRcdFx0XHQoc2VjLmNvbHVtbnMgfHwgW10pLmZvckVhY2goIChjb2wpID0+IHtcclxuXHRcdFx0XHRcdChjb2wuZmllbGRzIHx8IFtdKS5mb3JFYWNoKCAoZikgPT4gcHJvY2Vzc0ZpZWxkKCBmICkgKTtcclxuXHRcdFx0XHRcdChjb2wuc2VjdGlvbnMgfHwgW10pLmZvckVhY2goIChzKSA9PiB3YWxrU2VjdGlvbiggcyApICk7XHJcblx0XHRcdFx0fSApO1xyXG5cdFx0XHR9O1xyXG5cdFx0XHRjb25zdCBwcm9jZXNzSXRlbSAgPSAoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGlmICggIWl0ZW0gKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKCBpdGVtLmtpbmQgPT09ICdmaWVsZCcgKSBwcm9jZXNzRmllbGQoIGl0ZW0uZGF0YSApO1xyXG5cdFx0XHRcdGlmICggaXRlbS5raW5kID09PSAnc2VjdGlvbicgKSB3YWxrU2VjdGlvbiggaXRlbS5kYXRhICk7XHJcblx0XHRcdH07XHJcblx0XHRcdGNvbnN0IHByb2Nlc3NGaWVsZCA9IChmaWVsZCkgPT4ge1xyXG5cdFx0XHRcdGlmICggIWZpZWxkICkgcmV0dXJuO1xyXG5cdFx0XHRcdC8vIGFsbG93IHBhY2tzIHRvIG92ZXJyaWRlOlxyXG5cdFx0XHRcdGlmICggV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLnJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyKCBmaWVsZCwgZW1pdCwgeyBjZmcsIGNvcmUgfSApICkgcmV0dXJuO1xyXG5cdFx0XHRcdGRlZmF1bHRDb250ZW50Rm9yKCBmaWVsZCApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdFx0Ly8gV3JhcHBlciBmaXJzdCAtPiBpbm5lciBsaW5lcyB3aWxsIGJlIFRBQi1pbmRlbnRlZFxyXG5cdFx0XHRvcGVuKCBgPGRpdiBjbGFzcz1cInN0YW5kYXJkLWNvbnRlbnQtZm9ybVwiPmAgKTtcclxuXHRcdFx0YWRhcHRlZC5wYWdlcy5mb3JFYWNoKCAocGFnZSkgPT4gKHBhZ2UuaXRlbXMgfHwgW10pLmZvckVhY2goIHByb2Nlc3NJdGVtICkgKTtcclxuXHRcdFx0Y2xvc2UoIGA8L2Rpdj5gICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gbGluZXMuam9pbiggY2ZnLm5ld2xpbmUgKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHQvLyBleHBvc2UgKyByZWFkeSBldmVudCBmb3IgcGFja3MgdG8gcmVnaXN0ZXIgdGhlaXIgY29udGVudCBleHBvcnRlcnMuXHJcblx0d2luZG93LldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlciA9IHdpbmRvdy5XUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIgfHwgV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyO1xyXG5cdHdwYmNfYmZiX19kaXNwYXRjaF9ldmVudF9zYWZlKCAnd3BiYzpiZmI6Y29udGVudC1leHBvcnRlci1yZWFkeScsIHt9ICk7XHJcbn0pKCk7XHJcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLFlBQVk7RUFDWixZQUFZOztFQUVaLE1BQU1BLElBQUksR0FBR0MsTUFBTSxDQUFDQyxhQUFhLElBQUksQ0FBQyxDQUFDOztFQUV2QztFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7O0VBRUE7QUFDRDtBQUNBO0FBQ0E7RUFDQyxNQUFNQyw4QkFBOEIsR0FBRyxDQUFFLHVCQUF1QixDQUFFOztFQUVsRTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0MsU0FBU0MsNEJBQTRCQSxDQUFDQyxJQUFJLEVBQUVDLGVBQWUsRUFBRTtJQUM1RCxJQUFJLENBQUNELElBQUksSUFBSSxDQUFDQyxlQUFlLEVBQUVDLE1BQU0sRUFBRSxPQUFPRixJQUFJO0lBQ2xELElBQUlHLEdB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O1VBQ3JDLENBQUNBLEdBQUcsQ0FBQytCLE1BQU0sSUFBSSxFQUFFLEVBQUVVLE9BQU8sQ0FBR1QsQ0FBQyxJQUFLK0wsWUFBWSxDQUFFL0wsQ0FBRSxDQUFFLENBQUM7VUFDdEQsQ0FBQ2hDLEdBQUcsQ0FBQ21DLFFBQVEsSUFBSSxFQUFFLEVBQUVNLE9BQU8sQ0FBR2xELENBQUMsSUFBS3VPLFdBQVcsQ0FBRXZPLENBQUUsQ0FBRSxDQUFDO1FBQ3hELENBQUUsQ0FBQztNQUNKLENBQUM7TUFDRCxNQUFNeU8sV0FBVyxHQUFLdEwsSUFBSSxJQUFLO1FBQzlCLElBQUssQ0FBQ0EsSUFBSSxFQUFHO1FBQ2IsSUFBS0EsSUFBSSxDQUFDQyxJQUFJLEtBQUssT0FBTyxFQUFHb0wsWUFBWSxDQUFFckwsSUFBSSxDQUFDUixJQUFLLENBQUM7UUFDdEQsSUFBS1EsSUFBSSxDQUFDQyxJQUFJLEtBQUssU0FBUyxFQUFHbUwsV0FBVyxDQUFFcEwsSUFBSSxDQUFDUixJQUFLLENBQUM7TUFDeEQsQ0FBQztNQUNELE1BQU02TCxZQUFZLEdBQUkvRyxLQUFLLElBQUs7UUFDL0IsSUFBSyxDQUFDQSxLQUFLLEVBQUc7UUFDZDtRQUNBLElBQUt4Qix3QkFBd0IsQ0FBQ3lDLHVCQUF1QixDQUFFakIsS0FBSyxFQUFFdUIsSUFBSSxFQUFFO1VBQUU3RSxHQUFHO1VBQUV6SDtRQUFLLENBQUUsQ0FBQyxFQUFHO1FBQ3RGMFIsaUJBQWlCLENBQUUzRyxLQUFNLENBQUM7TUFDM0IsQ0FBQzs7TUFFRDtNQUNBN0MsSUFBSSxDQUFFLHFDQUFzQyxDQUFDO01BQzdDVixPQUFPLENBQUN4QyxLQUFLLENBQUN3QixPQUFPLENBQUdGLElBQUksSUFBSyxDQUFDQSxJQUFJLENBQUNyQixLQUFLLElBQUksRUFBRSxFQUFFdUIsT0FBTyxDQUFFdUwsV0FBWSxDQUFFLENBQUM7TUFDNUU1SixLQUFLLENBQUUsUUFBUyxDQUFDO01BRWpCLE9BQU9ILEtBQUssQ0FBQzlFLElBQUksQ0FBRXVFLEdBQUcsQ0FBQ0MsT0FBUSxDQUFDO0lBQ2pDO0VBRUQ7O0VBRUE7RUFDQXpILE1BQU0sQ0FBQ3NKLHdCQUF3QixHQUFHdEosTUFBTSxDQUFDc0osd0JBQXdCLElBQUlBLHdCQUF3QjtFQUM3RjRILDZCQUE2QixDQUFFLGlDQUFpQyxFQUFFLENBQUMsQ0FBRSxDQUFDO0FBQ3ZFLENBQUMsRUFBRSxDQUFDIiwiaWdub3JlTGlzdCI6W119 |
| 1146 |
|