1(() => { 2 // app/javascript/packs/stock-components/fund-web-components.es-ES.js 3 var fa = Object.defineProperty; 4 var ma = Object.defineProperties; 5 var pa = Object.getOwnPropertyDescriptors; 6 var Ke = Object.getOwnPropertySymbols; 7 var Gs = Object.prototype.hasOwnProperty; 8 var Xs = Object.prototype.propertyIsEnumerable; 9 var Js = Math.pow; 10 var Zs = (s, t, e) => t in s ? fa(s, t, { enumerable: true, configurable: true, writable: true, value: e }) : s[t] = e; 11 var M = (s, t) => { 12 for (var e in t || (t = {})) 13 Gs.call(t, e) && Zs(s, e, t[e]); 14 if (Ke) 15 for (var e of Ke(t)) 16 Xs.call(t, e) && Zs(s, e, t[e]); 17 return s; 18 }; 19 var G = (s, t) => ma(s, pa(t)); 20 var tr = (s, t) => { 21 var e = {}; 22 for (var i in s) 23 Gs.call(s, i) && t.indexOf(i) < 0 && (e[i] = s[i]); 24 if (s != null && Ke) 25 for (var i of Ke(s)) 26 t.indexOf(i) < 0 && Xs.call(s, i) && (e[i] = s[i]); 27 return e; 28 }; 29 var L = (s, t, e) => new Promise((i, r) => { 30 var n = (l) => { 31 try { 32 o(e.next(l)); 33 } catch (h) { 34 r(h); 35 } 36 }, a = (l) => { 37 try { 38 o(e.throw(l)); 39 } catch (h) { 40 r(h); 41 } 42 }, o = (l) => l.done ? i(l.value) : Promise.resolve(l.value).then(n, a); 43 o((e = e.apply(s, t)).next()); 44 }); 45 var oi = window; 46 var Ms = oi.ShadowRoot && (oi.ShadyCSS === void 0 || oi.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; 47 var Es = /* @__PURE__ */ Symbol(); 48 var er = /* @__PURE__ */ new WeakMap(); 49 var xn = class { 50 constructor(t, e, i) { 51 if (this._$cssResult$ = true, i !== Es) 52 throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); 53 this.cssText = t, this.t = e; 54 } 55 get styleSheet() { 56 let t = this.o; 57 const e = this.t; 58 if (Ms && t === void 0) { 59 const i = e !== void 0 && e.length === 1; 60 i && (t = er.get(e)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), i && er.set(e, t)); 61 } 62 return t; 63 } 64 toString() { 65 return this.cssText; 66 } 67 }; 68 var nt = (s) => new xn(typeof s == "string" ? s : s + "", void 0, Es); 69 var K = (s, ...t) => { 70 const e = s.length === 1 ? s[0] : t.reduce((i, r, n) => i + ((a) => { 71 if (a._$cssResult$ === true) 72 return a.cssText; 73 if (typeof a == "number") 74 return a; 75 throw Error("Value passed to 'css' function must be a 'css' function result: " + a + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); 76 })(r) + s[n + 1], s[0]); 77 return new xn(e, s, Es); 78 }; 79 var ga = (s, t) => { 80 Ms ? s.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet) : t.forEach((e) => { 81 const i = document.createElement("style"), r = oi.litNonce; 82 r !== void 0 && i.setAttribute("nonce", r), i.textContent = e.cssText, s.appendChild(i); 83 }); 84 }; 85 var ir = Ms ? (s) => s : (s) => s instanceof CSSStyleSheet ? ((t) => { 86 let e = ""; 87 for (const i of t.cssRules) 88 e += i.cssText; 89 return nt(e); 90 })(s) : s; 91 var zi; 92 var di = window; 93 var sr = di.trustedTypes; 94 var va = sr ? sr.emptyScript : ""; 95 var rr = di.reactiveElementPolyfillSupport; 96 var rs = { toAttribute(s, t) { 97 switch (t) { 98 case Boolean: 99 s = s ? va : null; 100 break; 101 case Object: 102 case Array: 103 s = s == null ? s : JSON.stringify(s); 104 } 105 return s; 106 }, fromAttribute(s, t) { 107 let e = s; 108 switch (t) { 109 case Boolean: 110 e = s !== null; 111 break; 112 case Number: 113 e = s === null ? null : Number(s); 114 break; 115 case Object: 116 case Array: 117 try { 118 e = JSON.parse(s); 119 } catch (i) { 120 e = null; 121 } 122 } 123 return e; 124 } }; 125 var kn = (s, t) => t !== s && (t == t || s == s); 126 var Fi = { attribute: true, type: String, converter: rs, reflect: false, hasChanged: kn }; 127 var ns = "finalized"; 128 var ce = class extends HTMLElement { 129 constructor() { 130 super(), this._$Ei = /* @__PURE__ */ new Map(), this.isUpdatePending = false, this.hasUpdated = false, this._$El = null, this._$Eu(); 131 } 132 static addInitializer(t) { 133 var e; 134 this.finalize(), ((e = this.h) !== null && e !== void 0 ? e : this.h = []).push(t); 135 } 136 static get observedAttributes() { 137 this.finalize(); 138 const t = [];
139 return this.elementProperties.forEach((e, i) => { 140 const r = this._$Ep(i, e); 141 r !== void 0 && (this._$Ev.set(r, i), t.push(r)); 142 }), t; 143 } 144 static createProperty(t, e = Fi) { 145 if (e.state && (e.attribute = false), this.finalize(), this.elementProperties.set(t, e), !e.noAccessor && !this.prototype.hasOwnProperty(t)) { 146 const i = typeof t == "symbol" ? /* @__PURE__ */ Symbol() : "__" + t, r = this.getPropertyDescriptor(t, i, e); 147 r !== void 0 && Object.defineProperty(this.prototype, t, r); 148 } 149 } 150 static getPropertyDescriptor(t, e, i) { 151 return { get() { 152 return this[e]; 153 }, set(r) { 154 const n = this[t]; 155 this[e] = r, this.requestUpdate(t, n, i); 156 }, configurable: true, enumerable: true }; 157 } 158 static getPropertyOptions(t) { 159 return this.elementProperties.get(t) || Fi; 160 } 161 static finalize() { 162 if (this.hasOwnProperty(ns)) 163 return false; 164 this[ns] = true; 165 const t = Object.getPrototypeOf(this); 166 if (t.finalize(), t.h !== void 0 && (this.h = [...t.h]), this.elementProperties = new Map(t.elementProperties), this._$Ev = /* @__PURE__ */ new Map(), this.hasOwnProperty("properties")) { 167 const e = this.properties, i = [...Object.getOwnPropertyNames(e), ...Object.getOwnPropertySymbols(e)]; 168 for (const r of i) 169 this.createProperty(r, e[r]); 170 } 171 return this.elementStyles = this.finalizeStyles(this.styles), true; 172 } 173 static finalizeStyles(t) { 174 const e = []; 175 if (Array.isArray(t)) { 176 const i = new Set(t.flat(1 / 0).reverse()); 177 for (const r of i) 178 e.unshift(ir(r)); 179 } else 180 t !== void 0 && e.push(ir(t)); 181 return e; 182 } 183 static _$Ep(t, e) { 184 const i = e.attribute; 185 return i === false ? void 0 : typeof i == "string" ? i : typeof t == "string" ? t.toLowerCase() : void 0; 186 } 187 _$Eu() { 188 var t; 189 this._$E_ = new Promise((e) => this.enableUpdating = e), this._$AL = /* @__PURE__ */ new Map(), this._$Eg(), this.requestUpdate(), (t = this.constructor.h) === null || t === void 0 || t.forEach((e) => e(this)); 190 } 191 addController(t) { 192 var e, i; 193 ((e = this._$ES) !== null && e !== void 0 ? e : this._$ES = []).push(t), this.renderRoot !== void 0 && this.isConnected && ((i = t.hostConnected) === null || i === void 0 || i.call(t)); 194 } 195 removeController(t) { 196 var e; 197 (e = this._$ES) === null || e === void 0 || e.splice(this._$ES.indexOf(t) >>> 0, 1); 198 } 199 _$Eg() { 200 this.constructor.elementProperties.forEach((t, e) => { 201 this.hasOwnProperty(e) && (this._$Ei.set(e, this[e]), delete this[e]); 202 }); 203 } 204 createRenderRoot() { 205 var t; 206 const e = (t = this.shadowRoot) !== null && t !== void 0 ? t : this.attachShadow(this.constructor.shadowRootOptions); 207 return ga(e, this.constructor.elementStyles), e; 208 } 209 connectedCallback() { 210 var t; 211 this.renderRoot === void 0 && (this.renderRoot = this.createRenderRoot()), this.enableUpdating(true), (t = this._$ES) === null || t === void 0 || t.forEach((e) => { 212 var i; 213 return (i = e.hostConnected) === null || i === void 0 ? void 0 : i.call(e); 214 }); 215 } 216 enableUpdating(t) { 217 } 218 disconnectedCallback() { 219 var t; 220 (t = this._$ES) === null || t === void 0 || t.forEach((e) => { 221 var i; 222 return (i = e.hostDisconnected) === null || i === void 0 ? void 0 : i.call(e); 223 }); 224 } 225 attributeChangedCallback(t, e, i) { 226 this._$AK(t, i); 227 } 228 _$EO(t, e, i = Fi) { 229 var r; 230 const n = this.constructor._$Ep(t, i); 231 if (n !== void 0 && i.reflect === true) { 232 const a = (((r = i.converter) === null || r === void 0 ? void 0 : r.toAttribute) !== void 0 ? i.converter : rs).toAttribute(e, i.type); 233 this._$El = t, a == null ? this.removeAttribute(n) : this.setAttribute(n, a), this._$El = null; 234 } 235 } 236 _$AK(t, e) { 237 var i; 238 const r = this.constructor, n = r._$Ev.get(t); 239 if (n !== void 0 && this._$El !== n) { 240 const a = r.getPropertyOptions(n), o = typeof a.converter == "function" ? { fromAttribute: a.converter } : ((i = a.converter) === null || i === void 0 ? void 0 : i.fromAttribute) !== void 0 ? a.converter : rs; 241 this._$El = n, this[n] = o.fromAttribute(e, a.type), this._$El = null; 242 } 243 } 244 requestUpdate(t, e, i) { 245 let r = true; 246 t !== void 0 && (((i = i || this.constructor.getPropertyOptions(t)).hasChanged || kn)(this[t], e) ? (this._$AL.has(t) || this._$AL.set(t, e), i.reflect === true && this._$El !== t && (this._$EC === void 0 && (this._$EC = /* @__PURE__ */ new Map()), this._$EC.set(t, i))) : r = false), !this.isUpdatePending && r && (this._$E_ = this._$Ej()); 247 } 248 _$Ej() { 249 return L(this, null, function* () { 250 this.isUpdatePending = true; 251 try { 252 yield this._$E_; 253 } catch (e) { 254 Promise.reject(e); 255 } 256 const t = this.scheduleUpdate(); 257 return t != null && (yield t), !this.isUpdatePending; 258 }); 259 } 260 scheduleUpdate() { 261 return this.performUpdate(); 262 } 263 performUpdate() { 264 var t; 265 if (!this.isUpdatePending) 266 return; 267 this.hasUpdated, this._$Ei && (this._$Ei.forEach((r, n) => this[n] = r), this._$Ei = void 0); 268 let e = false;
269 const i = this._$AL; 270 try { 271 e = this.shouldUpdate(i), e ? (this.willUpdate(i), (t = this._$ES) === null || t === void 0 || t.forEach((r) => { 272 var n; 273 return (n = r.hostUpdate) === null || n === void 0 ? void 0 : n.call(r); 274 }), this.update(i)) : this._$Ek(); 275 } catch (r) { 276 throw e = false, this._$Ek(), r; 277 } 278 e && this._$AE(i); 279 } 280 willUpdate(t) { 281 } 282 _$AE(t) { 283 var e; 284 (e = this._$ES) === null || e === void 0 || e.forEach((i) => { 285 var r; 286 return (r = i.hostUpdated) === null || r === void 0 ? void 0 : r.call(i); 287 }), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t)), this.updated(t); 288 } 289 _$Ek() { 290 this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false; 291 } 292 get updateComplete() { 293 return this.getUpdateComplete(); 294 } 295 getUpdateComplete() { 296 return this._$E_; 297 } 298 shouldUpdate(t) { 299 return true; 300 } 301 update(t) { 302 this._$EC !== void 0 && (this._$EC.forEach((e, i) => this._$EO(i, this[i], e)), this._$EC = void 0), this._$Ek(); 303 } 304 updated(t) { 305 } 306 firstUpdated(t) { 307 } 308 }; 309 ce[ns] = true, ce.elementProperties = /* @__PURE__ */ new Map(), ce.elementStyles = [], ce.shadowRootOptions = { mode: "open" }, rr == null || rr({ ReactiveElement: ce }), ((zi = di.reactiveElementVersions) !== null && zi !== void 0 ? zi : di.reactiveElementVersions = []).push("1.6.3"); 310 var Pi; 311 var ui = window; 312 var pe = ui.trustedTypes; 313 var nr = pe ? pe.createPolicy("lit-html", { createHTML: (s) => s }) : void 0; 314 var as = "$lit$"; 315 var Bt = `lit$${(Math.random() + "").slice(9)}$`; 316 var Sn = "?" + Bt; 317 var ba = `<${Sn}>`; 318 var Jt = document; 319 var Te = () => Jt.createComment(""); 320 var Ie = (s) => s === null || typeof s != "object" && typeof s != "function"; 321 var Cn = Array.isArray; 322 var ya = (s) => Cn(s) || typeof (s == null ? void 0 : s[Symbol.iterator]) == "function"; 323 var Ai = `[ 324\f\r]`; 325 var $e = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; 326 var ar = /-->/g; 327 var or = />/g; 328 var Wt = RegExp(`>|${Ai}(?:([^\\s"'>=/]+)(${Ai}*=${Ai}*(?:[^ 329\f\r"'\`<>=]|("|')|))|$)`, "g"); 330 var lr = /'/g; 331 var hr = /"/g; 332 var _n = /^(?:script|style|textarea|title)$/i; 333 var wa = (s) => (t, ...e) => ({ _$litType$: s, strings: t, values: e }); 334 var g = wa(1); 335 var te = /* @__PURE__ */ Symbol.for("lit-noChange"); 336 var I = /* @__PURE__ */ Symbol.for("lit-nothing"); 337 var cr = /* @__PURE__ */ new WeakMap(); 338 var Kt = Jt.createTreeWalker(Jt, 129, null, false); 339 function $n(s, t) { 340 if (!Array.isArray(s) || !s.hasOwnProperty("raw")) 341 throw Error("invalid template strings array"); 342 return nr !== void 0 ? nr.createHTML(t) : t; 343 } 344 var xa = (s, t) => { 345 const e = s.length - 1, i = []; 346 let r, n = t === 2 ? "<svg>" : "", a = $e; 347 for (let o = 0; o < e; o++) { 348 const l = s[o]; 349 let h, c, d = -1, f = 0; 350 for (; f < l.length && (a.lastIndex = f, c = a.exec(l), c !== null); ) 351 f = a.lastIndex, a === $e ? c[1] === "!--" ? a = ar : c[1] !== void 0 ? a = or : c[2] !== void 0 ? (_n.test(c[2]) && (r = RegExp("</" + c[2], "g")), a = Wt) : c[3] !== void 0 && (a = Wt) : a === Wt ? c[0] === ">" ? (a = r != null ? r : $e, d = -1) : c[1] === void 0 ? d = -2 : (d = a.lastIndex - c[2].length, h = c[1], a = c[3] === void 0 ? Wt : c[3] === '"' ? hr : lr) : a === hr || a === lr ? a = Wt : a === ar || a === or ? a = $e : (a = Wt, r = void 0); 352 const m = a === Wt && s[o + 1].startsWith("/>") ? " " : ""; 353 n += a === $e ? l + ba : d >= 0 ? (i.push(h), l.slice(0, d) + as + l.slice(d) + Bt + m) : l + Bt + (d === -2 ? (i.push(void 0), o) : m); 354 } 355 return [$n(s, n + (s[e] || "<?>") + (t === 2 ? "</svg>" : "")), i]; 356 }; 357 var os = class Dn { 358 constructor({ strings: t, _$litType$: e }, i) { 359 let r; 360 this.parts = []; 361 let n = 0, a = 0; 362 const o = t.length - 1, l = this.parts, [h, c] = xa(t, e); 363 if (this.el = Dn.createElement(h, i), Kt.currentNode = this.el.content, e === 2) { 364 const d = this.el.content, f = d.firstChild; 365 f.remove(), d.append(...f.childNodes); 366 } 367 for (; (r = Kt.nextNode()) !== null && l.length < o; ) { 368 if (r.nodeType === 1) { 369 if (r.hasAttributes()) { 370 const d = []; 371 for (const f of r.getAttributeNames()) 372 if (f.endsWith(as) || f.startsWith(Bt)) { 373 const m = c[a++]; 374 if (d.push(f), m !== void 0) { 375 const p = r.getAttribute(m.toLowerCase() + as).split(Bt), v = /([.?@])?(.*)/.exec(m); 376 l.push({ type: 1, index: n, name: v[2], strings: p, ctor: v[1] === "." ? Sa : v[1] === "?" ? _a : v[1] === "@" ? $a : bi }); 377 } else 378 l.push({ type: 6, index: n }); 379 } 380 for (const f of d) 381 r.removeAttribute(f); 382 } 383 if (_n.test(r.tagName)) { 384 const d = r.textContent.split(Bt), f = d.length - 1; 385 if (f > 0) { 386 r.textContent = pe ? pe.emptyScript : ""; 387 for (let m = 0; m < f; m++) 388 r.append(d[m], Te()), Kt.nextNode(), l.push({ type: 2, index: ++n }); 389 r.append(d[f], Te()); 390 } 391 } 392 } else if (r.nodeType === 8) 393 if (r.data === Sn) 394 l.push({ type: 2, index: n }); 395 else { 396 let d = -1; 397 for (; (d = r.data.indexOf(Bt, d + 1)) !== -1; ) 398 l.push({ type: 7, index: n }), d += Bt.length - 1; 399 } 400 n++; 401 } 402 } 403 static createElement(t, e) { 404 const i = Jt.createElement("template"); 405 return i.innerHTML = t, i; 406 } 407 }; 408 function ge(s, t, e = s, i) { 409 var r, n, a, o; 410 if (t === te) 411 return t; 412 let l = i !== void 0 ? (r = e._$Co) === null || r === void 0 ? void 0 : r[i] : e._$Cl; 413 const h = Ie(t) ? void 0 : t._$litDirective$; 414 return (l == null ? void 0 : l.constructor) !== h && ((n = l == null ? void 0 : l._$AO) === null || n === void 0 || n.call(l, false), h === void 0 ? l = void 0 : (l = new h(s), l._$AT(s, e, i)), i !== void 0 ? ((a = (o = e)._$Co) !== null && a !== void 0 ? a : o._$Co = [])[i] = l : e._$Cl = l), l !== void 0 && (t = ge(s, l._$AS(s, t.values), l, i)), t; 415 } 416 var ka = class { 417 constructor(t, e) { 418 this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = e; 419 } 420 get parentNode() { 421 return this._$AM.parentNode; 422 } 423 get _$AU() { 424 return this._$AM._$AU; 425 } 426 u(t) { 427 var e; 428 const { el: { content: i }, parts: r } = this._$AD, n = ((e = t == null ? void 0 : t.creationScope) !== null && e !== void 0 ? e : Jt).importNode(i, true); 429 Kt.currentNode = n; 430 let a = Kt.nextNode(), o = 0, l = 0, h = r[0]; 431 for (; h !== void 0; ) { 432 if (o === h.index) { 433 let c;
434 h.type === 2 ? c = new zs(a, a.nextSibling, this, t) : h.type === 1 ? c = new h.ctor(a, h.name, h.strings, this, t) : h.type === 6 && (c = new Da(a, this, t)), this._$AV.push(c), h = r[++l]; 435 } 436 o !== (h == null ? void 0 : h.index) && (a = Kt.nextNode(), o++); 437 } 438 return Kt.currentNode = Jt, n; 439 } 440 v(t) { 441 let e = 0; 442 for (const i of this._$AV) 443 i !== void 0 && (i.strings !== void 0 ? (i._$AI(t, i, e), e += i.strings.length - 2) : i._$AI(t[e])), e++; 444 } 445 }; 446 var zs = class Mn { 447 constructor(t, e, i, r) { 448 var n; 449 this.type = 2, this._$AH = I, this._$AN = void 0, this._$AA = t, this._$AB = e, this._$AM = i, this.options = r, this._$Cp = (n = r == null ? void 0 : r.isConnected) === null || n === void 0 || n; 450 } 451 get _$AU() { 452 var t, e; 453 return (e = (t = this._$AM) === null || t === void 0 ? void 0 : t._$AU) !== null && e !== void 0 ? e : this._$Cp; 454 } 455 get parentNode() { 456 let t = this._$AA.parentNode; 457 const e = this._$AM; 458 return e !== void 0 && (t == null ? void 0 : t.nodeType) === 11 && (t = e.parentNode), t; 459 } 460 get startNode() { 461 return this._$AA; 462 } 463 get endNode() { 464 return this._$AB; 465 } 466 _$AI(t, e = this) { 467 t = ge(this, t, e), Ie(t) ? t === I || t == null || t === "" ? (this._$AH !== I && this._$AR(), this._$AH = I) : t !== this._$AH && t !== te && this._(t) : t._$litType$ !== void 0 ? this.g(t) : t.nodeType !== void 0 ? this.$(t) : ya(t) ? this.T(t) : this._(t); 468 } 469 k(t) { 470 return this._$AA.parentNode.insertBefore(t, this._$AB); 471 } 472 $(t) { 473 this._$AH !== t && (this._$AR(), this._$AH = this.k(t)); 474 } 475 _(t) { 476 this._$AH !== I && Ie(this._$AH) ? this._$AA.nextSibling.data = t : this.$(Jt.createTextNode(t)), this._$AH = t; 477 } 478 g(t) { 479 var e; 480 const { values: i, _$litType$: r } = t, n = typeof r == "number" ? this._$AC(t) : (r.el === void 0 && (r.el = os.createElement($n(r.h, r.h[0]), this.options)), r); 481 if (((e = this._$AH) === null || e === void 0 ? void 0 : e._$AD) === n) 482 this._$AH.v(i); 483 else { 484 const a = new ka(n, this), o = a.u(this.options); 485 a.v(i), this.$(o), this._$AH = a; 486 } 487 } 488 _$AC(t) { 489 let e = cr.get(t.strings); 490 return e === void 0 && cr.set(t.strings, e = new os(t)), e; 491 } 492 T(t) { 493 Cn(this._$AH) || (this._$AH = [], this._$AR()); 494 const e = this._$AH; 495 let i, r = 0; 496 for (const n of t) 497 r === e.length ? e.push(i = new Mn(this.k(Te()), this.k(Te()), this, this.options)) : i = e[r], i._$AI(n), r++; 498 r < e.length && (this._$AR(i && i._$AB.nextSibling, r), e.length = r); 499 } 500 _$AR(t = this._$AA.nextSibling, e) { 501 var i; 502 for ((i = this._$AP) === null || i === void 0 || i.call(this, false, true, e); t && t !== this._$AB; ) { 503 const r = t.nextSibling; 504 t.remove(), t = r; 505 } 506 } 507 setConnected(t) { 508 var e; 509 this._$AM === void 0 && (this._$Cp = t, (e = this._$AP) === null || e === void 0 || e.call(this, t)); 510 } 511 }; 512 var bi = class { 513 constructor(t, e, i, r, n) { 514 this.type = 1, this._$AH = I, this._$AN = void 0, this.element = t, this.name = e, this._$AM = r, this.options = n, i.length > 2 || i[0] !== "" || i[1] !== "" ? (this._$AH = Array(i.length - 1).fill(new String()), this.strings = i) : this._$AH = I; 515 } 516 get tagName() { 517 return this.element.tagName; 518 } 519 get _$AU() { 520 return this._$AM._$AU; 521 } 522 _$AI(t, e = this, i, r) { 523 const n = this.strings; 524 let a = false; 525 if (n === void 0) 526 t = ge(this, t, e, 0), a = !Ie(t) || t !== this._$AH && t !== te, a && (this._$AH = t); 527 else { 528 const o = t; 529 let l, h; 530 for (t = n[0], l = 0; l < n.length - 1; l++) 531 h = ge(this, o[i + l], e, l), h === te && (h = this._$AH[l]), a || (a = !Ie(h) || h !== this._$AH[l]), h === I ? t = I : t !== I && (t += (h != null ? h : "") + n[l + 1]), this._$AH[l] = h; 532 } 533 a && !r && this.j(t); 534 } 535 j(t) { 536 t === I ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t != null ? t : ""); 537 } 538 }; 539 var Sa = class extends bi { 540 constructor() { 541 super(...arguments), this.type = 3; 542 } 543 j(t) { 544 this.element[this.name] = t === I ? void 0 : t; 545 } 546 }; 547 var Ca = pe ? pe.emptyScript : ""; 548 var _a = class extends bi { 549 constructor() { 550 super(...arguments), this.type = 4; 551 } 552 j(t) { 553 t && t !== I ? this.element.setAttribute(this.name, Ca) : this.element.removeAttribute(this.name); 554 } 555 }; 556 var $a = class extends bi { 557 constructor(t, e, i, r, n) { 558 super(t, e, i, r, n), this.type = 5; 559 } 560 _$AI(t, e = this) { 561 var i; 562 if ((t = (i = ge(this, t, e, 0)) !== null && i !== void 0 ? i : I) === te) 563 return; 564 const r = this._$AH, n = t === I && r !== I || t.capture !== r.capture || t.once !== r.once || t.passive !== r.passive, a = t !== I && (r === I || n); 565 n && this.element.removeEventListener(this.name, this, r), a && this.element.addEventListener(this.name, this, t), this._$AH = t; 566 } 567 handleEvent(t) { 568 var e, i; 569 typeof this._$AH == "function" ? this._$AH.call((i = (e = this.options) === null || e === void 0 ? void 0 : e.host) !== null && i !== void 0 ? i : this.element, t) : this._$AH.handleEvent(t); 570 } 571 }; 572 var Da = class { 573 constructor(t, e, i) { 574 this.element = t, this.type = 6, this._$AN = void 0, this._$AM = e, this.options = i; 575 } 576 get _$AU() { 577 return this._$AM._$AU; 578 } 579 _$AI(t) { 580 ge(this, t); 581 } 582 }; 583 var dr = ui.litHtmlPolyfillSupport; 584 dr == null || dr(os, zs), ((Pi = ui.litHtmlVersions) !== null && Pi !== void 0 ? Pi : ui.litHtmlVersions = []).push("2.8.0"); 585 var Ma = (s, t, e) => { 586 var i, r; 587 const n = (i = e == null ? void 0 : e.renderBefore) !== null && i !== void 0 ? i : t; 588 let a = n._$litPart$; 589 if (a === void 0) { 590 const o = (r = e == null ? void 0 : e.renderBefore) !== null && r !== void 0 ? r : null; 591 n._$litPart$ = a = new zs(t.insertBefore(Te(), o), o, void 0, e != null ? e : {}); 592 } 593 return a._$AI(s), a; 594 }; 595 var Ti; 596 var Ii; 597 var $t = class extends ce { 598 constructor() { 599 super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; 600 } 601 createRenderRoot() { 602 var t, e; 603 const i = super.createRenderRoot(); 604 return (t = (e = this.renderOptions).renderBefore) !== null && t !== void 0 || (e.renderBefore = i.firstChild), i; 605 } 606 update(t) { 607 const e = this.render(); 608 this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = Ma(e, this.renderRoot, this.renderOptions); 609 } 610 connectedCallback() { 611 var t; 612 super.connectedCallback(), (t = this._$Do) === null || t === void 0 || t.setConnected(true); 613 } 614 disconnectedCallback() { 615 var t; 616 super.disconnectedCallback(), (t = this._$Do) === null || t === void 0 || t.setConnected(false); 617 } 618 render() { 619 return te; 620 } 621 }; 622 $t.finalized = true, $t._$litElement$ = true, (Ti = globalThis.litElementHydrateSupport) === null || Ti === void 0 || Ti.call(globalThis, { LitElement: $t }); 623 var ur = globalThis.litElementPolyfillSupport; 624 ur == null || ur({ LitElement: $t }); 625 ((Ii = globalThis.litElementVersions) !== null && Ii !== void 0 ? Ii : globalThis.litElementVersions = []).push("3.3.3"); 626 var it = (s) => (t) => typeof t == "function" ? ((e, i) => (customElements.define(e, i), i))(s, t) : ((e, i) => { 627 const { kind: r, elements: n } = i; 628 return { kind: r, elements: n, finisher(a) { 629 customElements.define(e, a); 630 } }; 631 })(s, t); 632 var Ea = (s, t) => t.kind === "method" && t.descriptor && !("value" in t.descriptor) ? G(M({}, t), { finisher(e) { 633 e.createProperty(t.key, s); 634 } }) : { kind: "field", key: /* @__PURE__ */ Symbol(), placement: "own", descriptor: {}, originalKey: t.key, initializer() { 635 typeof t.initializer == "function" && (this[t.key] = t.initializer.call(this)); 636 }, finisher(e) { 637 e.createProperty(t.key, s); 638 } }; 639 var za = (s, t, e) => { 640 t.constructor.createProperty(e, s); 641 }; 642 function $(s) { 643 return (t, e) => e !== void 0 ? za(s, t, e) : Ea(s, t); 644 } 645 function C(s) { 646 return $(G(M({}, s), { state: true })); 647 } 648 var Ri; 649 ((Ri = window.HTMLSlotElement) === null || Ri === void 0 ? void 0 : Ri.prototype.assignedElements) != null; 650 var Fa = (s, ...t) => ({ 651 strTag: true, 652 strings: s, 653 values: t 654 }); 655 var A = Fa; 656 var Pa = (s) => typeof s != "string" && "strTag" in s; 657 var Aa = (s, t, e) => { 658 let i = s[0]; 659 for (let r = 1; r < s.length; r++) 660 i += t[e ? e[r - 1] : r - 1], i += s[r]; 661 return i; 662 }; 663 var En = (s) => Pa(s) ? Aa(s.strings, s.values) : s; 664 var fr = "lit-localize-status"; 665 var Ta = class { 666 constructor(t) { 667 this.__litLocalizeEventHandler = (e) => { 668 e.detail.status === "ready" && this.host.requestUpdate(); 669 }, this.host = t; 670 } 671 hostConnected() { 672 window.addEventListener(fr, this.__litLocalizeEventHandler); 673 } 674 hostDisconnected() { 675 window.removeEventListener(fr, this.__litLocalizeEventHandler); 676 } 677 }; 678 var Ia = (s) => s.addController(new Ta(s)); 679 var zn = Ia; 680 var Ra = () => (s) =>
680 typeof s == "function" ? Na(s) : La(s); 681 var lt = Ra; 682 var La = ({ kind: s, elements: t }) => ({ 683 kind: s, 684 elements: t, 685 finisher(e) { 686 e.addInitializer(zn); 687 } 688 }); 689 var Na = (s) => (s.addInitializer(zn), s); 690 var Ba = class { 691 constructor() { 692 this.settled = false, this.promise = new Promise((t, e) => { 693 this._resolve = t, this._reject = e; 694 }); 695 } 696 resolve(t) { 697 this.settled = true, this._resolve(t); 698 } 699 reject(t) { 700 this.settled = true, this._reject(t); 701 } 702 }; 703 for (let s = 0; s < 256; s++) 704 (s >> 4 & 15).toString(16) + (s & 15).toString(16); 705 var Oa = new Ba(); 706 Oa.resolve(); 707 var qa = (s) => { 708 Ua(En); 709 const t = s.sourceLocale; 710 return { 711 getLocale: () => t 712 }; 713 }; 714 var u = En; 715 var mr = false; 716 function Ua(s) { 717 if (mr) 718 throw new Error("lit-localize can only be configured once"); 719 u = s, mr = true; 720 } 721 function B(s) { 722 var t = s.width, e = s.height; 723 if (t < 0) 724 throw new Error("Negative width is not allowed for Size"); 725 if (e < 0) 726 throw new Error("Negative height is not allowed for Size"); 727 return { 728 width: t, 729 height: e 730 }; 731 } 732 function Gt(s, t) { 733 return s.width === t.width && s.height === t.height; 734 } 735 var Va = ( 736 /** @class */ 737 (function() { 738 function s(t) { 739 var e = this; 740 this._resolutionListener = function() { 741 return e._onResolutionChanged(); 742 }, this._resolutionMediaQueryList = null, this._observers = [], this._window = t, this._installResolutionListener(); 743 } 744 return s.prototype.dispose = function() { 745 this._uninstallResolutionListener(), this._window = null; 746 }, Object.defineProperty(s.prototype, "value", { 747 get: function() { 748 return this._window.devicePixelRatio; 749 }, 750 enumerable: false, 751 configurable: true 752 }), s.prototype.subscribe = function(t) { 753 var e = this, i = { next: t }; 754 return this._observers.push(i), { 755 unsubscribe: function() { 756 e._observers = e._observers.filter(function(r) { 757 return r !== i; 758 }); 759 } 760 }; 761 }, s.prototype._installResolutionListener = function() { 762 if (this._resolutionMediaQueryList !== null) 763 throw new Error("Resolution listener is already installed"); 764 var t = this._window.devicePixelRatio; 765 this._resolutionMediaQueryList = this._window.matchMedia("all and (resolution: ".concat(t, "dppx)")), this._resolutionMediaQueryList.addListener(this._resolutionListener); 766 }, s.prototype._uninstallResolutionListener = function() { 767 this._resolutionMediaQueryList !== null && (this._resolutionMediaQueryList.removeListener(this._resolutionListener), this._resolutionMediaQueryList = null); 768 }, s.prototype._reinstallResolutionListener = function() { 769 this._uninstallResolutionListener(), this._installResolutionListener(); 770 }, s.prototype._onResolutionChanged = function() { 771 var t = this; 772 this._observers.forEach(function(e) { 773 return e.next(t._window.devicePixelRatio); 774 }), this._reinstallResolutionListener(); 775 }, s; 776 })() 777 ); 778 function ja(s) { 779 return new Va(s); 780 } 781 var Ha = ( 782 /** @class */ 783 (function() { 784 function s(t, e, i) { 785 var r; 786 this._canvasElement = null, this._bitmapSizeChangedListeners = [], this._suggestedBitmapSize = null, this._suggestedBitmapSizeChangedListeners = [], this._devicePixelRatioObservable = null, this._canvasElementResizeObserver = null, this._canvasElement = t, this._canvasElementClientSize = B({ 787 width: this._canvasElement.clientWidth, 788 height: this._canvasElement.clientHeight 789 }), this._transformBitmapSize = e != null ? e : function(n) { 790 return n; 791 }, this._allowResizeObserver = (r = i == null ? void 0 : i.allowResizeObserver) !== null && r !== void 0 ? r : true, this._chooseAndInitObserver(); 792 } 793 return s.prototype.dispose = function() { 794 var t, e; 795 if (this._canvasElement === null) 796 throw new Error("Object is disposed"); 797 (t = this._canvasElementResizeObserver) === null || t === void 0 || t.disconnect(), this._canvasElementResizeObserver = null, (e = this._devicePixelRatioObservable) === null || e === void 0 || e.dispose(), this._devicePixelRatioObservable = null, this._suggestedBitmapSizeChangedListeners.length = 0, this._bitmapSizeChangedListeners.length = 0, this._canvasElement = null; 798 }, Object.defineProperty(s.prototype, "canvasElement", { 799 get: function() { 800 if (this._canvasElement === null) 801 throw new Error("Object is disposed"); 802 return this._canvasElement; 803 }, 804 enumerable: false, 805 configurable: true 806 }), Object.defineProperty(s.prototype, "canvasElementClientSize", { 807 get: function() { 808 return this._canvasElementClientSize; 809 }, 810 enumerable: false, 811 configurable: true 812 }), Object.defineProperty(s.prototype, "bitmapSize", { 813 get: function() { 814 return B({ 815 width: this.canvasElement.width, 816 height: this.canvasElement.height 817 }); 818 }, 819 enumerable: false, 820 configurable: true 821 }), s.prototype.resizeCanvasElement = function(t) { 822 this._canvasElementClientSize = B(t), this.canvasElement.style.width = "".concat(this._canvasElementClientSize.width, "px"), this.canvasElement.style.height = "".concat(this._canvasElementClientSize.height, "px"), this._invalidateBitmapSize(); 823 }, s.prototype.subscribeBitmapSizeChanged = function(t) { 824 this._bitmapSizeChangedListeners.push(t); 825 }, s.prototype.unsubscribeBitmapSizeChanged = function(t) { 826 this._bitmapSizeChangedListeners = this._bitmapSizeChangedListeners.filter(function(e) { 827 return e !== t; 828 }); 829 }, Object.defineProperty(s.prototype, "suggestedBitmapSize", { 830 get: function() { 831 return this._suggestedBitmapSize; 832 }, 833 enumerable: false, 834 configurable: true 835 }), s.prototype.subscribeSuggestedBitmapSizeChanged = function(t) { 836 this._suggestedBitmapSizeChangedListeners.push(t); 837 }, s.prototype.unsubscribeSuggestedBitmapSizeChanged = function(t) { 838 this._suggestedBitmapSizeChangedListeners = this._suggestedBitmapSizeChangedListeners.filter(function(e) { 839 return e !== t; 840 }); 841 }, s.prototype.applySuggestedBitmapSize = function() { 842 if (this._suggestedBitmapSize !== null) { 843 var t = this._suggestedBitmapSize; 844 this._suggestedBitmapSize = null, this._resizeBitmap(t), this._emitSuggestedBitmapSizeChanged(t, this._suggestedBitmapSize); 845 } 846 }, s.prototype._resizeBitmap = function(t) { 847 var e = this.bitmapSize; 848 Gt(e, t) || (this.canvasElement.width = t.width, this.canvasElement.height = t.height, this._emitBitmapSizeChanged(e, t)); 849 }, s.prototype._emitBitmapSizeChanged = function(t, e) { 850 var i = this;
851 this._bitmapSizeChangedListeners.forEach(function(r) { 852 return r.call(i, t, e); 853 }); 854 }, s.prototype._suggestNewBitmapSize = function(t) { 855 var e = this._suggestedBitmapSize, i = B(this._transformBitmapSize(t, this._canvasElementClientSize)), r = Gt(this.bitmapSize, i) ? null : i; 856 e === null && r === null || e !== null && r !== null && Gt(e, r) || (this._suggestedBitmapSize = r, this._emitSuggestedBitmapSizeChanged(e, r)); 857 }, s.prototype._emitSuggestedBitmapSizeChanged = function(t, e) { 858 var i = this; 859 this._suggestedBitmapSizeChangedListeners.forEach(function(r) { 860 return r.call(i, t, e); 861 }); 862 }, s.prototype._chooseAndInitObserver = function() { 863 var t = this; 864 if (!this._allowResizeObserver) { 865 this._initDevicePixelRatioObservable(); 866 return; 867 } 868 Qa().then(function(e) { 869 return e ? t._initResizeObserver() : t._initDevicePixelRatioObservable(); 870 }); 871 }, s.prototype._initDevicePixelRatioObservable = function() { 872 var t = this; 873 if (this._canvasElement !== null) { 874 var e = pr(this._canvasElement); 875 if (e === null) 876 throw new Error("No window is associated with the canvas"); 877 this._devicePixelRatioObservable = ja(e), this._devicePixelRatioObservable.subscribe(function() { 878 return t._invalidateBitmapSize(); 879 }), this._invalidateBitmapSize(); 880 } 881 }, s.prototype._invalidateBitmapSize = function() { 882 var t, e; 883 if (this._canvasElement !== null) { 884 var i = pr(this._canvasElement); 885 if (i !== null) { 886 var r = (e = (t = this._devicePixelRatioObservable) === null || t === void 0 ? void 0 : t.value) !== null && e !== void 0 ? e : i.devicePixelRatio, n = this._canvasElement.getClientRects(), a = ( 887 // eslint-disable-next-line no-negated-condition 888 n[0] !== void 0 ? Ya(n[0], r) : B({ 889 width: this._canvasElementClientSize.width * r, 890 height: this._canvasElementClientSize.height * r 891 }) 892 ); 893 this._suggestNewBitmapSize(a); 894 } 895 } 896 }, s.prototype._initResizeObserver = function() { 897 var t = this; 898 this._canvasElement !== null && (this._canvasElementResizeObserver = new ResizeObserver(function(e) { 899 var i = e.find(function(a) { 900 return a.target === t._canvasElement; 901 }); 902 if (!(!i || !i.devicePixelContentBoxSize || !i.devicePixelContentBoxSize[0])) { 903 var r = i.devicePixelContentBoxSize[0], n = B({ 904 width: r.inlineSize, 905 height: r.blockSize 906 }); 907 t._suggestNewBitmapSize(n); 908 } 909 }), this._canvasElementResizeObserver.observe(this._canvasElement, { box: "device-pixel-content-box" })); 910 }, s; 911 })() 912 ); 913 function Wa(s, t) { 914 if (t.type === "device-pixel-content-box") 915 return new Ha(s, t.transform, t.options); 916 throw new Error("Unsupported binding target"); 917 } 918 function pr(s) { 919 return s.ownerDocument.defaultView; 920 } 921 function Qa() { 922 return new Promise(function(s) { 923 var t = new ResizeObserver(function(e) { 924 s(e.every(function(i) { 925 return "devicePixelContentBoxSize" in i; 926 })), t.disconnect(); 927 }); 928 t.observe(document.body, { box: "device-pixel-content-box" }); 929 }).catch(function() { 930 return false; 931 }); 932 } 933 function Ya(s, t) { 934 return B({ 935 width: Math.round(s.left * t + s.width * t) - Math.round(s.left * t), 936 height: Math.round(s.top * t + s.height * t) - Math.round(s.top * t) 937 }); 938 } 939 var Ka = ( 940 /** @class */ 941 (function() { 942 function s(t, e, i) { 943 if (e.width === 0 || e.height === 0) 944 throw new TypeError("Rendering target could only be created on a media with positive width and height"); 945 if (this._mediaSize = e, i.width === 0 || i.height === 0) 946 throw new TypeError("Rendering target could only be created using a bitmap with positive integer width and height"); 947 this._bitmapSize = i, this._context = t; 948 } 949 return s.prototype.useMediaCoordinateSpace = function(t) { 950 try { 951 return this._context.save(), this._context.setTransform(1, 0, 0, 1, 0, 0), this._context.scale(this._horizontalPixelRatio, this._verticalPixelRatio), t({ 952 context: this._context, 953 mediaSize: this._mediaSize 954 }); 955 } finally {
956 this._context.restore(); 957 } 958 }, s.prototype.useBitmapCoordinateSpace = function(t) { 959 try { 960 return this._context.save(), this._context.setTransform(1, 0, 0, 1, 0, 0), t({ 961 context: this._context, 962 mediaSize: this._mediaSize, 963 bitmapSize: this._bitmapSize, 964 horizontalPixelRatio: this._horizontalPixelRatio, 965 verticalPixelRatio: this._verticalPixelRatio 966 }); 967 } finally { 968 this._context.restore(); 969 } 970 }, Object.defineProperty(s.prototype, "_horizontalPixelRatio", { 971 get: function() { 972 return this._bitmapSize.width / this._mediaSize.width; 973 }, 974 enumerable: false, 975 configurable: true 976 }), Object.defineProperty(s.prototype, "_verticalPixelRatio", { 977 get: function() { 978 return this._bitmapSize.height / this._mediaSize.height; 979 }, 980 enumerable: false, 981 configurable: true 982 }), s; 983 })() 984 ); 985 function ee(s, t) { 986 var e = s.canvasElementClientSize; 987 if (e.width === 0 || e.height === 0) 988 return null; 989 var i = s.bitmapSize; 990 if (i.width === 0 || i.height === 0) 991 return null; 992 var r = s.canvasElement.getContext("2d", t); 993 return r === null ? null : new Ka(r, e, i); 994 } 995 var Fn = { title: "", visible: true, hitTestTolerance: 3, lastValueVisible: true, priceLineVisible: true, priceLineSource: 0, priceLineWidth: 1, priceLineColor: "", priceLineStyle: 2, baseLineVisible: true, baseLineWidth: 1, baseLineColor: "#B2B5BE", baseLineStyle: 0, priceFormat: { type: "price", precision: 2, minMove: 0.01 } }; 996 var gr; 997 var Re; 998 function Ut(s, t) { 999 const e = (function(i, r) { 1000 switch (i) { 1001 case 0: 1002 default: 1003 return []; 1004 case 1: 1005 return [r, r]; 1006 case 2: 1007 return [2 * r, 2 * r]; 1008 case 3: 1009 return [6 * r, 6 * r]; 1010 case 4: 1011 return [r, 4 * r]; 1012 } 1013 })(t, s.lineWidth); 1014 return s.setLineDash(e), e; 1015 } 1016 function Pn(s, t, e, i) { 1017 s.beginPath(); 1018 const r = s.lineWidth % 2 ? 0.5 : 0; 1019 s.moveTo(e, t + r), s.lineTo(i, t + r), s.stroke(); 1020 } 1021 function et(s, t) { 1022 if (!s) 1023 throw new Error("Assertion failed" + (t ? ": " + t : "")); 1024 } 1025 function ct(s) { 1026 if (s === void 0) 1027 throw new Error("Value is undefined"); 1028 return s; 1029 } 1030 function k(s) { 1031 if (s === null) 1032 throw new Error("Value is null"); 1033 return s; 1034 } 1035 function Ot(s) { 1036 return k(ct(s)); 1037 } 1038 (function(s) { 1039 s[s.Simple = 0] = "Simple", s[s.WithSteps = 1] = "WithSteps", s[s.Curved = 2] = "Curved"; 1040 })(gr || (gr = {})), (function(s) { 1041 s[s.Solid = 0] = "Solid", s[s.Dotted = 1] = "Dotted", s[s.Dashed = 2] = "Dashed", s[s.LargeDashed = 3] = "LargeDashed", s[s.SparseDotted = 4] = "SparseDotted"; 1042 })(Re || (Re = {})); 1043 var Y = class { 1044 constructor() { 1045 this.t = []; 1046 } 1047 i(t, e, i) { 1048 const r = { h: t, l: e, o: i === true }; 1049 this.t.push(r); 1050 } 1051 _(t) { 1052 const e = this.t.findIndex((i) => t === i.h); 1053 e > -1 && this.t.splice(e, 1); 1054 } 1055 u(t) { 1056 this.t = this.t.filter((e) => e.l !== t); 1057 } 1058 p(t, e, i) { 1059 const r = [...this.t]; 1060 this.t = this.t.filter((n) => !n.o), r.forEach((n) => n.h(t, e, i)); 1061 } 1062 v() { 1063 return this.t.length > 0; 1064 } 1065 m() { 1066 this.t = []; 1067 } 1068 }; 1069 function ft(s, ...t) { 1070 for (const e of t) 1071 for (const i in e) 1072 e[i] !== void 0 && Object.prototype.hasOwnProperty.call(e, i) && !["__proto__", "constructor", "prototype"].includes(i) && (typeof e[i] != "object" || s[i] === void 0 || Array.isArray(e[i]) ? s[i] = e[i] : ft(s[i], e[i])); 1073 return s; 1074 } 1075 function ve(s) { 1076 return typeof s == "number" && isFinite(s); 1077 } 1078 function Le(s) { 1079 return typeof s == "number" && s % 1 == 0; 1080 } 1081 function Ve(s) { 1082 return typeof s == "string"; 1083 } 1084 function Ze(s) { 1085 return typeof s == "boolean"; 1086 } 1087 function zt(s) { 1088 const t = s; 1089 if (!t || typeof t != "object") 1090 return t; 1091 let e, i, r; 1092 for (i in e = Array.isArray(t) ? [] : {}, t) 1093 t.hasOwnProperty(i) && (r = t[i], e[i] = r && typeof r == "object" ? zt(r) : r); 1094 return e; 1095 } 1096 function vr(s) { 1097 return s !== null; 1098 } 1099 function ls(s) { 1100 return s === null ? void 0 : s; 1101 }
1102 var An = "-apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif"; 1103 function fi(s, t, e) { 1104 return t === void 0 && (t = An), `${e = e !== void 0 ? `${e} ` : ""}${s}px ${t}`; 1105 } 1106 var Za = class { 1107 constructor(t) { 1108 this.M = { S: 1, C: 5, k: NaN, P: "", T: "", R: "", D: "", I: 0, V: 0, B: 0, A: 0, L: 0 }, this.O = t; 1109 } 1110 N() { 1111 const t = this.M, e = this.F(), i = this.W(); 1112 return t.k === e && t.T === i || (t.k = e, t.T = i, t.P = fi(e, i), t.A = 2.5 / 12 * e, t.I = t.A, t.V = e / 12 * t.C, t.B = e / 12 * t.C, t.L = 0), t.R = this.H(), t.D = this.U(), this.M; 1113 } 1114 H() { 1115 return this.O.N().layout.textColor; 1116 } 1117 U() { 1118 return this.O.$(); 1119 } 1120 F() { 1121 return this.O.N().layout.fontSize; 1122 } 1123 W() { 1124 return this.O.N().layout.fontFamily; 1125 } 1126 }; 1127 function Li(s) { 1128 return s < 0 ? 0 : s > 255 ? 255 : Math.round(s) || 0; 1129 } 1130 function br(s) { 1131 return 0.199 * s[0] + 0.687 * s[1] + 0.114 * s[2]; 1132 } 1133 var Ga = class { 1134 constructor(t, e) { 1135 this.j = /* @__PURE__ */ new Map(), this.q = t, e && (this.j = e); 1136 } 1137 Y(t, e) { 1138 if (t === "transparent") 1139 return t; 1140 const i = this.K(t), r = i[3]; 1141 return `rgba(${i[0]}, ${i[1]}, ${i[2]}, ${e * r})`; 1142 } 1143 Z(t) { 1144 const e = this.K(t); 1145 return { G: `rgb(${e[0]}, ${e[1]}, ${e[2]})`, X: br(e) > 160 ? "black" : "white" }; 1146 } 1147 J(t) { 1148 return br(this.K(t)); 1149 } 1150 tt(t, e, i) { 1151 const [r, n, a, o] = this.K(t), [l, h, c, d] = this.K(e), f = [Li(r + i * (l - r)), Li(n + i * (h - n)), Li(a + i * (c - a)), (m = o + i * (d - o), m <= 0 || m > 1 ? Math.min(Math.max(m, 0), 1) : Math.round(1e4 * m) / 1e4)]; 1152 var m; 1153 return `rgba(${f[0]}, ${f[1]}, ${f[2]}, ${f[3]})`; 1154 } 1155 K(t) { 1156 const e = this.j.get(t); 1157 if (e) 1158 return e; 1159 const i = (function(a) { 1160 const o = document.createElement("div"); 1161 o.style.display = "none", document.body.appendChild(o), o.style.color = a; 1162 const l = window.getComputedStyle(o).color; 1163 return document.body.removeChild(o), l; 1164 })(t), r = i.match(/^rgba?\s*\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*\.?\d+))?\)$/); 1165 if (!r) { 1166 if (this.q.length) 1167 for (const a of this.q) { 1168 const o = a(t); 1169 if (o) 1170 return this.j.set(t, o), o; 1171 } 1172 throw new Error(`Failed to parse color: ${t}`); 1173 } 1174 const n = [parseInt(r[1], 10), parseInt(r[2], 10), parseInt(r[3], 10), r[4] ? parseFloat(r[4]) : 1]; 1175 return this.j.set(t, n), n; 1176 } 1177 }; 1178 var Tn = class { 1179 constructor() { 1180 this.it = []; 1181 } 1182 nt(t) { 1183 this.it = t; 1184 } 1185 st(t, e, i) { 1186 this.it.forEach((r) => { 1187 r.st(t, e, i); 1188 }); 1189 } 1190 }; 1191 var ne = class { 1192 st(t, e, i) { 1193 t.useBitmapCoordinateSpace((r) => this.et(r, e, i)); 1194 } 1195 }; 1196 var Xa = class extends ne { 1197 constructor() { 1198 super(...arguments), this.rt = null; 1199 } 1200 ht(t) { 1201 this.rt = t; 1202 } 1203 et({ context: t, horizontalPixelRatio: e, verticalPixelRatio: i }) { 1204 if (this.rt === null || this.rt.lt === null) 1205 return; 1206 const r = this.rt.lt, n = this.rt, a = Math.max(1, Math.floor(e)) % 2 / 2, o = (l) => { 1207 t.beginPath(); 1208 for (let h = r.to - 1; h >= r.from; --h) { 1209 const c = n.ot[h], d = Math.round(c._t * e) + a, f = c.ut * i, m = l * i + a; 1210 t.moveTo(d, f), t.arc(d, f, m, 0, 2 * Math.PI); 1211 } 1212 t.fill(); 1213 }; 1214 n.ct > 0 && (t.fillStyle = n.dt, o(n.ft + n.ct)), t.fillStyle = n.vt, o(n.ft); 1215 } 1216 }; 1217 function Ja() { 1218 return { ot: [{ _t: 0, ut: 0, wt: 0, Mt: 0 }], vt: "", dt: "", ft: 0, ct: 0, lt: null }; 1219 } 1220 var to = { from: 0, to: 1 }; 1221 var eo = class { 1222 constructor(t, e, i) { 1223 this.gt = new Tn(), this.bt = [], this.St = [], this.xt = true, this.O = t, this.Ct = e, this.yt = i, this.gt.nt(this.bt); 1224 } 1225 kt(t) { 1226 this.Pt(), this.xt = true; 1227 } 1228 Tt() { 1229 return this.xt && (this.Rt(), this.xt = false), this.gt; 1230 } 1231 Pt() {
1232 const t = this.yt.Dt(); 1233 t.length !== this.bt.length && (this.St = t.map(Ja), this.bt = this.St.map((e) => { 1234 const i = new Xa(); 1235 return i.ht(e), i; 1236 }), this.gt.nt(this.bt)); 1237 } 1238 Rt() { 1239 const t = this.Ct.N().mode === 2 || !this.Ct.It(), e = this.yt.Vt(), i = this.Ct.Bt(), r = this.O.Et(); 1240 this.Pt(), e.forEach((n, a) => { 1241 var c; 1242 const o = this.St[a], l = n.At(i), h = n.Lt(); 1243 !t && l !== null && n.It() && h !== null ? (o.vt = l.zt, o.ft = l.ft, o.ct = l.Ot, o.ot[0].Mt = l.Mt, o.ot[0].ut = n.Ft().Nt(l.Mt, h.Wt), o.dt = (c = l.Ht) != null ? c : this.O.Ut(o.ot[0].ut / n.Ft().$t()), o.ot[0].wt = i, o.ot[0]._t = r.jt(i), o.lt = to) : o.lt = null; 1244 }); 1245 } 1246 }; 1247 var io = class extends ne { 1248 constructor(t) { 1249 super(), this.qt = t; 1250 } 1251 et({ context: t, bitmapSize: e, horizontalPixelRatio: i, verticalPixelRatio: r }) { 1252 if (this.qt === null) 1253 return; 1254 const n = this.qt.Yt.It, a = this.qt.Kt.It; 1255 if (!n && !a) 1256 return; 1257 const o = Math.round(this.qt._t * i), l = Math.round(this.qt.ut * r); 1258 t.lineCap = "butt", n && o >= 0 && (t.lineWidth = Math.floor(this.qt.Yt.ct * i), t.strokeStyle = this.qt.Yt.R, t.fillStyle = this.qt.Yt.R, Ut(t, this.qt.Yt.Zt), (function(h, c, d, f) { 1259 h.beginPath(); 1260 const m = h.lineWidth % 2 ? 0.5 : 0; 1261 h.moveTo(c + m, d), h.lineTo(c + m, f), h.stroke(); 1262 })(t, o, 0, e.height)), a && l >= 0 && (t.lineWidth = Math.floor(this.qt.Kt.ct * r), t.strokeStyle = this.qt.Kt.R, t.fillStyle = this.qt.Kt.R, Ut(t, this.qt.Kt.Zt), Pn(t, l, 0, e.width)); 1263 } 1264 }; 1265 var so = class { 1266 constructor(t, e) { 1267 this.xt = true, this.Gt = { Yt: { ct: 1, Zt: 0, R: "", It: false }, Kt: { ct: 1, Zt: 0, R: "", It: false }, _t: 0, ut: 0 }, this.Xt = new io(this.Gt), this.Jt = t, this.yt = e; 1268 } 1269 kt() { 1270 this.xt = true; 1271 } 1272 Tt(t) { 1273 return this.xt && (this.Rt(), this.xt = false), this.Xt; 1274 } 1275 Rt() { 1276 const t = this.Jt.It(), e = this.yt.Qt().N().crosshair, i = this.Gt; 1277 if (e.mode === 2) 1278 return i.Kt.It = false, void (i.Yt.It = false); 1279 i.Kt.It = t && this.Jt.ti(this.yt), i.Yt.It = t && this.Jt.ii(), i.Kt.ct = e.horzLine.width, i.Kt.Zt = e.horzLine.style, i.Kt.R = e.horzLine.color, i.Yt.ct = e.vertLine.width, i.Yt.Zt = e.vertLine.style, i.Yt.R = e.vertLine.color, i._t = this.Jt.ni(), i.ut = this.Jt.si(); 1280 } 1281 }; 1282 function yi(s, t, e, i, r, n) { 1283 s.save(), s.globalCompositeOperation = "copy", s.fillStyle = n, s.fillRect(t, e, i, r), s.restore(); 1284 } 1285 function yr(s, t, e, i, r, n) { 1286 s.beginPath(), s.roundRect ? s.roundRect(t, e, i, r, n) : (s.lineTo(t + i - n[1], e), n[1] !== 0 && s.arcTo(t + i, e, t + i, e + n[1], n[1]), s.lineTo(t + i, e + r - n[2]), n[2] !== 0 && s.arcTo(t + i, e + r, t + i - n[2], e + r, n[2]), s.lineTo(t + n[3], e + r), n[3] !== 0 && s.arcTo(t, e + r, t, e + r - n[3], n[3]), s.lineTo(t, e + n[0]), n[0] !== 0 && s.arcTo(t, e, t + n[0], e, n[0])); 1287 } 1288 function wr(s, t, e, i, r, n, a = 0, o = [0, 0, 0, 0], l = "") { 1289 if (s.save(), !a || !l || l === n) 1290 return yr(s, t, e, i, r, o), s.fillStyle = n, s.fill(), void s.restore(); 1291 const h = a / 2; 1292 var c; 1293 yr(s, t + h, e + h, i - a, r - a, (c = -h, o.map((d) => d === 0 ? d : d + c))), n !== "transparent" && (s.fillStyle = n, s.fill()), l !== "transparent" && (s.lineWidth = a, s.strokeStyle = l, s.closePath(), s.stroke()), s.restore(); 1294 } 1295 function In(s, t, e, i, r, n, a) { 1296 s.save(), s.globalCompositeOperation = "copy"; 1297 const o = s.createLinearGradient(0, 0, 0, r); 1298 o.addColorStop(0, n), o.addColorStop(1, a), s.fillStyle = o, s.fillRect(t, e, i, r), s.restore(); 1299 } 1300 var xr = class { 1301 constructor(t, e) { 1302 this.ht(t, e); 1303 } 1304 ht(t, e) { 1305 this.qt = t, this.ei = e; 1306 } 1307 $t(t, e) { 1308 return this.qt.It ? t.k + t.A + t.I : 0; 1309 } 1310 st(t, e, i, r) { 1311 if (!this.qt.It || this.qt.ri.length === 0) 1312 return; 1313 const n = this.qt.R, a = this.ei.G, o = t.useBitmapCoordinateSpace((l) => { 1314 const h = l.context; 1315 h.font = e.P; 1316 const c = this.hi(l, e, i, r), d = c.ai; 1317 return c.li ? wr(h, d.oi, d._i, d.ui, d.ci, a, d.di, [d.ft, 0, 0, d.ft], a) : wr(h, d.fi, d._i, d.ui, d.ci, a, d.di, [0, d.ft, d.ft, 0], a), this.qt.pi && (h.fillStyle = n, h.fillRect(d.fi, d.mi, d.wi - d.fi, d.Mi)), this.qt.gi && (h.fillStyle = e.D, h.fillRect(c.li ? d.bi - d.di : 0, d._i, d.di, d.Si - d._i)), c; 1318 }); 1319 t.useMediaCoordinateSpace(({ context: l }) => { 1320 const h = o.xi; 1321 l.font = e.P, l.textAlign = o.li ? "right" : "left", l.textBaseline = "middle", l.fillStyle = n, l.fillText(this.qt.ri, h.Ci, (h._i + h.Si) / 2 + h.yi); 1322 }); 1323 } 1324 hi(t, e, i, r) { 1325 var rt, bt; 1326 const { context: n, bitmapSize: a, mediaSize: o, horizontalPixelRatio: l, verticalPixelRatio: h } = t, c = this.qt.pi || !this.qt.ki ? e.C : 0, d = this.qt.Pi ? e.S : 0, f = e.A + this.ei.Ti, m = e.I + this.ei.Ri, p = e.V, v = e.B, b = this.qt.ri, y = e.k, x = i.Di(n, b), S = Math.ceil(i.Ii(n, b)), w = y + f + m, _ = e.S + p + v + S + c, D = Math.max(1, Math.floor(h)); 1327 let z = Math.round(w * h); 1328 z % 2 != D % 2 && (z += 1); 1329 const P = d > 0 ? Math.max(1, Math.floor(d * l)) : 0, E = Math.round(_ * l), H = Math.round(c * l), J = (bt = (rt = this.ei.Vi) != null ? rt : this.ei.Bi) != null ? bt : this.ei.Ei, j = Math.round(J * h) - Math.floor(0.5 * h), Q = Math.floor(j + D / 2 - z / 2), N = Q + z, W = r === "right", at = W ? o.width - d : d, Z = W ? a.width - P : P; 1330 let Lt, U, Et; 1331 return W ? (Lt = Z - E, U = Z - H, Et = at - c - p - d) : (Lt = Z + E, U = Z + H, Et = at + c + p), { li: W, ai: { _i: Q, mi: j, Si: N, ui: E, ci: z, ft: 2 * l, di: P, oi: Lt, fi: Z, wi: U, Mi: D, bi: a.width }, xi: { _i: Q / h, Si: N / h, Ci: Et, yi: x } }; 1332 } 1333 }; 1334 var wi = class { 1335 constructor(t) { 1336 this.Ai = { Ei: 0, G: "#000", Ri: 0, Ti: 0 }, this.Li = { ri: "", It: false, pi: true, ki: false, Ht: "", R: "#FFF", gi: false, Pi: false }
1336, this.zi = { ri: "", It: false, pi: false, ki: true, Ht: "", R: "#FFF", gi: true, Pi: true }, this.xt = true, this.Oi = new (t || xr)(this.Li, this.Ai), this.Ni = new (t || xr)(this.zi, this.Ai); 1337 } 1338 ri() { 1339 return this.Fi(), this.Li.ri; 1340 } 1341 Ei() { 1342 return this.Fi(), this.Ai.Ei; 1343 } 1344 kt() { 1345 this.xt = true; 1346 } 1347 $t(t, e = false) { 1348 return Math.max(this.Oi.$t(t, e), this.Ni.$t(t, e)); 1349 } 1350 Wi() { 1351 var t; 1352 return (t = this.Ai.Vi) != null ? t : null; 1353 } 1354 Hi() { 1355 var t, e; 1356 return (e = (t = this.Ai.Vi) != null ? t : this.Ai.Bi) != null ? e : this.Ei(); 1357 } 1358 Ui(t) { 1359 this.Ai.Bi = t != null ? t : void 0; 1360 } 1361 $i() { 1362 return this.Fi(), this.Li.It || this.zi.It; 1363 } 1364 ji() { 1365 return this.Fi(), this.Li.It; 1366 } 1367 Tt(t) { 1368 return this.Fi(), this.Li.pi = this.Li.pi && t.N().ticksVisible, this.zi.pi = this.zi.pi && t.N().ticksVisible, this.Oi.ht(this.Li, this.Ai), this.Ni.ht(this.zi, this.Ai), this.Oi; 1369 } 1370 qi() { 1371 return this.Fi(), this.Oi.ht(this.Li, this.Ai), this.Ni.ht(this.zi, this.Ai), this.Ni; 1372 } 1373 Fi() { 1374 this.xt && (this.Li.pi = true, this.zi.pi = false, this.Yi(this.Li, this.zi, this.Ai)); 1375 } 1376 }; 1377 var ro = class extends wi { 1378 constructor(t, e, i) { 1379 super(), this.Jt = t, this.Ki = e, this.Zi = i; 1380 } 1381 Yi(t, e, i) { 1382 if (t.It = false, this.Jt.N().mode === 2) 1383 return; 1384 const r = this.Jt.N().horzLine; 1385 if (!r.labelVisible) 1386 return; 1387 const n = this.Ki.Lt(); 1388 if (!this.Jt.It() || this.Ki.Gi() || n === null) 1389 return; 1390 const a = this.Ki.Xi().Z(r.labelBackgroundColor); 1391 i.G = a.G, t.R = a.X; 1392 const o = 2 / 12 * this.Ki.k(); 1393 i.Ti = o, i.Ri = o; 1394 const l = this.Zi(this.Ki); 1395 i.Ei = l.Ei, t.ri = this.Ki.Ji(l.Mt, n), t.It = true; 1396 } 1397 }; 1398 var no = /[1-9]/g; 1399 var Rn = class { 1400 constructor() { 1401 this.qt = null; 1402 } 1403 ht(t) { 1404 this.qt = t; 1405 } 1406 st(t, e) { 1407 if (this.qt === null || this.qt.It === false || this.qt.ri.length === 0) 1408 return; 1409 const i = t.useMediaCoordinateSpace(({ context: f }) => (f.font = e.P, Math.round(e.Qi.Ii(f, k(this.qt).ri, no)))); 1410 if (i <= 0) 1411 return; 1412 const r = e.tn, n = i + 2 * r, a = n / 2, o = this.qt.nn; 1413 let l = this.qt.Ei, h = Math.floor(l - a) + 0.5; 1414 h < 0 ? (l += Math.abs(0 - h), h = Math.floor(l - a) + 0.5) : h + n > o && (l -= Math.abs(o - (h + n)), h = Math.floor(l - a) + 0.5); 1415 const c = h + n, d = Math.ceil(0 + e.S + e.C + e.A + e.k + e.I); 1416 t.useBitmapCoordinateSpace(({ context: f, horizontalPixelRatio: m, verticalPixelRatio: p }) => { 1417 const v = k(this.qt); 1418 f.fillStyle = v.G; 1419 const b = Math.round(h * m), y = Math.round(0 * p), x = Math.round(c * m), S = Math.round(d * p), w = Math.round(2 * m); 1420 if (f.beginPath(), f.moveTo(b, y), f.lineTo(b, S - w), f.arcTo(b, S, b + w, S, w), f.lineTo(x - w, S), f.arcTo(x, S, x, S - w, w), f.lineTo(x, y), f.fill(), v.pi) { 1421 const _ = Math.round(v.Ei * m), D = y, z = Math.round((D + e.C) * p); 1422 f.fillStyle = v.R; 1423 const P = Math.max(1, Math.floor(m)), E = Math.floor(0.5 * m); 1424 f.fillRect(_ - E, D, P, z - D); 1425 } 1426 }), t.useMediaCoordinateSpace(({ context: f }) => { 1427 const m = k(this.qt), p = 0 + e.S + e.C + e.A + e.k / 2; 1428 f.font = e.P, f.textAlign = "left", f.textBaseline = "middle", f.fillStyle = m.R; 1429 const v = e.Qi.Di(f, "Apr0"); 1430 f.translate(h + r, p + v), f.fillText(m.ri, 0, 0); 1431 }); 1432 } 1433 }; 1434 var ao = class { 1435 constructor(t, e, i) { 1436 this.xt = true, this.Xt = new Rn(), this.Gt = { It: false, G: "#4c525e", R: "white", ri: "", nn: 0, Ei: NaN, pi: true }, this.Ct = t, this.sn = e, this.Zi = i; 1437 } 1438 kt() { 1439 this.xt = true; 1440 } 1441 Tt() { 1442 return this.xt && (this.Rt(), this.xt = false), this.Xt.ht(this.Gt), this.Xt; 1443 } 1444 Rt() { 1445 const t = this.Gt; 1446 if (t.It = false, this.Ct.N().mode === 2) 1447 return; 1448 const e = this.Ct.N().vertLine; 1449 if (!e.labelVisible) 1450 return; 1451 const i = this.sn.Et(); 1452 if (i.Gi()) 1453 return; 1454 t.nn = i.nn(); 1455 const r = this.Zi(); 1456 if (r === null) 1457 return; 1458 t.Ei = r.Ei; 1459 const n = i.en(this.Ct.Bt()); 1460 t.ri = i.rn(k(n)), t.It = true;
1461 const a = this.sn.Xi().Z(e.labelBackgroundColor); 1462 t.G = a.G, t.R = a.X, t.pi = i.N().ticksVisible; 1463 } 1464 }; 1465 var Ln = class { 1466 constructor() { 1467 this.hn = null, this.an = 0; 1468 } 1469 ln() { 1470 return this.an; 1471 } 1472 _n(t) { 1473 this.an = t; 1474 } 1475 Ft() { 1476 return this.hn; 1477 } 1478 un(t) { 1479 this.hn = t; 1480 } 1481 cn(t) { 1482 return []; 1483 } 1484 dn() { 1485 return []; 1486 } 1487 It() { 1488 return true; 1489 } 1490 }; 1491 var hs; 1492 (function(s) { 1493 s[s.Normal = 0] = "Normal", s[s.Magnet = 1] = "Magnet", s[s.Hidden = 2] = "Hidden", s[s.MagnetOHLC = 3] = "MagnetOHLC"; 1494 })(hs || (hs = {})); 1495 var oo = class extends Ln { 1496 constructor(t, e) { 1497 super(), this.yt = null, this.fn = NaN, this.pn = 0, this.vn = false, this.mn = /* @__PURE__ */ new Map(), this.wn = false, this.Mn = /* @__PURE__ */ new WeakMap(), this.gn = /* @__PURE__ */ new WeakMap(), this.bn = NaN, this.Sn = NaN, this.xn = NaN, this.Cn = NaN, this.sn = t, this.yn = e, this.kn = /* @__PURE__ */ ((r, n) => (a) => { 1498 const o = n(), l = r(); 1499 if (a === k(this.yt).Pn()) 1500 return { Mt: l, Ei: o }; 1501 { 1502 const h = k(a.Lt()); 1503 return { Mt: a.Tn(o, h), Ei: o }; 1504 } 1505 })(() => this.fn, () => this.Sn); 1506 const i = /* @__PURE__ */ ((r, n) => () => { 1507 const a = this.sn.Et().Rn(r()), o = n(); 1508 return a && Number.isFinite(o) ? { wt: a, Ei: o } : null; 1509 })(() => this.pn, () => this.ni()); 1510 this.Dn = new ao(this, t, i); 1511 } 1512 N() { 1513 return this.yn; 1514 } 1515 In(t, e) { 1516 this.xn = t, this.Cn = e; 1517 } 1518 Vn() { 1519 this.xn = NaN, this.Cn = NaN; 1520 } 1521 Bn() { 1522 return this.xn; 1523 } 1524 En() { 1525 return this.Cn; 1526 } 1527 An(t, e, i) { 1528 this.wn || (this.wn = true), this.vn = true, this.Ln(t, e, i); 1529 } 1530 Bt() { 1531 return this.pn; 1532 } 1533 ni() { 1534 return this.bn; 1535 } 1536 si() { 1537 return this.Sn; 1538 } 1539 It() { 1540 return this.vn; 1541 } 1542 zn() { 1543 this.vn = false, this.On(), this.fn = NaN, this.bn = NaN, this.Sn = NaN, this.yt = null, this.Vn(), this.Nn(); 1544 } 1545 Fn(t) { 1546 if (!this.yn.doNotSnapToHiddenSeriesIndices) 1547 return t; 1548 const e = this.sn, i = e.Et(); 1549 let r = null, n = null; 1550 for (const h of e.Wn()) { 1551 const c = h.Un().Hn(t, -1); 1552 if (c) { 1553 if (c.$n === t) 1554 return t; 1555 (r === null || c.$n > r) && (r = c.$n); 1556 } 1557 const d = h.Un().Hn(t, 1); 1558 if (d) { 1559 if (d.$n === t) 1560 return t; 1561 (n === null || d.$n < n) && (n = d.$n); 1562 } 1563 } 1564 const a = [r, n].filter(vr); 1565 if (a.length === 0) 1566 return t; 1567 const o = i.jt(t), l = a.map((h) => Math.abs(o - i.jt(h))); 1568 return a[l.indexOf(Math.min(...l))]; 1569 } 1570 jn(t) { 1571 let e = this.Mn.get(t); 1572 e || (e = new so(this, t), this.Mn.set(t, e)); 1573 let i = this.gn.get(t); 1574 return i || (i = new eo(this.sn, this, t), this.gn.set(t, i)), [e, i]; 1575 } 1576 ti(t) { 1577 return t === this.yt && this.yn.horzLine.visible; 1578 } 1579 ii() { 1580 return this.yn.vertLine.visible; 1581 } 1582 qn(t, e) { 1583 this.vn && this.yt === t || this.mn.clear(); 1584 const i = []; 1585 return this.yt === t && i.push(this.Yn(this.mn, e, this.kn)), i; 1586 } 1587 dn() { 1588 return this.vn ? [this.Dn] : []; 1589 } 1590 Kn() { 1591 return this.yt; 1592 } 1593 Nn() { 1594 this.sn.Zn().forEach((t) => { 1595 var e, i; 1596 (e = this.Mn.get(t)) == null || e.kt(), (i = this.gn.get(t)) == null || i.kt(); 1597 }
1597), this.mn.forEach((t) => t.kt()), this.Dn.kt(); 1598 } 1599 Gn(t) { 1600 return t && !t.Pn().Gi() ? t.Pn() : null; 1601 } 1602 Ln(t, e, i) { 1603 this.Xn(t, e, i) && this.Nn(); 1604 } 1605 Xn(t, e, i) { 1606 const r = this.bn, n = this.Sn, a = this.fn, o = this.pn, l = this.yt, h = this.Gn(i); 1607 this.pn = t, this.bn = isNaN(t) ? NaN : this.sn.Et().jt(t), this.yt = i; 1608 const c = h !== null ? h.Lt() : null; 1609 return h !== null && c !== null ? (this.fn = e, this.Sn = h.Nt(e, c)) : (this.fn = NaN, this.Sn = NaN), r !== this.bn || n !== this.Sn || o !== this.pn || a !== this.fn || l !== this.yt; 1610 } 1611 On() { 1612 const t = this.sn.Jn().map((i) => i.Un().Qn()).filter(vr), e = t.length === 0 ? null : Math.max(...t); 1613 this.pn = e !== null ? e : NaN; 1614 } 1615 Yn(t, e, i) { 1616 let r = t.get(e); 1617 return r === void 0 && (r = new ro(this, e, i), t.set(e, r)), r; 1618 } 1619 }; 1620 function xi(s) { 1621 return s === "left" || s === "right"; 1622 } 1623 var tt = class _tt { 1624 constructor(t) { 1625 this.ts = /* @__PURE__ */ new Map(), this.ns = [], this.ss = t; 1626 } 1627 es(t, e) { 1628 const i = (function(r, n) { 1629 return r === void 0 ? n : { rs: Math.max(r.rs, n.rs), hs: r.hs || n.hs }; 1630 })(this.ts.get(t), e); 1631 this.ts.set(t, i); 1632 } 1633 ls() { 1634 return this.ss; 1635 } 1636 _s(t) { 1637 const e = this.ts.get(t); 1638 return e === void 0 ? { rs: this.ss } : { rs: Math.max(this.ss, e.rs), hs: e.hs }; 1639 } 1640 us() { 1641 this.cs(), this.ns = [{ ds: 0 }]; 1642 } 1643 fs(t) { 1644 this.cs(), this.ns = [{ ds: 1, Wt: t }]; 1645 } 1646 ps(t) { 1647 this.vs(), this.ns.push({ ds: 5, Wt: t }); 1648 } 1649 cs() { 1650 this.vs(), this.ns.push({ ds: 6 }); 1651 } 1652 ws() { 1653 this.cs(), this.ns = [{ ds: 4 }]; 1654 } 1655 Ms(t) { 1656 this.cs(), this.ns.push({ ds: 2, Wt: t }); 1657 } 1658 gs(t) { 1659 this.cs(), this.ns.push({ ds: 3, Wt: t }); 1660 } 1661 bs() { 1662 return this.ns; 1663 } 1664 Ss(t) { 1665 for (const e of t.ns) 1666 this.xs(e); 1667 this.ss = Math.max(this.ss, t.ss), t.ts.forEach((e, i) => { 1668 this.es(i, e); 1669 }); 1670 } 1671 static Cs() { 1672 return new _tt(2); 1673 } 1674 static ys() { 1675 return new _tt(3); 1676 } 1677 xs(t) { 1678 switch (t.ds) { 1679 case 0: 1680 this.us(); 1681 break; 1682 case 1: 1683 this.fs(t.Wt); 1684 break; 1685 case 2: 1686 this.Ms(t.Wt); 1687 break; 1688 case 3: 1689 this.gs(t.Wt); 1690 break; 1691 case 4: 1692 this.ws(); 1693 break; 1694 case 5: 1695 this.ps(t.Wt); 1696 break; 1697 case 6: 1698 this.vs(); 1699 } 1700 } 1701 vs() { 1702 const t = this.ns.findIndex((e) => e.ds === 5); 1703 t !== -1 && this.ns.splice(t, 1); 1704 } 1705 }; 1706 var Nn = class { 1707 formatTickmarks(t) { 1708 return t.map((e) => this.format(e)); 1709 } 1710 }; 1711 var kr = "."; 1712 function Ft(s, t) { 1713 if (!ve(s)) 1714 return "n/a"; 1715 if (!Le(t)) 1716 throw new TypeError("invalid length"); 1717 if (t < 0 || t > 16) 1718 throw new TypeError("invalid length"); 1719 return t === 0 ? s.toString() : ("0000000000000000" + s.toString()).slice(-t); 1720 } 1721 var ki = class extends Nn { 1722 constructor(t, e) { 1723 if (super(), e || (e = 1), ve(t) && Le(t) || (t = 100), t < 0) 1724 throw new TypeError("invalid base"); 1725 this.Ki = t, this.ks = e, this.Ps(); 1726 } 1727 format(t) { 1728 const e = t < 0 ? "\u2212" : ""; 1729 return t = Math.abs(t), e + this.Ts(t); 1730 } 1731 Ps() { 1732 if (this.Rs = 0, this.Ki > 0 && this.ks > 0) { 1733 let t = this.Ki; 1734 for (; t > 1; ) 1735 t /= 10, this.Rs++; 1736 } 1737 } 1738 Ts(t) { 1739 const e = this.Ki / this.ks; 1740 let i = Math.floor(t), r = ""; 1741 const n = this.Rs !== void 0 ? this.Rs : NaN; 1742 if (e > 1) { 1743 let a = +(Math.round(t * e) - i * e).toFixed(this.Rs); 1744 a >= e && (a -= e, i += 1), r = kr + Ft(+a.toFixed(this.Rs) * this.ks, n); 1745 } else 1746 i = Math.round(i * e) / e, n > 0 && (r = kr + Ft(0, n)); 1747 return i.toFixed(0) + r; 1748 } 1749 }; 1750 var Bn = class extends ki { 1751 constructor(t = 100) { 1752 super(t); 1753 } 1754 format(t) { 1755 return `${super.format(t)}%`; 1756 } 1757 }; 1758 var lo = class extends Nn { 1759 constructor(t) { 1760 super(), this.Ds = t; 1761 } 1762 format(t) { 1763 let e = ""; 1764 return t < 0 && (e = "-", t = -t), t < 995 ? e + this.Is(t) : t < 999995 ? e + this.Is(t / 1e3) + "K" : t < 999999995 ? (t = 1e3 * Math.round(t / 1e3), e + this.Is(t / 1e6) + "M") : (t = 1e6 * Math.round(t / 1e6), e + this.Is(t / 1e9) + "B"); 1765 } 1766 Is(t) { 1767 let e; 1768 const i = Math.pow(10, this.Ds); 1769 return e = (t = Math.round(t * i) / i) >= 1e-15 && t < 1 ? t.toFixed(this.Ds).replace(/\.?0+$/, "") : String(t), e.replace(/(\.[1-9]*)0+$/, (r, n) => n); 1770 } 1771 }; 1772 var ho = /[2-9]/g; 1773 var mi = class { 1774 constructor(t = 50) { 1775 this.Vs = 0, this.Bs = 1, this.Es = 1, this.As = {}, this.Ls = /* @__PURE__ */ new Map(), this.zs = t; 1776 } 1777 Os() { 1778 this.Vs = 0, this.Ls.clear(), this.Bs = 1, this.Es = 1, this.As = {}; 1779 } 1780 Ii(t, e, i) { 1781 return this.Ns(t, e, i).width; 1782 } 1783 Di(t, e, i) { 1784 const r = this.Ns(t, e, i); 1785 return ((r.actualBoundingBoxAscent || 0) - (r.actualBoundingBoxDescent || 0)) / 2; 1786 } 1787 Ns(t, e, i) { 1788 const r = i || ho, n = String(e).replace(r, "0"); 1789 if (this.Ls.has(n)) 1790 return ct(this.Ls.get(n)).Fs; 1791 if (this.Vs === this.zs) { 1792 const o = this.As[this.Es]; 1793 delete this.As[this.Es], this.Ls.delete(o), this.Es++, this.Vs--; 1794 } 1795 t.save(), t.textBaseline = "middle"; 1796 const a = t.measureText(n);
1797 return t.restore(), a.width === 0 && e.length || (this.Ls.set(n, { Fs: a, Ws: this.Bs }), this.As[this.Bs] = n, this.Vs++, this.Bs++), a; 1798 } 1799 }; 1800 var co = class { 1801 constructor(t) { 1802 this.Hs = null, this.M = null, this.Us = "right", this.$s = t; 1803 } 1804 js(t, e, i) { 1805 this.Hs = t, this.M = e, this.Us = i; 1806 } 1807 st(t) { 1808 this.M !== null && this.Hs !== null && this.Hs.st(t, this.M, this.$s, this.Us); 1809 } 1810 }; 1811 var On = class { 1812 constructor(t, e, i) { 1813 this.qs = t, this.$s = new mi(50), this.Ys = e, this.O = i, this.F = -1, this.Xt = new co(this.$s); 1814 } 1815 Tt() { 1816 const t = this.O.Ks(this.Ys); 1817 if (t === null) 1818 return null; 1819 const e = t.Zs(this.Ys) ? t.Gs() : this.Ys.Ft(); 1820 if (e === null) 1821 return null; 1822 const i = t.Xs(e); 1823 if (i === "overlay") 1824 return null; 1825 const r = this.O.Js(); 1826 return r.k !== this.F && (this.F = r.k, this.$s.Os()), this.Xt.js(this.qs.qi(), r, i), this.Xt; 1827 } 1828 }; 1829 var uo = class extends ne { 1830 constructor() { 1831 super(...arguments), this.qt = null; 1832 } 1833 ht(t) { 1834 this.qt = t; 1835 } 1836 Qs(t, e) { 1837 var a; 1838 if (!((a = this.qt) != null && a.It)) 1839 return null; 1840 const { ut: i, ct: r, te: n } = this.qt; 1841 return e >= i - r - 7 && e <= i + r + 7 ? { ie: this.qt, ne: Math.abs(e - i), se: 2, ee: "price-line", te: n } : null; 1842 } 1843 et({ context: t, bitmapSize: e, horizontalPixelRatio: i, verticalPixelRatio: r }) { 1844 if (this.qt === null || this.qt.It === false) 1845 return; 1846 const n = Math.round(this.qt.ut * r); 1847 n < 0 || n > e.height || (t.lineCap = "butt", t.strokeStyle = this.qt.R, t.lineWidth = Math.floor(this.qt.ct * i), Ut(t, this.qt.Zt), Pn(t, n, 0, e.width)); 1848 } 1849 }; 1850 var Fs = class { 1851 constructor(t) { 1852 this.re = { ut: 0, R: "rgba(0, 0, 0, 0)", ct: 1, Zt: 0, It: false }, this.he = new uo(), this.xt = true, this.ae = t, this.le = t.Qt(), this.he.ht(this.re); 1853 } 1854 kt() { 1855 this.xt = true; 1856 } 1857 Tt() { 1858 return this.ae.It() ? (this.xt && (this.oe(), this.xt = false), this.he) : null; 1859 } 1860 }; 1861 var fo = class extends Fs { 1862 constructor(t) { 1863 super(t); 1864 } 1865 oe() { 1866 this.re.It = false; 1867 const t = this.ae.Ft(), e = t._e()._e; 1868 if (e !== 2 && e !== 3) 1869 return; 1870 const i = this.ae.N(); 1871 if (!i.baseLineVisible || !this.ae.It()) 1872 return; 1873 const r = this.ae.Lt(); 1874 r !== null && (this.re.It = true, this.re.ut = t.Nt(r.Wt, r.Wt), this.re.R = i.baseLineColor, this.re.ct = i.baseLineWidth, this.re.Zt = i.baseLineStyle); 1875 } 1876 }; 1877 var mo = class extends ne { 1878 constructor() { 1879 super(...arguments), this.qt = null; 1880 } 1881 ht(t) { 1882 this.qt = t; 1883 } 1884 ue() { 1885 return this.qt; 1886 } 1887 et({ context: t, horizontalPixelRatio: e, verticalPixelRatio: i }) { 1888 const r = this.qt; 1889 if (r === null) 1890 return; 1891 const n = Math.max(1, Math.floor(e)), a = n % 2 / 2, o = Math.round(r.ce.x * e) + a, l = r.ce.y * i; 1892 t.fillStyle = r.de, t.beginPath(); 1893 const h = Math.max(2, 1.5 * r.fe) * e; 1894 t.arc(o, l, h, 0, 2 * Math.PI, false), t.fill(), t.fillStyle = r.pe, t.beginPath(), t.arc(o, l, r.ft * e, 0, 2 * Math.PI, false), t.fill(), t.lineWidth = n, t.strokeStyle = r.ve, t.beginPath(), t.arc(o, l, r.ft * e + n / 2, 0, 2 * Math.PI, false), t.stroke(); 1895 } 1896 }; 1897 var po = [{ me: 0, we: 0.25, Me: 4, ge: 10, be: 0.25, Se: 0, xe: 0.4, Ce: 0.8 }, { me: 0.25, we: 0.525, Me: 10, ge: 14, be: 0, Se: 0, xe: 0.8, Ce: 0 }, { me: 0.525, we: 1, Me: 14, ge: 14, be: 0, Se: 0, xe: 0, Ce: 0 }]; 1898 var go = class { 1899 constructor(t) { 1900 this.Xt = new mo(), this.xt = true, this.ye = true, this.ke = performance.now(), this.Pe = this.ke - 1, this.Te = t; 1901 } 1902 Re() { 1903 this.Pe = this.ke - 1, this.kt(); 1904 } 1905 De() { 1906 if (this.kt(), this.Te.N().lastPriceAnimation === 2) { 1907 const t = performance.now(), e = this.Pe - t; 1908 if (e > 0) 1909 return void (e < 650 && (this.Pe += 2600)); 1910 this.ke = t, this.Pe = t + 2600; 1911 } 1912 } 1913 kt() { 1914 this.xt = true; 1915 } 1916 Ie() { 1917 this.ye = true; 1918 } 1919 It() { 1920 return this.Te.N().lastPriceAnimation !== 0; 1921 } 1922 Ve() { 1923 switch (this.Te.N().lastPriceAnimation) { 1924 case 0: 1925 return false;
1926 case 1: 1927 return true; 1928 case 2: 1929 return performance.now() <= this.Pe; 1930 } 1931 } 1932 Tt() { 1933 return this.xt ? (this.Rt(), this.xt = false, this.ye = false) : this.ye && (this.Be(), this.ye = false), this.Xt; 1934 } 1935 Rt() { 1936 this.Xt.ht(null); 1937 const t = this.Te.Qt().Et(), e = t.Ee(), i = this.Te.Lt(); 1938 if (e === null || i === null) 1939 return; 1940 const r = this.Te.Ae(true); 1941 if (r.Le || !e.ze(r.$n)) 1942 return; 1943 const n = { x: t.jt(r.$n), y: this.Te.Ft().Nt(r.Mt, i.Wt) }, a = r.R, o = this.Te.N().lineWidth, l = this.Oe(this.Ne(), a); 1944 this.Xt.ht({ de: a, fe: o, pe: l.pe, ve: l.ve, ft: l.ft, ce: n }); 1945 } 1946 Be() { 1947 const t = this.Xt.ue(); 1948 if (t !== null) { 1949 const e = this.Oe(this.Ne(), t.de); 1950 t.pe = e.pe, t.ve = e.ve, t.ft = e.ft; 1951 } 1952 } 1953 Ne() { 1954 return this.Ve() ? performance.now() - this.ke : 2599; 1955 } 1956 Fe(t, e, i, r) { 1957 const n = i + (r - i) * e; 1958 return this.Te.Qt().Xi().Y(t, n); 1959 } 1960 Oe(t, e) { 1961 const i = t % 2600 / 2600; 1962 let r; 1963 for (const h of po) 1964 if (i >= h.me && i <= h.we) { 1965 r = h; 1966 break; 1967 } 1968 et(r !== void 0, "Last price animation internal logic error"); 1969 const n = (i - r.me) / (r.we - r.me); 1970 return { pe: this.Fe(e, n, r.be, r.Se), ve: this.Fe(e, n, r.xe, r.Ce), ft: (a = n, o = r.Me, l = r.ge, o + (l - o) * a) }; 1971 var a, o, l; 1972 } 1973 }; 1974 var vo = class extends Fs { 1975 constructor(t) { 1976 super(t); 1977 } 1978 oe() { 1979 const t = this.re; 1980 t.It = false; 1981 const e = this.ae.N(); 1982 if (!e.priceLineVisible || !this.ae.It()) 1983 return; 1984 const i = this.ae.Ae(e.priceLineSource === 0); 1985 i.Le || (t.It = true, t.ut = i.Ei, t.R = this.ae.We(i.R), t.ct = e.priceLineWidth, t.Zt = e.priceLineStyle); 1986 } 1987 }; 1988 var bo = class extends wi { 1989 constructor(t) { 1990 super(), this.Jt = t; 1991 } 1992 Yi(t, e, i) { 1993 t.It = false, e.It = false; 1994 const r = this.Jt; 1995 if (!r.It()) 1996 return;
1997 const n = r.N(), a = n.lastValueVisible, o = r.He() !== "", l = n.seriesLastValueMode === 0, h = r.Ae(false); 1998 if (h.Le) 1999 return; 2000 a && (t.ri = this.Ue(h, a, l), t.It = t.ri.length !== 0), (o || l) && (e.ri = this.$e(h, a, o, l), e.It = e.ri.length > 0); 2001 const c = r.We(h.R), d = this.Jt.Qt().Xi().Z(c); 2002 i.G = d.G, i.Ei = h.Ei, e.Ht = r.Qt().Ut(h.Ei / r.Ft().$t()), t.Ht = c, t.R = d.X, e.R = d.X; 2003 } 2004 $e(t, e, i, r) { 2005 let n = ""; 2006 const a = this.Jt.He(); 2007 return i && a.length !== 0 && (n += `${a} `), e && r && (n += this.Jt.Ft().je() ? t.qe : t.Ye), n.trim(); 2008 } 2009 Ue(t, e, i) { 2010 return e ? i ? this.Jt.Ft().je() ? t.Ye : t.qe : t.ri : ""; 2011 } 2012 }; 2013 function Sr(s, t, e, i) { 2014 const r = Number.isFinite(t), n = Number.isFinite(e); 2015 return r && n ? s(t, e) : r || n ? r ? t : e : i; 2016 } 2017 var ot = class _ot { 2018 constructor(t, e) { 2019 this.Ke = t, this.Ze = e; 2020 } 2021 Ge(t) { 2022 return t !== null && this.Ke === t.Ke && this.Ze === t.Ze; 2023 } 2024 Xe() { 2025 return new _ot(this.Ke, this.Ze); 2026 } 2027 Je() { 2028 return this.Ke; 2029 } 2030 Qe() { 2031 return this.Ze; 2032 } 2033 tr() { 2034 return this.Ze - this.Ke; 2035 } 2036 Gi() { 2037 return this.Ze === this.Ke || Number.isNaN(this.Ze) || Number.isNaN(this.Ke); 2038 } 2039 Ss(t) { 2040 return t === null ? this : new _ot(Sr(Math.min, this.Je(), t.Je(), -1 / 0), Sr(Math.max, this.Qe(), t.Qe(), 1 / 0)); 2041 } 2042 ir(t) { 2043 if (!ve(t) || this.Ze - this.Ke === 0) 2044 return; 2045 const e = 0.5 * (this.Ze + this.Ke); 2046 let i = this.Ze - e, r = this.Ke - e; 2047 i *= t, r *= t, this.Ze = e + i, this.Ke = e + r; 2048 } 2049 nr(t) { 2050 ve(t) && (this.Ze += t, this.Ke += t); 2051 } 2052 sr() { 2053 return { minValue: this.Ke, maxValue: this.Ze }; 2054 } 2055 static er(t) { 2056 return t === null ? null : new _ot(t.minValue, t.maxValue); 2057 } 2058 }; 2059 var pi = class _pi { 2060 constructor(t, e) { 2061 this.rr = t, this.hr = e || null; 2062 } 2063 ar() { 2064 return this.rr; 2065 } 2066 lr() { 2067 return this.hr; 2068 } 2069 sr() { 2070 return { priceRange: this.rr === null ? null : this.rr.sr(), margins: this.hr || void 0 }; 2071 } 2072 static er(t) { 2073 return t === null ? null : new _pi(ot.er(t.priceRange), t.margins); 2074 } 2075 }; 2076 var yo = [2, 4, 8, 16, 32, 64, 128, 256, 512]; 2077 var wo = "Custom series with conflation reducer must have a priceValueBuilder method"; 2078 var xo = class extends Fs { 2079 constructor(t, e) { 2080 super(t), this._r = e; 2081 } 2082 oe() { 2083 const t = this.re; 2084 t.It = false; 2085 const e = this._r.N(); 2086 if (!this.ae.It() || !e.lineVisible) 2087 return; 2088 const i = this._r.ur(); 2089 i !== null && (t.It = true, t.ut = i, t.R = e.color, t.ct = e.lineWidth, t.Zt = e.lineStyle, t.te = this._r.N().id); 2090 } 2091 }; 2092 var ko = class extends wi { 2093 constructor(t, e) { 2094 super(), this.Te = t, this._r = e; 2095 } 2096 Yi(t, e, i) { 2097 t.It = false, e.It = false; 2098 const r = this._r.N(), n = r.axisLabelVisible, a = r.title !== "", o = this.Te; 2099 if (!n || !o.It()) 2100 return; 2101 const l = this._r.ur(); 2102 if (l === null) 2103 return; 2104 a && (e.ri = r.title, e.It = true), e.Ht = o.Qt().Ut(l / o.Ft().$t()), t.ri = this.cr(r.price), t.It = true; 2105 const h = this.Te.Qt().Xi().Z(r.axisLabelColor || r.color); 2106 i.G = h.G; 2107 const c = r.axisLabelTextColor || h.X; 2108 t.R = c, e.R = c, i.Ei = l; 2109 } 2110 cr(t) { 2111 const e = this.Te.Lt(); 2112 return e === null ? "" : this.Te.Ft().Ji(t, e.Wt); 2113 } 2114 }; 2115 var So = class { 2116 constructor(t, e) { 2117 this.Te = t, this.yn = e, this.dr = new xo(t, this), this.qs = new ko(t, this), this.pr = new On(this.qs, t, t.Qt()); 2118 } 2119 vr(t) { 2120 ft(this.yn, t), this.kt(), this.Te.Qt().mr(); 2121 } 2122 N() { 2123 return this.yn; 2124 } 2125 wr() { 2126 return this.dr; 2127 } 2128 Mr() { 2129 return this.pr; 2130 } 2131 gr() { 2132 return this.qs; 2133 } 2134 kt() { 2135 this.dr.kt(), this.qs.kt(); 2136 } 2137 ur() { 2138 const t = this.Te, e = t.Ft();
2139 if (t.Qt().Et().Gi() || e.Gi()) 2140 return null; 2141 const i = t.Lt(); 2142 return i === null ? null : e.Nt(this.yn.price, i.Wt); 2143 } 2144 }; 2145 var Co = class { 2146 constructor() { 2147 this.br = /* @__PURE__ */ new WeakMap(); 2148 } 2149 Sr(t, e, i) { 2150 const r = 1 / e * i; 2151 if (t >= r) 2152 return 1; 2153 const n = r / t, a = Math.pow(2, Math.floor(Math.log2(n))); 2154 return Math.min(a, 512); 2155 } 2156 Cr(t, e, i, r = false, n) { 2157 if (t.length === 0 || e <= 1) 2158 return t; 2159 const a = this.yr(e); 2160 if (a <= 1) 2161 return t; 2162 const o = this.kr(t); 2163 let l = o.Pr.get(a); 2164 return l !== void 0 || (l = this.Tr(t, a, i, r, n, o.Pr), o.Pr.set(a, l)), l; 2165 } 2166 Rr(t, e, i, r, n = false, a) { 2167 if (i < 1 || t.length === 0) 2168 return t; 2169 const o = this.kr(t), l = o.Pr.get(i); 2170 if (!l) 2171 return this.Cr(t, i, r, n, a); 2172 const h = this.Dr(t, e, i, l, n, r, a); 2173 return o.Pr.set(i, h), h; 2174 } 2175 yr(t) { 2176 if (t <= 2) 2177 return 2; 2178 for (const e of yo) 2179 if (t <= e) 2180 return e; 2181 return 512; 2182 } 2183 Ir(t) { 2184 if (t.length === 0) 2185 return 0; 2186 const e = t[0], i = t[t.length - 1]; 2187 return 31 * t.length + 17 * e.$n + 13 * i.$n; 2188 } 2189 Tr(t, e, i, r = false, n, a = /* @__PURE__ */ new Map()) { 2190 if (e === 2) 2191 return this.Vr(t, 2, i, r, n); 2192 const o = e / 2; 2193 let l = a.get(o); 2194 return l || (l = this.Tr(t, o, i, r, n, a), a.set(o, l)), this.Br(l, i, r, n); 2195 } 2196 Vr(t, e, i, r = false, n) { 2197 const a = this.Er(t, e, i, r, n); 2198 return this.Ar(a, r); 2199 } 2200 Br(t, e, i = false, r) { 2201 const n = this.Er(t, 2, e, i, r); 2202 return this.Ar(n, i); 2203 } 2204 Er(t, e, i, r = false, n) { 2205 const a = []; 2206 for (let o = 0; o < t.length; o += e) 2207 if (t.length - o >= e) { 2208 const l = this.Lr(t[o], t[o + 1], i, r, n); 2209 l.zr = false, a.push(l); 2210 } else if (a.length === 0) 2211 a.push(this.Or(t[o], true)); 2212 else { 2213 const l = a[a.length - 1]; 2214 a[a.length - 1] = this.Nr(l, t[o], i, r, n); 2215 } 2216 return a; 2217 } 2218 Fr(t, e) { 2219 return (t != null ? t : 1) + (e != null ? e : 1); 2220 } 2221 Lr(t, e, i, r = false, n) { 2222 if (!r || !i || !n) { 2223 const h = t.Wt[1] > e.Wt[1] ? t.Wt[1] : e.Wt[1], c = t.Wt[2] < e.Wt[2] ? t.Wt[2] : e.Wt[2]; 2224 return { Wr: t.$n, Hr: e.$n, Ur: t.wt, $r: e.wt, jr: t.Wt[0], qr: h, Yr: c, Kr: e.Wt[3], Zr: this.Fr(t.Zr, e.Zr), Gr: void 0, zr: false }; 2225 } 2226 const a = i(this.Xr(t, n), this.Xr(e, n)), o = n(a), l = o.length ? o[o.length - 1] : 0; 2227 return { Wr: t.$n, Hr: e.$n, Ur: t.wt, $r: e.wt, jr: t.Wt[0], qr: Math.max(t.Wt[1], l), Yr: Math.min(t.Wt[2], l), Kr: l, Zr: this.Fr(t.Zr, e.Zr), Gr: a, zr: false }; 2228 } 2229 Nr(t, e, i, r = false, n) { 2230 var f, m; 2231 if (!r || !i || !n) 2232 return { Wr: t.Wr, Hr: e.$n, Ur: t.Ur, $r: e.wt, jr: t.jr, qr: t.qr > e.Wt[1] ? t.qr : e.Wt[1], Yr: t.Yr < e.Wt[2] ? t.Yr : e.Wt[2], Kr: e.Wt[3], Zr: t.Zr + ((f = e.Zr) != null ? f : 1), Gr: t.Gr, zr: false }; 2233 const a = t.Gr, o = this.Xr(e, n), l = a ? { data: a, index: t.Wr, originalTime: t.Ur, time: t.Ur, priceValues: n(a) } : null, h = l ? i(l, o) : o.data, c = l ? n(h) : o.priceValues, d = c.length ? c[c.length - 1] : 0; 2234 return { Wr: t.Wr, Hr: e.$n, Ur: t.Ur, $r: e.wt, jr: t.jr, qr: Math.max(t.qr, d), Yr: Math.min(t.Yr, d), Kr: d, Zr: t.Zr + ((m = e.Zr) != null ? m : 1), Gr: h, zr: false }; 2235 } 2236 Jr(t, e, i, r, n, a, o = false, l) { 2237 const h = e === r ? n : t[e]; 2238 if (i - e == 1) 2239 return this.Or(h, true); 2240 const c = e + 1 === r ? n : t[e + 1]; 2241 let d = this.Lr(h, c, a, o, l); 2242 for (let f = e + 2; f < i; f++) { 2243 const m = f === r ? n : t[f]; 2244 d = this.Nr(d, m, a, o, l); 2245 } 2246 return d; 2247 } 2248 Xr(t, e) { 2249 var r; 2250 const i = (r = t.ue) != null ? r : {};
2251 return { data: t.ue, index: t.$n, originalTime: t.Qr, time: t.wt, priceValues: e(i) }; 2252 } 2253 th(t, e = false) { 2254 const i = e === true, r = !!t.Gr; 2255 return { $n: t.Wr, wt: t.Ur, Qr: t.Ur, Wt: [i ? t.Kr : t.jr, t.qr, t.Yr, t.Kr], Zr: t.Zr, ue: i ? r ? t.Gr : { wt: t.Ur } : void 0 }; 2256 } 2257 Ar(t, e = false) { 2258 return t.map((i) => this.th(i, e)); 2259 } 2260 Dr(t, e, i, r, n = false, a, o) { 2261 if (r.length === 0) 2262 return r; 2263 const l = t.length - 1, h = Math.floor(l / i) * i; 2264 if (Math.min(h + i, t.length) - h < i && t.length > i) { 2265 const c = t.slice(); 2266 return c[c.length - 1] = e, this.Cr(c, i, a, n, o); 2267 } 2268 if (Math.floor((l - 1) / i) === Math.floor(l / i) || r.length === 1) { 2269 const c = Math.min(h + i, t.length), d = c - h; 2270 if (d <= 0) 2271 return r; 2272 const f = d === 1 ? this.Or(h === l ? e : t[h], true) : this.Jr(t, h, c, l, e, a, n, o); 2273 return r[r.length - 1] = this.th(f, n), r; 2274 } 2275 { 2276 const c = t.slice(); 2277 return c[c.length - 1] = e, this.Cr(c, i, a, n, o); 2278 } 2279 } 2280 Or(t, e = false) { 2281 var i; 2282 return { Wr: t.$n, Hr: t.$n, Ur: t.wt, $r: t.wt, jr: t.Wt[0], qr: t.Wt[1], Yr: t.Wt[2], Kr: t.Wt[3], Zr: (i = t.Zr) != null ? i : 1, Gr: t.ue, zr: e }; 2283 } 2284 kr(t) { 2285 const e = this.ih(t), i = this.Ir(t); 2286 return e.nh !== i && (e.Pr.clear(), e.nh = i), e; 2287 } 2288 ih(t) { 2289 let e = this.br.get(t); 2290 return e === void 0 && (e = { nh: this.Ir(t), Pr: /* @__PURE__ */ new Map() }, this.br.set(t, e)), e; 2291 } 2292 }; 2293 var _o = class extends Ln { 2294 constructor(t) { 2295 super(), this.sn = t; 2296 } 2297 Qt() { 2298 return this.sn; 2299 } 2300 }; 2301 var $o = { Bar: (s, t, e, i) => { 2302 var l; 2303 const r = t.upColor, n = t.downColor, a = k(s(e, i)), o = Ot(a.Wt[0]) <= Ot(a.Wt[3]); 2304 return { sh: (l = a.R) != null ? l : o ? r : n }; 2305 }, Candlestick: (s, t, e, i) => { 2306 var f, m, p; 2307 const r = t.upColor, n = t.downColor, a = t.borderUpColor, o = t.borderDownColor, l = t.wickUpColor, h = t.wickDownColor, c = k(s(e, i)), d = Ot(c.Wt[0]) <= Ot(c.Wt[3]); 2308 return { sh: (f = c.R) != null ? f : d ? r : n, eh: (m = c.Ht) != null ? m : d ? a : o, rh: (p = c.hh) != null ? p : d ? l : h }; 2309 }, Custom: (s, t, e, i) => { 2310 var r; 2311 return { sh: (r = k(s(e, i)).R) != null ? r : t.color }; 2312 }, Area: (s, t, e, i) => { 2313 var n, a, o, l; 2314 const r = k(s(e, i)); 2315 return { sh: (n = r.vt) != null ? n : t.lineColor, vt: (a = r.vt) != null ? a : t.lineColor, ah: (o = r.ah) != null ? o : t.topColor, oh: (l = r.oh) != null ? l : t.bottomColor }; 2316 }, Baseline: (s, t, e, i) => { 2317 var n, a, o, l, h, c; 2318 const r = k(s(e, i)); 2319 return { sh: r.Wt[3] >= t.baseValue.price ? t.topLineColor : t.bottomLineColor, _h: (n = r._h) != null ? n : t.topLineColor, uh: (a = r.uh) != null ? a : t.bottomLineColor, dh: (o = r.dh) != null ? o : t.topFillColor1, fh: (l = r.fh) != null ? l : t.topFillColor2, ph: (h = r.ph) != null ? h : t.bottomFillColor1, mh: (c = r.mh) != null ? c : t.bottomFillColor2 }; 2320 }, Line: (s, t, e, i) => { 2321 var n, a; 2322 const r = k(s(e, i)); 2323 return { sh: (n = r.R) != null ? n : t.color, vt: (a = r.R) != null ? a : t.color }; 2324 }, Histogram: (s, t, e, i) => { 2325 var r; 2326 return { sh: (r = k(s(e, i)).R) != null ? r : t.color }; 2327 } }; 2328 var Do = class { 2329 constructor(t) { 2330 this.wh = (e, i) => i !== void 0 ? i.Wt : this.Te.Un().Mh(e), this.Te = t, this.gh = $o[t.bh()]; 2331 } 2332 Sh(t, e) { 2333 return this.gh(this.wh, this.Te.N(), t, e); 2334 } 2335 }; 2336 function qn(s, t, e, i, r = 0, n = t.length) { 2337 let a = n - r; 2338 for (; 0 < a; ) { 2339 const o = a >> 1, l = r + o; 2340 i(t[l], e) === s ? (r = l + 1, a -= o + 1) : a = o; 2341 } 2342 return r; 2343 } 2344 var ie = qn.bind(null, true); 2345 var Ps = qn.bind(null, false); 2346 var Cr; 2347 (function(s) { 2348 s[s.NearestLeft = -1] = "NearestLeft", s[s.None = 0] = "None", s[s.NearestRight = 1] = "NearestRight"; 2349 })(Cr || (Cr = {})); 2350 var Nt = 30; 2351 var Mo = class { 2352 constructor() { 2353 this.xh = [], this.Ch = /* @__PURE__ */ new Map(), this.yh = /* @__PURE__ */ new Map(), this.kh = []; 2354 } 2355 Ph() { 2356 return this.Th() > 0 ? this.xh[this.xh.length - 1] : null; 2357 } 2358 Rh() { 2359 return this.Th() > 0 ? this.Dh(0) : null; 2360 } 2361 Qn() { 2362 return this.Th() > 0 ? this.Dh(this.xh.length - 1) : null; 2363 } 2364 Th() { 2365 return this.xh.length; 2366 } 2367 Gi() { 2368 return this.Th() === 0; 2369 } 2370 ze(t) { 2371 return this.Ih(t, 0) !== null; 2372 } 2373 Mh(t) { 2374 return this.Hn(t); 2375 } 2376 Hn(t, e = 0) { 2377 const i = this.Ih(t, e); 2378 return i === null ? null : G(M({}, this.Vh(i)), { $n: this.Dh(i) }); 2379 } 2380 Bh() { 2381 return this.xh; 2382 } 2383 Eh(t, e, i) { 2384 if (this.Gi()) 2385 return null; 2386 let r = null; 2387 for (const n of i) 2388 r = Ge(r, this.Ah(t, e, n)); 2389 return r; 2390 } 2391 ht(t) { 2392 this.yh.clear(), this.Ch.clear(), this.xh = t, this.kh = t.map((e) => e.$n); 2393 } 2394 Lh() { 2395 return this.kh; 2396 } 2397 Dh(t) { 2398 return this.xh[t].$n; 2399 } 2400 Vh(t) { 2401 return this.xh[t]; 2402 } 2403 Ih(t, e) { 2404 const i = this.zh(t); 2405 if (i === null && e !== 0) 2406 switch (e) { 2407 case -1: 2408 return this.Oh(t); 2409 case 1: 2410 return this.Nh(t); 2411 default: 2412 throw new TypeError("Unknown search mode"); 2413 } 2414 return i; 2415 } 2416 Oh(t) { 2417 let e = this.Fh(t); 2418 return e > 0 && (e -= 1), e !== this.xh.length && this.Dh(e) < t ? e : null; 2419 } 2420 Nh(t) { 2421 const e = this.Wh(t); 2422 return e !== this.xh.length && t < this.Dh(e) ? e : null; 2423 } 2424 zh(t) { 2425 const e = this.Fh(t); 2426 return e === this.xh.length || t < this.xh[e].$n ? null : e; 2427 } 2428 Fh(t) { 2429 return ie(this.xh, t, (e, i) => e.$n < i); 2430 } 2431 Wh(t) { 2432 return Ps(this.xh, t, (e, i) => e.$n > i); 2433 } 2434 Hh(t, e, i) { 2435 let r = null; 2436 for (let n = t; n < e; n++) { 2437 const a = this.xh[n].Wt[i]; 2438 Number.isNaN(a) || (r === null ? r = { Uh: a, $h: a } : (a < r.Uh && (r.Uh = a), a > r.$h && (r.$h = a))); 2439 } 2440 return r; 2441 } 2442 Ah(t, e, i) { 2443 if (this.Gi()) 2444 return null; 2445 let r = null; 2446 const n = k(this.Rh()), a = k(this.Qn()), o = Math.max(t, n), l = Math.min(e, a), h = Math.ceil(o / Nt) * Nt, c = Math.max(h, Math.floor(l / Nt) * Nt); 2447 { 2448 const f = this.Fh(o), m = this.Wh(Math.min(l, h, e)); 2449 r = Ge(r, this.Hh(f, m, i)); 2450 } 2451 let d = this.Ch.get(i); 2452 d === void 0 && (d = /* @__PURE__ */ new Map(), this.Ch.set(i, d)); 2453 for (let f = Math.max(h + 1, o); f < c; f += Nt) { 2454 const m = Math.floor(f / Nt); 2455 let p = d.get(m); 2456 if (p === void 0) { 2457 const v = this.Fh(m * Nt), b = this.Wh((m + 1) * Nt - 1); 2458 p = this.Hh(v, b, i), d.set(m, p); 2459 } 2460 r = Ge(r, p); 2461 } 2462 { 2463 const f = this.Fh(c), m = this.Wh(l); 2464 r = Ge(r, this.Hh(f, m, i)); 2465 } 2466 return r; 2467 } 2468 }; 2469 function Ge(s, t) { 2470 return s === null ? t : t === null ? s : { Uh: Math.min(s.Uh, t.Uh), $h: Math.max(s.$h, t.$h) }; 2471 } 2472 function Ni() { 2473 return new Mo(); 2474 } 2475 var gi = { setLineStyle: Ut }; 2476 var Eo = class { 2477 constructor(t) { 2478 this.jh = t; 2479 } 2480 st(t, e, i) { 2481 this.jh.draw(t, gi); 2482 } 2483 qh(t, e, i) { 2484 var r, n;
2485 (n = (r = this.jh).drawBackground) == null || n.call(r, t, gi); 2486 } 2487 }; 2488 var zo = class { 2489 constructor(t) { 2490 this.Ls = null, this.Yh = t; 2491 } 2492 Tt() { 2493 var i; 2494 const t = this.Yh.renderer(); 2495 if (t === null) 2496 return null; 2497 if (((i = this.Ls) == null ? void 0 : i.Kh) === t) 2498 return this.Ls.Zh; 2499 const e = new Eo(t); 2500 return this.Ls = { Kh: t, Zh: e }, e; 2501 } 2502 Gh() { 2503 var t, e, i; 2504 return (i = (e = (t = this.Yh).zOrder) == null ? void 0 : e.call(t)) != null ? i : "normal"; 2505 } 2506 }; 2507 var Un = class { 2508 constructor(t) { 2509 this.Xh = null, this.Jh = t; 2510 } 2511 Qh() { 2512 return this.Jh; 2513 } 2514 Nn() { 2515 var t, e; 2516 (e = (t = this.Jh).updateAllViews) == null || e.call(t); 2517 } 2518 jn() { 2519 var i, r, n, a; 2520 const t = (n = (r = (i = this.Jh).paneViews) == null ? void 0 : r.call(i)) != null ? n : []; 2521 if (((a = this.Xh) == null ? void 0 : a.Kh) === t) 2522 return this.Xh.Zh; 2523 const e = t.map((o) => new zo(o)); 2524 return this.Xh = { Kh: t, Zh: e }, e; 2525 } 2526 Qs(t, e) { 2527 var i, r, n; 2528 return (n = (r = (i = this.Jh).hitTest) == null ? void 0 : r.call(i, t, e)) != null ? n : null; 2529 } 2530 }; 2531 var Fo = class extends Un { 2532 cn() { 2533 return []; 2534 } 2535 }; 2536 var Po = class { 2537 constructor(t) { 2538 this.jh = t; 2539 } 2540 st(t, e, i) { 2541 this.jh.draw(t, gi); 2542 } 2543 qh(t, e, i) { 2544 var r, n; 2545 (n = (r = this.jh).drawBackground) == null || n.call(r, t, gi); 2546 } 2547 }; 2548 var _r = class { 2549 constructor(t) { 2550 this.Ls = null, this.Yh = t; 2551 } 2552 Tt() { 2553 var i; 2554 const t = this.Yh.renderer(); 2555 if (t === null) 2556 return null; 2557 if (((i = this.Ls) == null ? void 0 : i.Kh) === t) 2558 return this.Ls.Zh; 2559 const e = new Po(t); 2560 return this.Ls = { Kh: t, Zh: e }, e; 2561 } 2562 Gh() { 2563 var t, e, i; 2564 return (i = (e = (t = this.Yh).zOrder) == null ? void 0 : e.call(t)) != null ? i : "normal"; 2565 } 2566 }; 2567 function Vn(s) { 2568 var t, e, i, r, n; 2569 return { ri: s.text(), Ei: s.coordinate(), Vi: (t = s.fixedCoordinate) == null ? void 0 : t.call(s), R: s.textColor(), G: s.backColor(), It: (i = (e = s.visible) == null ? void 0 : e.call(s)) != null ? i : true, pi: (n = (r = s.tickVisible) == null ? void 0 : r.call(s)) != null ? n : true }; 2570 } 2571 var Ao = class { 2572 constructor(t, e) { 2573 this.Xt = new Rn(), this.ta = t, this.ia = e; 2574 } 2575 Tt() { 2576 return this.Xt.ht(M({ nn: this.ia.nn() }, Vn(this.ta))), this.Xt; 2577 } 2578 }; 2579 var To = class extends wi { 2580 constructor(t, e) { 2581 super(), this.ta = t, this.Ki = e; 2582 } 2583 Yi(t, e, i) { 2584 const r = Vn(this.ta); 2585 i.G = r.G, t.R = r.R; 2586 const n = 2 / 12 * this.Ki.k(); 2587 i.Ti = n, i.Ri = n, i.Ei = r.Ei, i.Vi = r.Vi, t.ri = r.ri, t.It = r.It, t.pi = r.pi; 2588 } 2589 }; 2590 var Io = class extends Un { 2591 constructor(t, e) { 2592 super(t), this.na = null, this.sa = null, this.ea = null, this.ra = null, this.Te = e; 2593 } 2594 dn() { 2595 var r, n, a, o; 2596 const t = (a = (n = (r = this.Jh).timeAxisViews) == null ? void 0 : n.call(r)) != null ? a : []; 2597 if (((o = this.na) == null ? void 0 : o.Kh) === t) 2598 return this.na.Zh; 2599 const e = this.Te.Qt().Et(), i = t.map((l) => new Ao(l, e)); 2600 return this.na = { Kh: t, Zh: i }, i; 2601 } 2602 qn() { 2603 var r, n, a, o; 2604 const t = (a = (n = (r = this.Jh).priceAxisViews) == null ? void 0 : n.call(r)) != null ? a : []; 2605 if (((o = this.sa) == null ? void 0 : o.Kh) === t) 2606 return this.sa.Zh; 2607 const e = this.Te.Ft(), i = t.map((l) => new To(l, e)); 2608 return this.sa = { Kh: t, Zh: i }, i; 2609 } 2610 ha() { 2611 var i, r, n, a; 2612 const t = (n = (r = (i = this.Jh).priceAxisPaneViews) == null ? void 0 : r.call(i)) != null ? n : []; 2613 if (((a = this.ea) == null ? void 0 : a.Kh) === t) 2614 return this.ea.Zh; 2615 const e = t.map((o) => new _r(o)); 2616 return this.ea = { Kh: t, Zh: e }, e; 2617 } 2618 aa() { 2619 var i, r, n, a; 2620 const t = (n = (r = (i = this.Jh).timeAxisPaneViews) == null ? void 0 : r.call(i)) != null ? n : []; 2621 if (((a = this.ra) == null ? void 0 : a.Kh) === t) 2622 return this.ra.Zh; 2623 const e = t.map((o) => new _r(o)); 2624 return this.ra = { Kh: t, Zh: e }, e; 2625 } 2626 la(t, e) { 2627 var i, r, n; 2628 return (n = (r = (i = this.Jh).autoscaleInfo) == null ? void 0 : r.call(i, t, e)) != null ? n : null; 2629 } 2630 }; 2631 function Bi(s, t, e, i) {
2632 s.forEach((r) => { 2633 t(r).forEach((n) => { 2634 n.Gh() === e && i.push(n); 2635 }); 2636 }); 2637 } 2638 function Oi(s) { 2639 return s.jn(); 2640 } 2641 function Ro(s) { 2642 return s.ha(); 2643 } 2644 function Lo(s) { 2645 return s.aa(); 2646 } 2647 var No = ["Area", "Line", "Baseline"]; 2648 var Si = class extends _o { 2649 constructor(t, e, i, r, n) { 2650 super(t), this.qt = Ni(), this.dr = new vo(this), this.oa = [], this._a = new fo(this), this.ua = null, this.ca = null, this.da = null, this.fa = [], this.pa = new Co(), this.va = /* @__PURE__ */ new Map(), this.ma = null, this.yn = i, this.wa = e; 2651 const a = new bo(this); 2652 if (this.mn = [a], this.pr = new On(a, this, t), No.includes(this.wa) && (this.ua = new go(this)), this.Ma(), this.Yh = r(this, this.Qt(), n), this.wa === "Custom") { 2653 const o = this.Yh; 2654 o.ga && this.ba(o.ga); 2655 } 2656 } 2657 m() { 2658 this.da !== null && clearTimeout(this.da); 2659 } 2660 We(t) { 2661 return this.yn.priceLineColor || t; 2662 } 2663 Ae(t) { 2664 const e = { Le: true }, i = this.Ft(); 2665 if (this.Qt().Et().Gi() || i.Gi() || this.qt.Gi()) 2666 return e; 2667 const r = this.Qt().Et().Ee(), n = this.Lt(); 2668 if (r === null || n === null) 2669 return e; 2670 let a, o; 2671 if (t) { 2672 const d = this.qt.Ph(); 2673 if (d === null) 2674 return e; 2675 a = d, o = d.$n; 2676 } else { 2677 const d = this.qt.Hn(r.bi(), -1); 2678 if (d === null || (a = this.qt.Mh(d.$n), a === null)) 2679 return e; 2680 o = d.$n; 2681 } 2682 const l = a.Wt[3], h = this.Sa().Sh(o, { Wt: a }), c = i.Nt(l, n.Wt); 2683 return { Le: false, Mt: l, ri: i.Ji(l, n.Wt), qe: i.xa(l), Ye: i.Ca(l, n.Wt), R: h.sh, Ei: c, $n: o }; 2684 } 2685 Sa() { 2686 return this.ca !== null || (this.ca = new Do(this)), this.ca; 2687 } 2688 N() { 2689 return this.yn; 2690 } 2691 vr(t) { 2692 const e = this.Qt(), { priceScaleId: i, visible: r, priceFormat: n } = t; 2693 i !== void 0 && i !== this.yn.priceScaleId && e.ya(this, i), r !== void 0 && r !== this.yn.visible && e.ka(); 2694 const a = t.conflationThresholdFactor !== void 0; 2695 ft(this.yn, t), a && (this.va.clear(), this.Qt().mr()), n !== void 0 && (this.Ma(), e.Pa()), e.Ta(this), e.Ra(), this.Yh.kt("options"); 2696 } 2697 ht(t, e) { 2698 this.qt.ht(t), this.va.clear(); 2699 const i = this.Qt().Et().N(); 2700 i.enableConflation && i.precomputeConflationOnInit && this.Da(i.precomputeConflationPriority), this.Yh.kt("data"), this.ua !== null && (e && e.Ia ? this.ua.De() : t.length === 0 && this.ua.Re()); 2701 const r = this.Qt().Ks(this); 2702 this.Qt().Va(r), this.Qt().Ta(this), this.Qt().Ra(), this.Qt().mr(); 2703 } 2704 Ba(t) { 2705 const e = new So(this, t); 2706 return this.oa.push(e), this.Qt().Ta(this), e; 2707 } 2708 Ea(t) { 2709 const e = this.oa.indexOf(t); 2710 e !== -1 && this.oa.splice(e, 1), this.Qt().Ta(this); 2711 } 2712 Aa() { 2713 return this.oa; 2714 } 2715 bh() { 2716 return this.wa; 2717 } 2718 Lt() { 2719 const t = this.La(); 2720 return t === null ? null : { Wt: t.Wt[3], za: t.wt }; 2721 } 2722 La() { 2723 const t = this.Qt().Et().Ee(); 2724 if (t === null) 2725 return null; 2726 const e = t.Oa(); 2727 return this.qt.Hn(e, 1); 2728 } 2729 Un() { 2730 return this.qt; 2731 } 2732 ba(t) { 2733 this.ma = t, this.va.clear(); 2734 } 2735 Na() { 2736 return !!this.Qt().Et().N().enableConflation && this.Fa() > 1; 2737 } 2738 Rr(t) { 2739 if (!this.Na()) 2740 return; 2741 const e = this.Fa(); 2742 if (!this.va.has(e)) 2743 return; 2744 const i = this.wa === "Custom", r = i && this.ma || void 0, n = i && this.Yh.Wa ? (l) => { 2745 const h = l, c = this.Yh.Wa(h); 2746 return Array.isArray(c) ? c : [typeof c == "number" ? c : 0]; 2747 } : void 0, a = this.pa.Rr(this.qt.Bh(), t, e, r, i, n), o = Ni(); 2748 o.ht(a), this.va.set(e, o); 2749 } 2750 Ha() { 2751 var r; 2752 const t = this.Qt().Et().N().enableConflation; 2753 if (this.wa === "Custom" && this.ma === null) 2754 return this.qt; 2755 if (!t) 2756 return this.qt; 2757 const e = this.Fa(), i = this.va.get(e); 2758 return i || (this.Ua(e), (r = this.va.get(e)) != null ? r : this.qt); 2759 } 2760 $a(t) { 2761 const e = this.qt.Mh(t); 2762 return e === null ? null : this.wa === "Bar" || this.wa === "Candlestick" || this.wa === "Custom" ? { jr: e.Wt[0], qr: e.Wt[1], Yr: e.Wt[2], Kr: e.Wt[3] } : e.Wt[3]; 2763 } 2764 ja(t) { 2765 const e = []; 2766 Bi(this.fa, Oi, "top", e); 2767 const i = this.ua; 2768 return i !== null && i.It() && (this.da === null && i.Ve() && (this.da = setTimeout(() => { 2769 this.da = null, this.Qt().qa(); 2770 }, 0)), i.Ie(), e.unshift(i)), e; 2771 } 2772 jn() { 2773 const t = []; 2774 this.Ya() || t.push(this._a), t.push(this.Yh, this.dr); 2775 const e = this.oa.map((i) => i.wr()); 2776 return t.push(...e), Bi(this.fa, Oi, "normal", t), t; 2777 } 2778 Ka() { 2779 return this.Za(Oi, "bottom"); 2780 } 2781 Ga(t) { 2782 return this.Za(Ro, t); 2783 }
2784 Xa(t) { 2785 return this.Za(Lo, t); 2786 } 2787 Ja(t, e) { 2788 return this.fa.map((i) => i.Qs(t, e)).filter((i) => i !== null); 2789 } 2790 cn() { 2791 return [this.pr, ...this.oa.map((t) => t.Mr())]; 2792 } 2793 qn(t, e) { 2794 if (e !== this.hn && !this.Ya()) 2795 return []; 2796 const i = [...this.mn]; 2797 for (const r of this.oa) 2798 i.push(r.gr()); 2799 return this.fa.forEach((r) => { 2800 i.push(...r.qn()); 2801 }), i; 2802 } 2803 dn() { 2804 const t = []; 2805 return this.fa.forEach((e) => { 2806 t.push(...e.dn()); 2807 }), t; 2808 } 2809 la(t, e) { 2810 if (this.yn.autoscaleInfoProvider !== void 0) { 2811 const i = this.yn.autoscaleInfoProvider(() => { 2812 const r = this.Qa(t, e); 2813 return r === null ? null : r.sr(); 2814 }); 2815 return pi.er(i); 2816 } 2817 return this.Qa(t, e); 2818 } 2819 Kh() { 2820 var e; 2821 const t = this.yn.priceFormat; 2822 return (e = t.base) != null ? e : 1 / t.minMove; 2823 } 2824 tl() { 2825 return this.il; 2826 } 2827 Nn() { 2828 var t; 2829 this.Yh.kt(); 2830 for (const e of this.mn) 2831 e.kt(); 2832 for (const e of this.oa) 2833 e.kt(); 2834 this.dr.kt(), this._a.kt(), (t = this.ua) == null || t.kt(), this.fa.forEach((e) => e.Nn()); 2835 }
2836 Ft() { 2837 return k(super.Ft()); 2838 } 2839 At(t) { 2840 if (!((this.wa === "Line" || this.wa === "Area" || this.wa === "Baseline") && this.yn.crosshairMarkerVisible)) 2841 return null; 2842 const e = this.qt.Mh(t); 2843 return e === null ? null : { Mt: e.Wt[3], ft: this.nl(), Ht: this.sl(), Ot: this.el(), zt: this.rl(t) }; 2844 } 2845 He() { 2846 return this.yn.title; 2847 } 2848 It() { 2849 return this.yn.visible; 2850 } 2851 hl(t) { 2852 this.fa.push(new Io(t, this)); 2853 } 2854 al(t) { 2855 this.fa = this.fa.filter((e) => e.Qh() !== t); 2856 } 2857 ll() { 2858 if (this.wa === "Custom") 2859 return (t) => this.Yh.Wa(t); 2860 } 2861 ol() { 2862 if (this.wa === "Custom") 2863 return (t) => this.Yh._l(t); 2864 } 2865 ul() { 2866 return this.qt.Lh(); 2867 } 2868 Ya() { 2869 return !xi(this.Ft().cl()); 2870 } 2871 Qa(t, e) { 2872 if (!Le(t) || !Le(e) || this.qt.Gi()) 2873 return null; 2874 const i = this.wa === "Line" || this.wa === "Area" || this.wa === "Baseline" || this.wa === "Histogram" ? [3] : [2, 1], r = this.qt.Eh(t, e, i); 2875 let n = r !== null ? new ot(r.Uh, r.$h) : null, a = null; 2876 if (this.bh() === "Histogram") { 2877 const o = this.yn.base, l = new ot(o, o); 2878 n = n !== null ? n.Ss(l) : l; 2879 } 2880 return this.fa.forEach((o) => { 2881 const l = o.la(t, e); 2882 if (l != null && l.priceRange) { 2883 const h = new ot(l.priceRange.minValue, l.priceRange.maxValue); 2884 n = n !== null ? n.Ss(h) : h; 2885 } 2886 l != null && l.margins && (a = l.margins); 2887 }), new pi(n, a); 2888 } 2889 nl() { 2890 switch (this.wa) { 2891 case "Line": 2892 case "Area": 2893 case "Baseline": 2894 return this.yn.crosshairMarkerRadius; 2895 } 2896 return 0; 2897 } 2898 sl() { 2899 switch (this.wa) { 2900 case "Line": 2901 case "Area": 2902 case "Baseline": { 2903 const t = this.yn.crosshairMarkerBorderColor; 2904 if (t.length !== 0) 2905 return t; 2906 } 2907 } 2908 return null; 2909 } 2910 el() { 2911 switch (this.wa) { 2912 case "Line": 2913 case "Area": 2914 case "Baseline": 2915 return this.yn.crosshairMarkerBorderWidth; 2916 } 2917 return 0; 2918 } 2919 rl(t) { 2920 switch (this.wa) { 2921 case "Line": 2922 case "Area": 2923 case "Baseline": { 2924 const e = this.yn.crosshairMarkerBackgroundColor; 2925 if (e.length !== 0) 2926 return e; 2927 } 2928 } 2929 return this.Sa().Sh(t).sh; 2930 } 2931 Ma() { 2932 var t; 2933 switch (this.yn.priceFormat.type) { 2934 case "custom": { 2935 const e = this.yn.priceFormat.formatter; 2936 this.il = { format: e, formatTickmarks: (t = this.yn.priceFormat.tickmarksFormatter) != null ? t : (i) => i.map(e) }; 2937 break; 2938 } 2939 case "volume": 2940 this.il = new lo(this.yn.priceFormat.precision); 2941 break; 2942 case "percent": 2943 this.il = new Bn(this.yn.priceFormat.precision); 2944 break; 2945 default: { 2946 const e = Math.pow(10, this.yn.priceFormat.precision); 2947 this.il = new ki(e, this.yn.priceFormat.minMove * e); 2948 } 2949 } 2950 this.hn !== null && this.hn.dl(); 2951 } 2952 Za(t, e) { 2953 const i = []; 2954 return Bi(this.fa, t, e, i), i; 2955 } 2956 Fa() { 2957 const { fl: t, pl: e, vl: i } = this.ml(); 2958 return this.pa.Sr(t, e, i); 2959 } 2960 ml() { 2961 var n, a; 2962 const t = this.Qt().Et(), e = t.fl(), i = window.devicePixelRatio || 1, r = t.N().conflationThresholdFactor; 2963 return { fl: e, pl: i, vl: (a = (n = this.yn.conflationThresholdFactor) != null ? n : r) != null ? a : 1 }; 2964 } 2965 wl(t) { 2966 const e = this.qt.Bh(); 2967 let i; 2968 if (this.wa === "Custom" && this.ma !== null) { 2969 const n = this.ll(); 2970 if (!n) 2971 throw new Error(wo); 2972 i = this.pa.Cr(e, t, this.ma, true, (a) => n(a)); 2973 } else 2974 i = this.pa.Cr(e, t); 2975 const r = Ni(); 2976 return r.ht(i), r; 2977 } 2978 Ua(t) { 2979 const e = this.wl(t); 2980 this.va.set(t, e); 2981 } 2982 Da(t) { 2983 var i; 2984 if (this.wa === "Custom" && (this.ma === null || !this.ll())) 2985 return; 2986 this.va.clear(); 2987 const e = this.Qt().Et().Ml(); 2988 for (const r of e) { 2989 const n = () => { 2990 this.gl(r); 2991 }, a = typeof window == "object" && window || typeof self == "object" && self; 2992 (i = a == null ? void 0 : a.Sl) != null && i.bl ? a.Sl.bl(() => { 2993 n(); 2994 }, { se: t }) : Promise.resolve().then(() => n()); 2995 } 2996 } 2997 gl(t) { 2998 if (this.va.has(t) || this.qt.Bh().length === 0) 2999 return; 3000 const e = this.wl(t); 3001 this.va.set(t, e); 3002 } 3003 }; 3004 var Bo = [3]; 3005 var Oo = [0, 1, 2, 3]; 3006 var qo = class { 3007 constructor(t) { 3008 this.yn = t; 3009 } 3010 xl(t, e, i) { 3011 let r = t; 3012 if (this.yn.mode === 0) 3013 return r; 3014 const n = i.Pn(), a = n.Lt(); 3015 if (a === null) 3016 return r; 3017 const o = n.Nt(t, a), l = i.Cl().filter((c) => c instanceof Si).reduce((c, d) => { 3018 if (i.Zs(d) || !d.It()) 3019 return c; 3020 const f = d.Ft(), m = d.Un(); 3021 if (f.Gi() || !m.ze(e)) 3022 return c; 3023 const p = m.Mh(e); 3024 if (p === null) 3025 return c;
3026 const v = Ot(d.Lt()), b = this.yn.mode === 3 ? Oo : Bo; 3027 return c.concat(b.map((y) => f.Nt(p.Wt[y], v.Wt))); 3028 }, []); 3029 if (l.length === 0) 3030 return r; 3031 l.sort((c, d) => Math.abs(c - o) - Math.abs(d - o)); 3032 const h = l[0]; 3033 return r = n.Tn(h, a), r; 3034 } 3035 }; 3036 function fe(s, t, e) { 3037 return Math.min(Math.max(s, t), e); 3038 } 3039 function Xe(s, t, e) { 3040 return t - s <= e; 3041 } 3042 var Uo = class extends ne { 3043 constructor() { 3044 super(...arguments), this.qt = null; 3045 } 3046 ht(t) { 3047 this.qt = t; 3048 } 3049 et({ context: t, bitmapSize: e, horizontalPixelRatio: i, verticalPixelRatio: r }) { 3050 if (this.qt === null) 3051 return; 3052 const n = Math.max(1, Math.floor(i)); 3053 t.lineWidth = n, (function(a, o) { 3054 a.save(), a.lineWidth % 2 && a.translate(0.5, 0.5), o(), a.restore(); 3055 })(t, () => { 3056 const a = k(this.qt); 3057 if (a.yl) { 3058 t.strokeStyle = a.kl, Ut(t, a.Pl), t.beginPath(); 3059 for (const o of a.Tl) { 3060 const l = Math.round(o.Rl * i); 3061 t.moveTo(l, -n), t.lineTo(l, e.height + n); 3062 } 3063 t.stroke(); 3064 } 3065 if (a.Dl) { 3066 t.strokeStyle = a.Il, Ut(t, a.Vl), t.beginPath(); 3067 for (const o of a.Bl) { 3068 const l = Math.round(o.Rl * r); 3069 t.moveTo(-n, l), t.lineTo(e.width + n, l); 3070 } 3071 t.stroke(); 3072 } 3073 }); 3074 } 3075 }; 3076 var Vo = class { 3077 constructor(t) { 3078 this.Xt = new Uo(), this.xt = true, this.yt = t; 3079 } 3080 kt() { 3081 this.xt = true; 3082 } 3083 Tt() { 3084 if (this.xt) { 3085 const t = this.yt.Qt().N().grid, e = { Dl: t.horzLines.visible, yl: t.vertLines.visible, Il: t.horzLines.color, kl: t.vertLines.color, Vl: t.horzLines.style, Pl: t.vertLines.style, Bl: this.yt.Pn().El(), Tl: (this.yt.Qt().Et().El() || []).map((i) => ({ Rl: i.coord })) }; 3086 this.Xt.ht(e), this.xt = false; 3087 } 3088 return this.Xt; 3089 } 3090 }; 3091 var jo = class { 3092 constructor(t) { 3093 this.Yh = new Vo(t); 3094 } 3095 wr() { 3096 return this.Yh; 3097 } 3098 }; 3099 var qi = { Al: 4, Ll: 1e-4 }; 3100 function de(s, t) { 3101 const e = 100 * (s - t) / t; 3102 return t < 0 ? -e : e; 3103 } 3104 function Ho(s, t) { 3105 const e = de(s.Je(), t), i = de(s.Qe(), t); 3106 return new ot(e, i); 3107 } 3108 function Fe(s, t) { 3109 const e = 100 * (s - t) / t + 100; 3110 return t < 0 ? -e : e; 3111 } 3112 function Wo(s, t) { 3113 const e = Fe(s.Je(), t), i = Fe(s.Qe(), t); 3114 return new ot(e, i); 3115 } 3116 function vi(s, t) { 3117 const e = Math.abs(s); 3118 if (e < 1e-15) 3119 return 0; 3120 const i = Math.log10(e + t.Ll) + t.Al; 3121 return s < 0 ? -i : i; 3122 } 3123 function Pe(s, t) { 3124 const e = Math.abs(s); 3125 if (e < 1e-15) 3126 return 0; 3127 const i = Math.pow(10, e - t.Al) - t.Ll; 3128 return s < 0 ? -i : i; 3129 } 3130 function De(s, t) { 3131 if (s === null) 3132 return null; 3133 const e = vi(s.Je(), t), i = vi(s.Qe(), t); 3134 return new ot(e, i); 3135 } 3136 function ue(s, t) { 3137 if (s === null) 3138 return null; 3139 const e = Pe(s.Je(), t), i = Pe(s.Qe(), t); 3140 return new ot(e, i); 3141 } 3142 function Ui(s) { 3143 if (s === null) 3144 return qi; 3145 const t = Math.abs(s.Qe() - s.Je()); 3146 if (t >= 1 || t < 1e-15) 3147 return qi; 3148 const e = Math.ceil(Math.abs(Math.log10(t))), i = qi.Al + e; 3149 return { Al: i, Ll: 1 / Math.pow(10, i) }; 3150 } 3151 var Vi = class { 3152 constructor(t, e) { 3153 if (this.zl = t, this.Ol = e, (function(i) { 3154 if (i < 0) 3155 return false; 3156 if (i > 1e18) 3157 return true; 3158 for (let r = i; r > 1; r /= 10) 3159 if (r % 10 != 0) 3160 return false; 3161 return true; 3162 })(this.zl)) 3163 this.Nl = [2, 2.5, 2]; 3164 else { 3165 this.Nl = []; 3166 for (let i = this.zl; i !== 1; ) { 3167 if (i % 2 == 0) 3168 this.Nl.push(2), i /= 2; 3169 else { 3170 if (i % 5 != 0) 3171 throw new Error("unexpected base"); 3172 this.Nl.push(2, 2.5), i /= 5; 3173 } 3174 if (this.Nl.length > 100) 3175 throw new Error("something wrong with base"); 3176 } 3177 } 3178 } 3179 Fl(t, e, i) { 3180 const r = this.zl === 0 ? 0 : 1 / this.zl; 3181 let n = Math.pow(10, Math.max(0, Math.ceil(Math.log10(t - e)))), a = 0, o = this.Ol[0]; 3182 for (; ; ) { 3183 const d = Xe(n, r, 1e-14) && n > r + 1e-14, f = Xe(n, i * o, 1e-14), m = Xe(n, 1, 1e-14); 3184 if (!(d && f && m)) 3185 break; 3186 n /= o, o = this.Ol[++a % this.Ol.length]; 3187 } 3188 if (n <= r + 1e-14 && (n = r), n = Math.max(1, n), this.Nl.length > 0 && (l = n, h = 1, c = 1e-14, Math.abs(l - h) < c)) 3189 for (a = 0, o = this.Nl[0]; Xe(n, i * o, 1e-14) && n > r + 1e-14; ) 3190 n /= o, o = this.Nl[++a % this.Nl.length]; 3191 var l, h, c; 3192 return n; 3193 } 3194 }; 3195 var $r = class { 3196 constructor(t, e, i, r) { 3197 this.Wl = [], this.Ki = t, this.zl = e, this.Hl = i, this.Ul = r; 3198 } 3199 Fl(t, e) { 3200 if (t < e) 3201 throw new Error("high < low"); 3202 const i = this.Ki.$t(), r = (t - e) * this.$l() / i, n = new Vi(this.zl, [2, 2.5, 2]), a = new Vi(this.zl, [2, 2, 2.5]), o = new Vi(this.zl, [2.5, 2, 2]), l = []; 3203 return l.push(n.Fl(t, e, r), a.Fl(t, e, r), o.Fl(t, e, r)), (function(h) { 3204 if (h.length < 1) 3205 throw Error("array is empty"); 3206 let c = h[0]; 3207 for (let d = 1; d < h.length; ++d) 3208 h[d] < c && (c = h[d]); 3209 return c; 3210 })(l); 3211 } 3212 jl() { 3213 const t = this.Ki, e = t.Lt(); 3214 if (e === null) 3215 return void (this.Wl = []); 3216 const i = t.$t(), r = this.Hl(i - 1, e), n = this.Hl(0, e), a = this.Ki.N().entireTextOnly ? this.ql() / 2 : 0, o = a, l = i - 1 - a, h = Math.max(r, n), c = Math.min(r, n); 3217 if (h === c) 3218 return void (this.Wl = []); 3219 const d = this.Fl(h, c); 3220 if (this.Yl(e, d, h, c, o, l), t.Kl() && this.Zl(d, c, h)) { 3221 const p = this.Ki.Gl(); 3222 this.Xl(e, d, o, l, p, 2 * p); 3223 } 3224 const f = this.Wl.map((p) => p.Jl), m = this.Ki.Ql(f); 3225 for (let p = 0; p < this.Wl.length; p++) 3226 this.Wl[p].io = m[p]; 3227 } 3228 El() { 3229 return this.Wl; 3230 } 3231 ql() { 3232 return this.Ki.k(); 3233 } 3234 $l() { 3235 return Math.ceil(this.ql() * this.Ki.N().tickMarkDensity); 3236 } 3237 Yl(t, e, i, r, n, a) { 3238 const o = this.Wl, l = this.Ki; 3239 let h = i % e; 3240 h += h < 0 ? e : 0; 3241 const c = i >= r ? 1 : -1; 3242 let d = null, f = 0; 3243 for (let m = i - h; m > r; m -= e) { 3244 const p = this.Ul(m, t, true); 3245 d !== null && Math.abs(p - d) < this.$l() || p < n || p > a || (f < o.length ? (o[f].Rl = p, o[f].io = l.no(m), o[f].Jl = m) : o.push({ Rl: p, io: l.no(m), Jl: m }), f++, d = p, l.so() && (e = this.Fl(m * c, r))); 3246 } 3247 o.length = f; 3248 } 3249 Xl(t, e, i, r, n, a) { 3250 const o = this.Wl, l = this.eo(t, i, n, a), h = this.eo(t, r, -a, -n), c = this.Ul(0, t, true) - this.Ul(e, t, true); 3251 o.length > 0 && o[0].Rl - l.Rl < c / 2 && o.shift(), o.length > 0 && h.Rl - o[o.length - 1].Rl < c / 2 && o.pop(), o.unshift(l), o.push(h); 3252 } 3253 eo(t, e, i, r) { 3254 const n = (i + r) / 2, a = this.Hl(e + i, t), o = this.Hl(e + r, t), l = Math.min(a, o), h = Math.max(a, o), c = Math.max(0.1, this.Fl(h, l)), d = this.Hl(e + n, t), f = d - d % c, m = this.Ul(f, t, true); 3255 return { io: this.Ki.no(f), Rl: m, Jl: f }; 3256 } 3257 Zl(t, e, i) { 3258 let r = Ot(this.Ki.ar()); 3259 return this.Ki.so() && (r = ue(r, this.Ki.ro())), r.Je() - e < t && i - r.Qe() < t; 3260 } 3261 }; 3262 function jn(s) { 3263 return s.slice().sort((t, e) => k(t.ln()) - k(e.ln())); 3264 } 3265 var Dr; 3266 (function(s) { 3267 s[s.Normal = 0] = "Normal", s[s.Logarithmic = 1] = "Logarithmic", s[s.Percentage = 2] = "Percentage", s[s.IndexedTo100 = 3] = "IndexedTo100"; 3268 })(Dr || (Dr = {})); 3269 var Mr = new Bn(); 3270 var Er = new ki(100, 1); 3271 var Qo = class { 3272 constructor(t, e, i, r, n) { 3273 this.ho = 0, this.ao = null, this.rr = null, this.lo = null, this.oo = { _o: false, uo: null }, this.co = false, this.do = 0, this.fo = 0, this.po = new Y(), this.vo = new Y(), this.mo = [], this.wo = null, this.Mo = null, this.bo = null, this.So = null, this.xo = null, this.il = Er, this.Co = Ui(null), this.yo = t, this.yn = e, this.ko = i, this.Po = r, this.To = n, this.Ro = new $r(this, 100, this.Do.bind(this), this.Io.bind(this)); 3274 } 3275 cl() { 3276 return this.yo; 3277 } 3278 N() { 3279 return this.yn; 3280 } 3281 vr(t) { 3282 if (ft(this.yn, t), this.dl(), t.mode !== void 0 && this.Vo({ _e: t.mode }), t.scaleMargins !== void 0) { 3283 const e = ct(t.scaleMargins.top), i = ct(t.scaleMargins.bottom); 3284 if (e < 0 || e > 1) 3285 throw new Error(`Invalid top margin - expect value between 0 and 1, given=${e}`); 3286 if (i < 0 || i > 1) 3287 throw new Error(`Invalid bottom margin - expect value between 0 and 1, given=${i}`); 3288 if (e + i > 1) 3289 throw new Error(`Invalid margins - sum of margins must be less than 1, given=${e + i}`); 3290 this.Bo(), this.bo = null; 3291 } 3292 } 3293 Eo() { 3294 return this.yn.autoScale; 3295 } 3296 Ao() { 3297 return this.co; 3298 } 3299 so() { 3300 return this.yn.mode === 1; 3301 } 3302 je() { 3303 return this.yn.mode === 2; 3304 } 3305 Lo() { 3306 return this.yn.mode === 3; 3307 } 3308 ro() { 3309 return this.Co; 3310 } 3311 _e() { 3312 return { hs: this.yn.autoScale, zo: this.yn.invertScale, _e: this.yn.mode }; 3313 } 3314 Vo(t) { 3315 const e = this._e(); 3316 let i = null; 3317 t.hs !== void 0 && (this.yn.autoScale = t.hs), t._e !== void 0 && (this.yn.mode = t._e, t._e !== 2 && t._e !== 3 || (this.yn.autoScale = true), this.oo._o = false), e._e === 1 && t._e !== e._e && ((function(n, a) { 3318 if (n === null) 3319 return false;
3320 const o = Pe(n.Je(), a), l = Pe(n.Qe(), a); 3321 return isFinite(o) && isFinite(l); 3322 })(this.rr, this.Co) ? (i = ue(this.rr, this.Co), i !== null && this.Oo(i)) : this.yn.autoScale = true), t._e === 1 && t._e !== e._e && (i = De(this.rr, this.Co), i !== null && this.Oo(i)); 3323 const r = e._e !== this.yn.mode; 3324 r && (e._e === 2 || this.je()) && this.dl(), r && (e._e === 3 || this.Lo()) && this.dl(), t.zo !== void 0 && e.zo !== t.zo && (this.yn.invertScale = t.zo, this.No()), this.vo.p(e, this._e()); 3325 } 3326 Fo() { 3327 return this.vo; 3328 } 3329 k() { 3330 return this.ko.fontSize; 3331 } 3332 $t() { 3333 return this.ho; 3334 } 3335 Wo(t) { 3336 this.ho !== t && (this.ho = t, this.Bo(), this.bo = null); 3337 } 3338 Ho() { 3339 if (this.ao) 3340 return this.ao; 3341 const t = this.$t() - this.Uo() - this.$o(); 3342 return this.ao = t, t; 3343 } 3344 ar() { 3345 return this.jo(), this.rr; 3346 } 3347 Oo(t, e) { 3348 const i = this.rr; 3349 (e || i === null && t !== null || i !== null && !i.Ge(t)) && (this.bo = null, this.rr = t); 3350 } 3351 qo(t) { 3352 this.Oo(t), this.Yo(t !== null); 3353 } 3354 Gi() { 3355 return this.jo(), this.ho === 0 || !this.rr || this.rr.Gi(); 3356 } 3357 Ko(t) { 3358 return this.zo() ? t : this.$t() - 1 - t; 3359 } 3360 Nt(t, e) { 3361 return this.je() ? t = de(t, e) : this.Lo() && (t = Fe(t, e)), this.Io(t, e); 3362 } 3363 Zo(t, e, i) { 3364 this.jo(); 3365 const r = this.$o(), n = k(this.ar()), a = n.Je(), o = n.Qe(), l = this.Ho() - 1, h = this.zo(), c = l / (o - a), d = i === void 0 ? 0 : i.from, f = i === void 0 ? t.length : i.to, m = this.Go(); 3366 for (let p = d; p < f; p++) { 3367 const v = t[p], b = v.Mt; 3368 if (isNaN(b)) 3369 continue; 3370 let y = b; 3371 m !== null && (y = m(v.Mt, e)); 3372 const x = r + c * (y - a), S = h ? x : this.ho - 1 - x; 3373 v.ut = S; 3374 } 3375 } 3376 Xo(t, e, i) { 3377 this.jo(); 3378 const r = this.$o(), n = k(this.ar()), a = n.Je(), o = n.Qe(), l = this.Ho() - 1, h = this.zo(), c = l / (o - a), d = i === void 0 ? 0 : i.from, f = i === void 0 ? t.length : i.to, m = this.Go(); 3379 for (let p = d; p < f; p++) { 3380 const v = t[p]; 3381 let b = v.jr, y = v.qr, x = v.Yr, S = v.Kr; 3382 m !== null && (b = m(v.jr, e), y = m(v.qr, e), x = m(v.Yr, e), S = m(v.Kr, e)); 3383 let w = r + c * (b - a), _ = h ? w : this.ho - 1 - w; 3384 v.Jo = _, w = r + c * (y - a), _ = h ? w : this.ho - 1 - w, v.Qo = _, w = r + c * (x - a), _ = h ? w : this.ho - 1 - w, v.t_ = _, w = r + c * (S - a), _ = h ? w : this.ho - 1 - w, v.i_ = _; 3385 } 3386 } 3387 Tn(t, e) { 3388 const i = this.Do(t, e); 3389 return this.n_(i, e); 3390 } 3391 n_(t, e) { 3392 let i = t; 3393 return this.je() ? i = (function(r, n) { 3394 return n < 0 && (r = -r), r / 100 * n + n; 3395 })(i, e) : this.Lo() && (i = (function(r, n) { 3396 return r -= 100, n < 0 && (r = -r), r / 100 * n + n; 3397 })(i, e)), i; 3398 } 3399 Cl() { 3400 return this.mo; 3401 } 3402 Dt() { 3403 return this.Mo || (this.Mo = jn(this.mo)), this.Mo; 3404 } 3405 s_(t) { 3406 this.mo.indexOf(t) === -1 && (this.mo.push(t), this.dl(), this.e_()); 3407 } 3408 r_(t) { 3409 const e = this.mo.indexOf(t); 3410 if (e === -1) 3411 throw new Error("source is not attached to scale"); 3412 this.mo.splice(e, 1), this.mo.length === 0 && (this.Vo({ hs: true }), this.Oo(null)), this.dl(), this.e_(); 3413 } 3414 Lt() { 3415 let t = null; 3416 for (const e of this.mo) { 3417 const i = e.Lt(); 3418 i !== null && (t === null || i.za < t.za) && (t = i); 3419 } 3420 return t === null ? null : t.Wt; 3421 } 3422 zo() { 3423 return this.yn.invertScale; 3424 } 3425 El() { 3426 const t = this.Lt() === null; 3427 if (this.bo !== null && (t || this.bo.h_ === t)) 3428 return this.bo.El; 3429 this.Ro.jl(); 3430 const e = this.Ro.El(); 3431 return this.bo = { El: e, h_: t }, this.po.p(), e; 3432 } 3433 a_() { 3434 return this.po; 3435 } 3436 l_(t) { 3437 this.je() || this.Lo() || this.So === null && this.lo === null && (this.Gi() || (this.So = this.ho - t, this.lo = k(this.ar()).Xe())); 3438 } 3439 o_(t) { 3440 if (this.je() || this.Lo() || this.So === null) 3441 return;
3442 this.Vo({ hs: false }), (t = this.ho - t) < 0 && (t = 0); 3443 let e = (this.So + 0.2 * (this.ho - 1)) / (t + 0.2 * (this.ho - 1)); 3444 const i = k(this.lo).Xe(); 3445 e = Math.max(e, 0.1), i.ir(e), this.Oo(i); 3446 } 3447 __() { 3448 this.je() || this.Lo() || (this.So = null, this.lo = null); 3449 } 3450 u_(t) { 3451 this.Eo() || this.xo === null && this.lo === null && (this.Gi() || (this.xo = t, this.lo = k(this.ar()).Xe())); 3452 } 3453 c_(t) { 3454 if (this.Eo() || this.xo === null) 3455 return; 3456 const e = k(this.ar()).tr() / (this.Ho() - 1); 3457 let i = t - this.xo; 3458 this.zo() && (i *= -1); 3459 const r = i * e, n = k(this.lo).Xe(); 3460 n.nr(r), this.Oo(n, true), this.bo = null; 3461 } 3462 d_() { 3463 this.Eo() || this.xo !== null && (this.xo = null, this.lo = null); 3464 } 3465 tl() { 3466 return this.il || this.dl(), this.il; 3467 } 3468 Ji(t, e) { 3469 switch (this.yn.mode) { 3470 case 2: 3471 return this.f_(de(t, e)); 3472 case 3: 3473 return this.tl().format(Fe(t, e)); 3474 default: 3475 return this.cr(t); 3476 } 3477 } 3478 no(t) { 3479 switch (this.yn.mode) { 3480 case 2: 3481 return this.f_(t); 3482 case 3: 3483 return this.tl().format(t); 3484 default: 3485 return this.cr(t); 3486 } 3487 } 3488 Ql(t) { 3489 switch (this.yn.mode) { 3490 case 2: 3491 return this.p_(t); 3492 case 3: 3493 return this.tl().formatTickmarks(t); 3494 default: 3495 return this.v_(t); 3496 } 3497 } 3498 xa(t) { 3499 return this.cr(t, k(this.wo).tl()); 3500 } 3501 Ca(t, e) { 3502 return t = de(t, e), this.f_(t, Mr); 3503 } 3504 m_() { 3505 return this.mo; 3506 } 3507 w_(t) { 3508 this.oo = { uo: t, _o: false }; 3509 } 3510 Nn() { 3511 this.mo.forEach((t) => t.Nn()); 3512 } 3513 Kl() { 3514 return this.yn.ensureEdgeTickMarksVisible && this.Eo(); 3515 } 3516 Gl() { 3517 return this.k() / 2; 3518 } 3519 dl() { 3520 this.bo = null; 3521 let t = 1 / 0; 3522 this.wo = null; 3523 for (const i of this.mo) 3524 i.ln() < t && (t = i.ln(), this.wo = i); 3525 let e = 100; 3526 this.wo !== null && (e = Math.round(this.wo.Kh())), this.il = Er, this.je() ? (this.il = Mr, e = 100) : this.Lo() ? (this.il = new ki(100, 1), e = 100) : this.wo !== null && (this.il = this.wo.tl()), this.Ro = new $r(this, e, this.Do.bind(this), this.Io.bind(this)), this.Ro.jl(); 3527 } 3528 e_() { 3529 this.Mo = null; 3530 } 3531 M_() { 3532 return this.wo === null || this.je() || this.Lo() ? 1 : 1 / this.wo.Kh(); 3533 } 3534 Xi() { 3535 return this.To; 3536 } 3537 Yo(t) { 3538 this.co = t; 3539 } 3540 Uo() { 3541 return this.zo() ? this.yn.scaleMargins.bottom * this.$t() + this.fo : this.yn.scaleMargins.top * this.$t() + this.do; 3542 } 3543 $o() { 3544 return this.zo() ? this.yn.scaleMargins.top * this.$t() + this.do : this.yn.scaleMargins.bottom * this.$t() + this.fo; 3545 } 3546 jo() { 3547 this.oo._o || (this.oo._o = true, this.g_()); 3548 } 3549 Bo() { 3550 this.ao = null; 3551 } 3552 Io(t, e) { 3553 if (this.jo(), this.Gi()) 3554 return 0; 3555 t = this.so() && t ? vi(t, this.Co) : t; 3556 const i = k(this.ar()), r = this.$o() + (this.Ho() - 1) * (t - i.Je()) / i.tr(); 3557 return this.Ko(r); 3558 } 3559 Do(t, e) { 3560 if (this.jo(), this.Gi()) 3561 return 0; 3562 const i = this.Ko(t), r = k(this.ar()), n = r.Je() + r.tr() * ((i - this.$o()) / (this.Ho() - 1)); 3563 return this.so() ? Pe(n, this.Co) : n; 3564 } 3565 No() { 3566 this.bo = null, this.Ro.jl(); 3567 } 3568 g_() { 3569 if (this.Ao() && !this.Eo()) 3570 return; 3571 const t = this.oo.uo; 3572 if (t === null) 3573 return; 3574 let e = null; 3575 const i = this.m_(); 3576 let r = 0, n = 0; 3577 for (const l of i) { 3578 if (!l.It()) 3579 continue; 3580 const h = l.Lt(); 3581 if (h === null) 3582 continue; 3583 const c = l.la(t.Oa(), t.bi()); 3584 let d = c && c.ar(); 3585 if (d !== null) { 3586 switch (this.yn.mode) { 3587 case 1: 3588 d = De(d, this.Co); 3589 break; 3590 case 2: 3591 d = Ho(d, h.Wt); 3592 break; 3593 case 3: 3594 d = Wo(d, h.Wt); 3595 } 3596 if (e = e === null ? d : e.Ss(k(d)), c !== null) { 3597 const f = c.lr(); 3598 f !== null && (r = Math.max(r, f.above), n = Math.max(n, f.below)); 3599 } 3600 } 3601 } 3602 if (this.Kl() && (r = Math.max(r, this.Gl()), n = Math.max(n, this.Gl())), r === this.do && n === this.fo || (this.do = r, this.fo = n, this.bo = null, this.Bo()), e !== null) { 3603 if (e.Je() === e.Qe()) { 3604 const l = 5 * this.M_(); 3605 this.so() && (e = ue(e, this.Co)), e = new ot(e.Je() - l, e.Qe() + l), this.so() && (e = De(e, this.Co)); 3606 } 3607 if (this.so()) { 3608 const l = ue(e, this.Co), h = Ui(l); 3609 if (a = h, o = this.Co, a.Al !== o.Al || a.Ll !== o.Ll) { 3610 const c = this.lo !== null ? ue(this.lo, this.Co) : null; 3611 this.Co = h, e = De(l, h), c !== null && (this.lo = De(c, h)); 3612 } 3613 } 3614 this.Oo(e); 3615 } else 3616 this.rr === null && (this.Oo(new ot(-0.5, 0.5)), this.Co = Ui(null)); 3617 var a, o; 3618 } 3619 Go() { 3620 return this.je() ? de : this.Lo() ? Fe : this.so() ? (t) => vi(t, this.Co) : null; 3621 } 3622 b_(t, e, i) { 3623 return e === void 0 ? (i === void 0 && (i = this.tl()), i.format(t)) : e(t); 3624 } 3625 S_(t, e, i) { 3626 return e === void 0 ? (i === void 0 && (i = this.tl()), i.formatTickmarks(t)) : e(t); 3627 } 3628 cr(t, e) { 3629 return this.b_(t, this.Po.priceFormatter, e); 3630 } 3631 v_(t, e) { 3632 var r; 3633 const i = this.Po.priceFormatter; 3634 return this.S_(t, (r = this.Po.tickmarksPriceFormatter) != null ? r : i ? (n) => n.map(i) : void 0, e); 3635 } 3636 f_(t, e) { 3637 return this.b_(t, this.Po.percentageFormatter, e); 3638 } 3639 p_(t, e) { 3640 var r; 3641 const i = this.Po.percentageFormatter; 3642 return this.S_(t, (r = this.Po.tickmarksPercentageFormatter) != null ? r : i ? (n) => n.map(i) : void 0, e); 3643 } 3644 }; 3645 function zr(s) { 3646 return s instanceof Si; 3647 } 3648 var cs = class { 3649 constructor(t, e) { 3650 this.mo = [], this.x_ = /* @__PURE__ */ new Map(), this.ho = 0, this.C_ = 0, this.y_ = 1, this.Mo = null, this.k_ = null, this.P_ = false, this.T_ = new Y(), this.fa = [], this.ia = t, this.sn = e, this.R_ = new jo(this); 3651 const i = e.N(); 3652 this.D_ = this.I_("left", i.leftPriceScale), this.V_ = this.I_("right", i.rightPriceScale), this.D_.Fo().i(this.B_.bind(this, this.D_), this), this.V_.Fo().i(this.B_.bind(this, this.V_), this), this.E_(i); 3653 } 3654 E_(t) { 3655 if (t.leftPriceScale && this.D_.vr(t.leftPriceScale), t.rightPriceScale && this.V_.vr(t.rightPriceScale), t.localization && (this.D_.dl(), this.V_.dl()), t.overlayPriceScales) { 3656 const e = Array.from(this.x_.values()); 3657 for (const i of e) { 3658 const r = k(i[0].Ft()); 3659 r.vr(t.overlayPriceScales), t.localization && r.dl(); 3660 } 3661 } 3662 } 3663 A_(t) { 3664 switch (t) {
3665 case "left": 3666 return this.D_; 3667 case "right": 3668 return this.V_; 3669 } 3670 return this.x_.has(t) ? ct(this.x_.get(t))[0].Ft() : null; 3671 } 3672 m() { 3673 this.Qt().L_().u(this), this.D_.Fo().u(this), this.V_.Fo().u(this), this.mo.forEach((t) => { 3674 t.m && t.m(); 3675 }), this.fa = this.fa.filter((t) => { 3676 const e = t.Qh(); 3677 return e.detached && e.detached(), false; 3678 }), this.T_.p(); 3679 } 3680 z_() { 3681 return this.y_; 3682 } 3683 O_(t) { 3684 this.y_ = t; 3685 } 3686 Qt() { 3687 return this.sn; 3688 } 3689 nn() { 3690 return this.C_; 3691 } 3692 $t() { 3693 return this.ho; 3694 } 3695 N_(t) { 3696 this.C_ = t, this.F_(); 3697 } 3698 Wo(t) { 3699 this.ho = t, this.D_.Wo(t), this.V_.Wo(t), this.mo.forEach((e) => { 3700 if (this.Zs(e)) { 3701 const i = e.Ft(); 3702 i !== null && i.Wo(t); 3703 } 3704 }), this.F_(); 3705 } 3706 W_(t) { 3707 this.P_ = t; 3708 } 3709 H_() { 3710 return this.P_; 3711 } 3712 U_() { 3713 return this.mo.filter(zr); 3714 } 3715 Cl() { 3716 return this.mo; 3717 } 3718 Zs(t) { 3719 const e = t.Ft(); 3720 return e === null || this.D_ !== e && this.V_ !== e; 3721 } 3722 s_(t, e, i) { 3723 this.j_(t, e, i ? t.ln() : this.mo.length); 3724 } 3725 r_(t, e) { 3726 const i = this.mo.indexOf(t); 3727 et(i !== -1, "removeDataSource: invalid data source"), this.mo.splice(i, 1), e || this.mo.forEach((a, o) => a._n(o)); 3728 const r = k(t.Ft()).cl(); 3729 if (this.x_.has(r)) { 3730 const a = ct(this.x_.get(r)), o = a.indexOf(t); 3731 o !== -1 && (a.splice(o, 1), a.length === 0 && this.x_.delete(r)); 3732 } 3733 const n = t.Ft(); 3734 n && n.Cl().indexOf(t) >= 0 && (n.r_(t), this.q_(n)), this.Y_(); 3735 } 3736 Xs(t) { 3737 return t === this.D_ ? "left" : t === this.V_ ? "right" : "overlay"; 3738 } 3739 K_() { 3740 return this.D_; 3741 } 3742 Z_() { 3743 return this.V_; 3744 } 3745 G_(t, e) { 3746 t.l_(e); 3747 } 3748 X_(t, e) { 3749 t.o_(e), this.F_(); 3750 } 3751 J_(t) { 3752 t.__(); 3753 } 3754 Q_(t, e) { 3755 t.u_(e); 3756 } 3757 tu(t, e) { 3758 t.c_(e), this.F_(); 3759 } 3760 iu(t) { 3761 t.d_(); 3762 } 3763 F_() { 3764 this.mo.forEach((t) => { 3765 t.Nn(); 3766 }); 3767 } 3768 Pn() { 3769 var r; 3770 const [t, e] = this.nu(); 3771 let i = null; 3772 return t.N().visible && t.Cl().length !== 0 ? i = t : e.N().visible && e.Cl().length !== 0 ? i = e : this.mo.length !== 0 && (i = this.mo[0].Ft()), i === null && (i = (r = this.Gs()) != null ? r : t), i; 3773 } 3774 Gs() { 3775 const [t, e] = this.nu(); 3776 return t.N().visible ? t : e.N().visible ? e : null; 3777 } 3778 q_(t) { 3779 t !== null && t.Eo() && this.su(t); 3780 } 3781 eu(t) { 3782 const e = this.ia.Ee(); 3783 t.Vo({ hs: true }), e !== null && t.w_(e), this.F_(); 3784 } 3785 ru() { 3786 this.su(this.D_), this.su(this.V_); 3787 } 3788 hu() { 3789 this.q_(this.D_), this.q_(this.V_), this.mo.forEach((t) => { 3790 this.Zs(t) && this.q_(t.Ft()); 3791 }), this.F_(), this.sn.mr(); 3792 } 3793 Dt() { 3794 return this.Mo === null && (this.Mo = jn(this.mo)), this.Mo; 3795 } 3796 au() { 3797 var a; 3798 const t = this.Dt(), e = (a = this.sn.ou()) == null ? void 0 : a.lu, i = this.sn.N().hoveredSeriesOnTop, r = this.k_; 3799 if (r !== null && r.Kh === t && r._u === e && r.uu === i) 3800 return r.cu; 3801 const n = (function(o, l, h) { 3802 if (!h) 3803 return o; 3804 const c = o.indexOf(l); 3805 if (c === -1 || c === o.length - 1) 3806 return o; 3807 const d = []; 3808 for (let f = 0; f < o.length; f++) 3809 f !== c && d.push(o[f]); 3810 return d.push(o[c]), d; 3811 })(t, e, i); 3812 return this.k_ = { Kh: t, _u: e, uu: i, cu: n }, n; 3813 } 3814 du(t, e) { 3815 e = fe(e, 0, this.mo.length - 1); 3816 const i = this.mo.indexOf(t); 3817 et(i !== -1, "setSeriesOrder: invalid data source"), this.mo.splice(i, 1), this.mo.splice(e, 0, t), this.mo.forEach((r, n) => r._n(n)), this.Y_(); 3818 for (const r of [this.D_, this.V_]) 3819 r.e_(), r.dl(); 3820 this.sn.mr(); 3821 } 3822 Vt() { 3823 return this.Dt().filter(zr); 3824 } 3825 fu() { 3826 return this.T_; 3827 } 3828 pu() { 3829 return this.R_; 3830 } 3831 hl(t) { 3832 this.fa.push(new Fo(t)); 3833 } 3834 al(t) { 3835 this.fa = this.fa.filter((e) => e.Qh() !== t), t.detached && t.detached(), this.sn.mr(); 3836 } 3837 vu() { 3838 return this.fa; 3839 } 3840 Ja(t, e) { 3841 return this.fa.map((i) => i.Qs(t, e)).filter((i) => i !== null); 3842 } 3843 su(t) { 3844 const e = t.m_(); 3845 if (e && e.length > 0 && !this.ia.Gi()) { 3846 const i = this.ia.Ee(); 3847 i !== null && t.w_(i); 3848 } 3849 t.Nn(); 3850 } 3851 j_(t, e, i) { 3852 let r = this.A_(e); 3853 if (r === null && (r = this.I_(e, this.sn.N().overlayPriceScales)), this.mo.splice(i, 0, t), !xi(e)) { 3854 const n = this.x_.get(e) || []; 3855 n.push(t), this.x_.set(e, n); 3856 } 3857 t._n(i), r.s_(t), t.un(r), this.q_(r), this.Y_(); 3858 } 3859 Y_() { 3860 this.Mo = null, this.k_ = null; 3861 } 3862 nu() { 3863 return this.sn.N().defaultVisiblePriceScaleId === "left" ? [this.D_, this.V_] : [this.V_, this.D_]; 3864 } 3865 B_(t, e, i) { 3866 e._e !== i._e && this.su(t); 3867 } 3868 I_(t, e) { 3869 const i = M({ visible: true, autoScale: true }, zt(e)), r = new Qo(t, i, this.sn.N().layout, this.sn.N().localization, this.sn.Xi()); 3870 return r.Wo(this.$t()), r; 3871 } 3872 }; 3873 function ds(s, t) { 3874 return t === null || s.se === 2 && t.se !== 2 || (t.se !== 2 || s.se === 2) && s.ne !== t.ne && s.ne < t.ne; 3875 } 3876 function Hn(s) { 3877 return { te: s.te, ie: s.ie }; 3878 } 3879 function Yo(s) { 3880 var t, e, i; 3881 return { ne: (t = s.distance) != null ? t : 0, se: (e = s.hitTestPriority) != null ? e : s.itemType === "marker" ? 2 : 0, ee: (i = s.itemType) != null ? i : "primitive", mu: s.cursorStyle, te: s.externalId }; 3882 } 3883 function Je(s) { 3884 var t; 3885 return { lu: s.lu, wu: Hn(s.Mu), mu: s.Mu.mu, ee: (t = s.Mu.ee) != null ? t : "primitive" }; 3886 } 3887 function Ko(s, t, e, i) { 3888 var n, a; 3889 let r = null; 3890 for (const o of s) { 3891 let l = (a = (n = o.Qs) == null ? void 0 : n.call(o, t, e, i)) != null ? a : null; 3892 if (l === null) { 3893 const h = o.Tt(i); 3894 l = h !== null && h.Qs ? h.Qs(t, e) : null; 3895 } 3896 if (l !== null) { 3897 const h = { gu: o, Mu: l }; 3898 (r === null || ds(h.Mu, r.Mu)) && (r = h); 3899 } 3900 } 3901 return r; 3902 } 3903 function Zo(s) { 3904 return s.jn !== void 0; 3905 } 3906 function Wn(s, t, e) { 3907 var o; 3908 const i = [s, ...s.Dt()].reverse(), r = (function(l, h, c) { 3909 var b, y; 3910 let d, f, m; 3911 for (const x of l) { 3912 const S = (y = (b = x.Ja) == null ? void 0 : b.call(x, h, c)) != null ? y : []; 3913 for (const w of S) { 3914 const _ = Yo(w); 3915 p = w.zOrder, v = d == null ? void 0 : d.zOrder, (!v || p === "top" && v !== "top" || p === "normal" && v === "bottom" || w.zOrder === (d == null ? void 0 : d.zOrder) && f !== void 0 && ds(_, f) || w.zOrder === (d == null ? void 0 : d.zOrder) && f === void 0) && (d = w, f = _, m = x); 3916 } 3917 } 3918 var p, v; 3919 return d && m && f ? { Mu: f, bu: d, lu: m } : null; 3920 })(i, t, e); 3921 if ((r == null ? void 0 : r.bu.zOrder) === "top") 3922 return Je(r); 3923 let n = null, a = null; 3924 for (const l of i) { 3925 if (r && r.lu === l && r.bu.zOrder !== "bottom" && !r.bu.isBackgroun
3925d) 3926 return n != null ? n : Je(r); 3927 if (Zo(l)) { 3928 const h = Ko(l.jn(s), t, e, s); 3929 if (h !== null) { 3930 const c = { lu: l, gu: h.gu, wu: Hn(h.Mu), mu: h.Mu.mu, ee: (o = h.Mu.ee) != null ? o : "primitive" }; 3931 (n === null || ds(h.Mu, a)) && (n = c, a = h.Mu); 3932 } 3933 } 3934 if (r && r.lu === l && r.bu.zOrder !== "bottom" && r.bu.isBackground) 3935 return n != null ? n : Je(r); 3936 } 3937 return n !== null ? n : r != null && r.bu ? Je(r) : null; 3938 } 3939 var Go = class { 3940 constructor(t, e, i = 50) { 3941 this.Vs = 0, this.Bs = 1, this.Es = 1, this.Ls = /* @__PURE__ */ new Map(), this.As = /* @__PURE__ */ new Map(), this.Su = t, this.xu = e, this.zs = i; 3942 } 3943 Cu(t) { 3944 const e = t.time, i = this.xu.cacheKey(e), r = this.Ls.get(i); 3945 if (r !== void 0) 3946 return r.yu; 3947 if (this.Vs === this.zs) { 3948 const a = this.As.get(this.Es); 3949 this.As.delete(this.Es), this.Ls.delete(ct(a)), this.Es++, this.Vs--; 3950 } 3951 const n = this.Su(t); 3952 return this.Ls.set(i, { yu: n, Ws: this.Bs }), this.As.set(this.Bs, i), this.Vs++, this.Bs++, n; 3953 } 3954 }; 3955 var Ae = class { 3956 constructor(t, e) { 3957 et(t <= e, "right should be >= left"), this.ku = t, this.Pu = e; 3958 } 3959 Oa() { 3960 return this.ku; 3961 } 3962 bi() { 3963 return this.Pu; 3964 } 3965 Tu() { 3966 return this.Pu - this.ku + 1; 3967 } 3968 ze(t) { 3969 return this.ku <= t && t <= this.Pu; 3970 } 3971 Ge(t) { 3972 return this.ku === t.Oa() && this.Pu === t.bi(); 3973 } 3974 }; 3975 function Fr(s, t) { 3976 return s === null || t === null ? s === t : s.Ge(t); 3977 } 3978 var Xo = class { 3979 constructor() { 3980 this.Ru = /* @__PURE__ */ new Map(), this.Ls = null, this.Du = false; 3981 } 3982 Iu(t) { 3983 this.Du = t, this.Ls = null; 3984 } 3985 Vu(t, e) { 3986 this.Bu(e), this.Ls = null; 3987 for (let i = e; i < t.length; ++i) { 3988 const r = t[i]; 3989 let n = this.Ru.get(r.timeWeight); 3990 n === void 0 && (n = [], this.Ru.set(r.timeWeight, n)), n.push({ index: i, time: r.time, weight: r.timeWeight, originalTime: r.originalTime }); 3991 } 3992 } 3993 Eu(t, e, i, r, n) { 3994 const a = Math.ceil(e / t); 3995 return this.Ls !== null && this.Ls.Au === a && n === this.Ls.Lu && i === this.Ls.zu || (this.Ls = { Lu: n, zu: i, El: this.Ou(a, i, r), Au: a }), this.Ls.El; 3996 } 3997 Bu(t) { 3998 if (t === 0) 3999 return void this.Ru.clear(); 4000 const e = []; 4001 this.Ru.forEach((i, r) => { 4002 t <= i[0].index ? e.push(r) : i.splice(ie(i, t, (n) => n.index < t), 1 / 0); 4003 }); 4004 for (const i of e) 4005 this.Ru.delete(i); 4006 } 4007 Ou(t, e, i) { 4008 let r = []; 4009 const n = (a) => !e || i.has(a.index); 4010 for (const a of Array.from(this.Ru.keys()).sort((o, l) => l - o)) { 4011 if (!this.Ru.get(a)) 4012 continue; 4013 const o = r; 4014 r = []; 4015 const l = o.length; 4016 let h = 0; 4017 const c = ct(this.Ru.get(a)), d = c.length; 4018 let f = 1 / 0, m = -1 / 0; 4019 for (let p = 0; p < d; p++) { 4020 const v = c[p], b = v.index; 4021 for (; h < l; ) { 4022 const y = o[h], x = y.index; 4023 if (!(x < b && n(y))) { 4024 f = x; 4025 break; 4026 } 4027 h++, r.push(y), m = x, f = 1 / 0; 4028 } 4029 if (f - b >= t && b - m >= t && n(v)) 4030 r.push(v), m = b; 4031 else if (this.Du) 4032 return o; 4033 } 4034 for (; h < l; h++) 4035 n(o[h]) && r.push(o[h]); 4036 } 4037 return r; 4038 } 4039 }; 4040 var me = class _me { 4041 constructor(t) { 4042 this.Nu = t; 4043 } 4044 Fu() { 4045 return this.Nu === null ? null : new Ae(Math.floor(this.Nu.Oa()), Math.ceil(this.Nu.bi())); 4046 } 4047 Wu() { 4048 return this.Nu; 4049 } 4050 static Hu() { 4051 return new _me(null); 4052 } 4053 }; 4054 function Jo(s, t) { 4055 return s.weight > t.weight ? s : t; 4056 } 4057 var tl = class { 4058 constructor(t, e, i, r) { 4059 this.C_ = 0, this.Uu = null, this.$u = [], this.xo = null, this.So = null, this.ju = new Xo(), this.qu = /* @__PURE__ */ new Map(), this.Yu = me.Hu(), this.Ku = true, this.Zu = new Y(), this.Gu = new Y(), this.Xu = new Y(), this.Ju = null, this.Qu = null, this.tc = /* @__PURE__ */ new Map(), this.nc = -1, this.sc = [], this.ec = 1, this.yn = e, this.Po = i, this.rc = e.rightOffset, this.hc = e.barSpacing, this.sn = t, this.ac(e), this.xu = r, this.lc(), this.ju.Iu(e.uniformDistribution), this.oc(), this._c(); 4060 } 4061 N() { 4062 return this.yn; 4063 } 4064 uc(t) { 4065 ft(this.Po, t), this.cc(), this.lc(); 4066 } 4067 vr(t, e) { 4068 var i; 4069 ft(this.yn, t), this.yn.fixLeftEdge && this.dc(), this.yn.fixRightEdge && this.fc(), t.barSpacing !== void 0 && this.sn.Ms(t.barSpacing), t.rightOffset !== void 0 && this.sn.gs(t.rightOffset), this.ac(t), t.minBarSpacing === void 0 && t.maxBarSpacing === void 0 || this.sn.Ms((i = t.barSpacing) != null ? i : this.hc), t.ignoreWhitespaceIndices !== void 0 && t.ignoreWhitespaceIndices !== this.yn.ignoreWhitespaceIndices && this._c(), this.cc(), this.lc(), t.enableConflation === void 0 && t.conflationThresholdFactor === void 0 || this.oc(), this.Xu.p(); 4070 } 4071 Rn(t) { 4072 var e, i; 4073 return (i = (e = this.$u[t]) == null ? void 0 : e.time) != null ? i : null; 4074 } 4075 en(t) { 4076 var e; 4077 return (e = this.$u[t]) != null ? e : null; 4078 } 4079 vc(t, e) { 4080 if (this.$u.length < 1) 4081 return null; 4082 if (this.xu.key(t) > this.xu.key(this.$u[this.$u.length - 1].time)) 4083 return e ? this.$u.length - 1 : null; 4084 const i = ie(this.$u, this.xu.key(t), (r, n) => this.xu.key(r.time) < n); 4085 return this.xu.key(t) < this.xu.key(this.$u[i].time) ? e ? i : null : i; 4086 } 4087 Gi() { 4088 return this.C_ === 0 || this.$u.length === 0 || this.Uu === null; 4089 } 4090 mc() { 4091 return this.$u.length > 0; 4092 } 4093 Ee() { 4094 return this.wc(), this.Yu.Fu(); 4095 } 4096 Mc() { 4097 return this.wc(), this.Yu.Wu(); 4098 } 4099 gc() { 4100 const t = this.Ee(); 4101 if (t === null) 4102 return null; 4103 const e = { from: t.Oa(), to: t.bi() }; 4104 return this.bc(e); 4105 } 4106 bc(t) { 4107 const e = Math.round(t.from), i = Math.round(t.to), r = k(this.Sc()), n = k(this.xc()); 4108 return { from: k(this.en(Math.max(r, e))), to: k(this.en(Math.min(n, i)
4108)) }; 4109 } 4110 Cc(t) { 4111 return { from: k(this.vc(t.from, true)), to: k(this.vc(t.to, true)) }; 4112 } 4113 nn() { 4114 return this.C_; 4115 } 4116 N_(t) { 4117 if (!isFinite(t) || t <= 0 || this.C_ === t) 4118 return; 4119 const e = this.Mc(), i = this.C_; 4120 if (this.C_ = t, this.Ku = true, this.yn.lockVisibleTimeRangeOnResize && i !== 0) { 4121 const r = this.hc * t / i; 4122 this.hc = r; 4123 } 4124 if (this.yn.fixLeftEdge && e !== null && e.Oa() <= 0) { 4125 const r = i - t; 4126 this.rc -= Math.round(r / this.hc) + 1, this.Ku = true; 4127 } 4128 this.yc(), this.kc(); 4129 } 4130 jt(t) { 4131 if (this.Gi() || !Le(t)) 4132 return 0; 4133 const e = this.Pc() + this.rc - t; 4134 return this.C_ - (e + 0.5) * this.hc - 1; 4135 } 4136 Tc(t, e) { 4137 const i = this.Pc(), r = e === void 0 ? 0 : e.from, n = e === void 0 ? t.length : e.to; 4138 for (let a = r; a < n; a++) { 4139 const o = t[a].wt, l = i + this.rc - o, h = this.C_ - (l + 0.5) * this.hc - 1; 4140 t[a]._t = h; 4141 } 4142 } 4143 Rc(t, e) { 4144 const i = Math.ceil(this.Dc(t)); 4145 return e && this.yn.ignoreWhitespaceIndices && !this.Ic(i) ? this.Vc(i) : i; 4146 } 4147 gs(t) { 4148 this.Ku = true, this.rc = t, this.kc(), this.sn.Bc(), this.sn.mr(); 4149 } 4150 fl() { 4151 return this.hc; 4152 } 4153 Ms(t) { 4154 const e = this.hc; 4155 if (this.Ec(t), this.yn.rightOffsetPixels !== void 0 && e !== 0) { 4156 const i = this.rc * e / this.hc; 4157 this.rc = i; 4158 } 4159 this.kc(), this.sn.Bc(), this.sn.mr(); 4160 } 4161 Ac() { 4162 return this.rc; 4163 } 4164 El() { 4165 if (this.Gi()) 4166 return null; 4167 if (this.Qu !== null) 4168 return this.Qu; 4169 const t = this.hc, e = 5 * (this.sn.N().layout.fontSize + 4) / 8 * (this.yn.tickMarkMaxCharacterLength || 8), i = Math.round(e / t), r = k(this.Ee()), n = Math.max(r.Oa(), r.Oa() - i), a = Math.max(r.bi(), r.bi() - i), o = this.ju.Eu(t, e, this.yn.ignoreWhitespaceIndices, this.tc, this.nc), l = this.Sc() + i, h = this.xc() - i, c = this.Lc(), d = this.yn.fixLeftEdge || c, f = this.yn.fixRightEdge || c; 4170 let m = 0; 4171 for (const p of o) { 4172 if (!(n <= p.index && p.index <= a)) 4173 continue; 4174 let v; 4175 m < this.sc.length ? (v = this.sc[m], v.coord = this.jt(p.index), v.label = this.zc(p), v.weight = p.weight) : (v = { needAlignCoordinate: false, coord: this.jt(p.index), label: this.zc(p), weight: p.weight }, this.sc.push(v)), this.hc > e / 2 && !c ? v.needAlignCoordinate = false : v.needAlignCoordinate = d && p.index <= l || f && p.index >= h, m++; 4176 } 4177 return this.sc.length = m, this.Qu = this.sc, this.sc; 4178 } 4179 Oc() { 4180 let t; 4181 this.Ku = true, this.Ms(this.yn.barSpacing), t = this.yn.rightOffsetPixels !== void 0 ? this.yn.rightOffsetPixels / this.fl() : this.yn.rightOffset, this.gs(t); 4182 } 4183 Nc(t) { 4184 this.Ku = true, this.Uu = t, this.kc(), this.dc(); 4185 } 4186 Fc(t, e) { 4187 const i = this.Dc(t), r = this.fl(), n = r + e * (r / 10); 4188 this.Ms(n), this.yn.rightBarStaysOnScroll || this.gs(this.Ac() + (i - this.Dc(t))); 4189 } 4190 l_(t) { 4191 this.xo && this.d_(), this.So === null && this.Ju === null && (this.Gi() || (this.So = t, this.Wc())); 4192 } 4193 o_(t) { 4194 if (this.Ju === null) 4195 return; 4196 const e = fe(this.C_ - t, 0, this.C_), i = fe(this.C_ - k(this.So), 0, this.C_); 4197 e !== 0 && i !== 0 && this.Ms(this.Ju.fl * e / i); 4198 } 4199 __() { 4200 this.So !== null && (this.So = null, this.Hc()); 4201 } 4202 u_(t) { 4203 this.xo === null && this.Ju === null && (this.Gi() || (this.xo = t, this.Wc())); 4204 } 4205 c_(t) { 4206 if (this.xo === null) 4207 return; 4208 const e = (this.xo - t) / this.fl(); 4209 this.rc = k(this.Ju).Ac + e, this.Ku = true, this.kc(); 4210 } 4211 d_() { 4212 this.xo !== null && (this.xo = null, this.Hc()); 4213 } 4214 Uc() { 4215 this.$c(this.yn.rightOffset); 4216 } 4217 $c(t, e = 400) { 4218 if (!isFinite(t)) 4219 throw new RangeError("offset is required and must be finite number"); 4220 if (!isFinite(e) || e <= 0) 4221 throw new RangeError("animationDuration (optional) must be finite positive number"); 4222 const i = this.rc, r = performance.now(); 4223 this.sn.ps({ jc: (n) => (n - r) / e >= 1, qc: (n) => { 4224 const a = (n - r) / e; 4225 return a >= 1 ? t : i + (t - i) * a; 4226 } }); 4227 } 4228 kt(t, e) { 4229 this.Ku = true, this.$u = t, this.ju.Vu(t, e), this.kc(); 4230 } 4231 Yc() { 4232 return this.Zu; 4233 } 4234 Kc() { 4235 return this.Gu; 4236 } 4237 Zc() { 4238 return this.Xu; 4239 } 4240 Pc() { 4241 return this.Uu || 0; 4242 } 4243 Gc(t, e) { 4244 const i = t.Tu(), r = e && this.yn.rightOffsetPixels || 0; 4245 this.Ec((this.C_ - r) / i), this.rc = t.bi() - this.Pc(), e && (this.rc = r ? r / this.fl() : this.yn.rightOffset), this.kc(), this.Ku = true, this.sn.Bc(), this.sn.mr(); 4246 } 4247 Xc() { 4248 const t = this.Sc(), e = this.xc(); 4249 if (t === null || e === null) 4250 return; 4251 const i = !this.yn.rightOffsetPixels && this.yn.rightOffset || 0; 4252 this.Gc(new Ae(t, e + i), true); 4253 } 4254 Jc(t) { 4255 const e = new Ae(t.from, t.to); 4256 this.Gc(e); 4257 } 4258 rn(t) { 4259 return this.Po.timeFormatter !== void 0 ? this.Po.timeFormatter(t.originalTime) : this.xu.formatHorzItem(t.time); 4260 } 4261 _c() { 4262 if (!this.yn.ignoreWhitespaceIndices) 4263 return; 4264 this.tc.clear(); 4265 const t = this.sn.Jn(); 4266 for (const e of t) 4267 for (const i of e.ul()) 4268 this.tc.set(i, true); 4269 this.nc++; 4270 } 4271 Qc() { 4272 return this.ec; 4273 } 4274 Ml() { 4275 const t = 1 / (window.devicePixelRatio || 1), e = this.yn.minBarSpacing; 4276 if (e >= t) 4277 return [1]; 4278 const i = [1]; 4279 let r = 2; 4280 for (; r <= 512; ) 4281 e < t / r && i.push(r), r *= 2; 4282 return i; 4283 } 4284 Lc() { 4285 const t = this.sn.N().handleScroll, e = this.sn.N().handleScale; 4286 return !(t.horzTouchDrag || t.mouseWheel || t.pressedMouseMove || t.vertTouchDrag || e.axisDoubleClickReset.time || e.axisPressedMouseMove.time || e.mouseWheel || e.pinch); 4287 } 4288 Sc() { 4289 return this.$u.length === 0 ? null : 0; 4290 } 4291 xc() { 4292 return this.$u.length === 0 ? null : this.$u.length - 1; 4293 } 4294 td(t) { 4295 return (this.C_ - 1 - t) / this.hc; 4296 } 4297 Dc(t) { 4298 const e = this.td(t), i = this.Pc() + this.rc - e; 4299 return Math.round(1e6 * i) / 1e6; 4300 } 4301 Ec(t) { 4302 const e = this.hc; 4303 this.hc = t, this.yc(), e !== this.hc && (this.Ku = true, this.nd(), this.oc()); 4304 } 4305 wc() { 4306 if (!this.Ku) 4307 return; 4308 if (this.Ku = false, this.Gi()) 4309 return void this.sd(me.Hu()); 4310 const t = this.Pc(), e = this.C_ / this.hc, i = this.rc + t, r = new Ae(i - e + 1, i); 4311 this.sd(new me(r)); 4312 } 4313 yc() { 4314 const t = fe(this.hc, this.ed(), this.rd()); 4315 this.hc !== t && (this.hc = t, this.Ku = true); 4316 } 4317 rd() { 4318 return this.yn.maxBarSpacing > 0 ? this.yn.maxBarSpacing : 0.5 * this.C_; 4319 } 4320 ed() { 4321 return this.yn.fixLeftEdge && this.yn.fixRightEdge && this.$u.length !== 0 ? this.C_ / this.$u.length : this.yn.minBarSpacing; 4322 } 4323 oc() { 4324 var r; 4325 if (!this.yn.enableConflation) 4326 return void (this.ec = 1); 4327 const t = 1 / (window.devicePixelRatio || 1) * ((r = this.yn.conflationThresholdFactor) != null ? r : 1); 4328 if (this.hc >= t) 4329 return void (this.ec = 1); 4330 const e = t / this.hc, i = Math.pow(2, Math.floor(Math.log2(e))); 4331 this.ec = Math.min(i, 512); 4332 } 4333 kc() { 4334 const t = this.hd(); 4335 t !== null && this.rc < t && (this.rc = t, this.Ku = true); 4336 const e = this.ad(); 4337 this.rc > e && (this.rc = e, this.Ku = true); 4338 } 4339 hd() { 4340 const t = this.Sc(), e = this.Uu;
4341 return t === null || e === null ? null : t - e - 1 + (this.yn.fixLeftEdge ? this.C_ / this.hc : Math.min(2, this.$u.length)); 4342 } 4343 ad() { 4344 return this.yn.fixRightEdge ? 0 : this.C_ / this.hc - Math.min(2, this.$u.length); 4345 } 4346 Wc() { 4347 this.Ju = { fl: this.fl(), Ac: this.Ac() }; 4348 } 4349 Hc() { 4350 this.Ju = null; 4351 } 4352 zc(t) { 4353 let e = this.qu.get(t.weight); 4354 return e === void 0 && (e = new Go((i) => this.ld(i), this.xu), this.qu.set(t.weight, e)), e.Cu(t); 4355 } 4356 ld(t) { 4357 return this.xu.formatTickmark(t, this.Po); 4358 } 4359 sd(t) { 4360 const e = this.Yu; 4361 this.Yu = t, Fr(e.Fu(), this.Yu.Fu()) || this.Zu.p(), Fr(e.Wu(), this.Yu.Wu()) || this.Gu.p(), this.nd(); 4362 } 4363 nd() { 4364 this.Qu = null; 4365 } 4366 cc() { 4367 this.nd(), this.qu.clear(); 4368 } 4369 lc() { 4370 this.xu.updateFormatter(this.Po); 4371 } 4372 dc() { 4373 if (!this.yn.fixLeftEdge) 4374 return; 4375 const t = this.Sc(); 4376 if (t === null) 4377 return; 4378 const e = this.Ee(); 4379 if (e === null) 4380 return; 4381 const i = e.Oa() - t; 4382 if (i < 0) { 4383 const r = this.rc - i - 1; 4384 this.gs(r); 4385 } 4386 this.yc(); 4387 } 4388 fc() { 4389 this.kc(), this.yc(); 4390 } 4391 Ic(t) { 4392 return !this.yn.ignoreWhitespaceIndices || this.tc.get(t) || false; 4393 } 4394 Vc(t) { 4395 const e = (function* (r) { 4396 const n = Math.round(r), a = n < r; 4397 let o = 1; 4398 for (; ; ) 4399 a ? (yield n + o, yield n - o) : (yield n - o, yield n + o), o++; 4400 })(t), i = this.xc(); 4401 for (; i; ) { 4402 const r = e.next().value; 4403 if (this.tc.get(r)) 4404 return r; 4405 if (r < 0 || r > i) 4406 break; 4407 } 4408 return t; 4409 } 4410 ac(t) { 4411 if (t.rightOffsetPixels !== void 0) { 4412 const e = t.rightOffsetPixels / (t.barSpacing || this.hc); 4413 this.sn.gs(e); 4414 } 4415 } 4416 }; 4417 var Pr; 4418 var Ar; 4419 var Tr; 4420 var Ir; 4421 var Rr; 4422 (function(s) { 4423 s[s.OnTouchEnd = 0] = "OnTouchEnd", s[s.OnNextTap = 1] = "OnNextTap"; 4424 })(Pr || (Pr = {})); 4425 var el = class { 4426 constructor(t, e, i) { 4427 this.od = [], this._d = [], this.ud = null, this.C_ = 0, this.dd = null, this.fd = new Y(), this.pd = new Y(), this.vd = null, this.md = t, this.yn = e, this.xu = i, this.To = new Ga(this.yn.layout.colorParsers), this.wd = new Za(this), this.ia = new tl(this, e.timeScale, this.yn.localization, i), this.Ct = new oo(this, e.crosshair), this.Md = new qo(e.crosshair), e.addDefaultPane && (this.gd(0), this.od[0].O_(2)), this.bd = this.Sd(0), this.xd = this.Sd(1); 4428 } 4429 Pa() { 4430 this.Cd(tt.ys()); 4431 } 4432 mr() { 4433 this.Cd(tt.Cs()); 4434 } 4435 qa() { 4436 this.Cd(new tt(1)); 4437 } 4438 Ta(t) { 4439 const e = this.yd(t); 4440 this.Cd(e); 4441 } 4442 ou() { 4443 return this.dd; 4444 } 4445 kd(t) { 4446 var i, r, n, a, o, l, h, c, d; 4447 if (((i = this.dd) == null ? void 0 : i.lu) === (t == null ? void 0 : t.lu) && ((n = (r = this.dd) == null ? void 0 : r.wu) == null ? void 0 : n.te) === ((a = t == null ? void 0 : t.wu) == null ? void 0 : a.te) && ((l = (o = this.dd) == null ? void 0 : o.wu) == null ? void 0 : l.ie) === ((h = t == null ? void 0 : t.wu) == null ? void 0 : h.ie) && ((c = this.dd) == null ? void 0 : c.mu) === (t == null ? void 0 : t.mu) && ((d = this.dd) == null ? void 0 : d.ee) === (t == null ? void 0 : t.ee)) 4448 return; 4449 const e = this.dd; 4450 this.dd = t, e !== null && this.Ta(e.lu), t !== null && t.lu !== (e == null ? void 0 : e.lu) && this.Ta(t.lu); 4451 } 4452 N() { 4453 return this.yn; 4454 } 4455 vr(t) { 4456 ft(this.yn, t), this.od.forEach((e) => e.E_(t)), t.timeScale !== void 0 && this.ia.vr(t.timeScale), t.localization !== void 0 && this.ia.uc(t.localization), (t.leftPriceScale || t.rightPriceScale) && this.fd.p(), this.bd = this.Sd(0), this.xd = this.Sd(1), this.Pa(); 4457 } 4458 Pd(t, e, i = 0) { 4459 const r = this.od[i]; 4460 if (r === void 0) 4461 return; 4462 if (t === "left") 4463 return ft(this.yn, { leftPriceScale: e }), r.E_({ leftPriceScale: e }), this.fd.p(), void this.Pa(); 4464 if (t === "right") 4465 return ft(this.yn, { rightPriceScale: e }), r.E_({ rightPriceScale: e }), this.fd.p(), void this.Pa(); 4466 const n = this.Td(t, i); 4467 n !== null && (n.Ft.vr(e), this.fd.p()); 4468 } 4469 Td(t, e) { 4470 const i = this.od[e]; 4471 if (i === void 0) 4472 return null; 4473 const r = i.A_(t); 4474 return r !== null ? { Kn: i, Ft: r } : null; 4475 } 4476 Et() { 4477 return this.ia; 4478 } 4479 Zn() { 4480 return this.od; 4481 } 4482 Rd() { 4483 return this.Ct; 4484 } 4485 Dd() { 4486 return this.pd; 4487 } 4488 Id(t, e) { 4489 t.Wo(e), this.Bc(); 4490 } 4491 N_(t) {
4492 this.C_ = t, this.ia.N_(this.C_), this.od.forEach((e) => e.N_(t)), this.Bc(); 4493 } 4494 Vd(t) { 4495 this.od.length !== 1 && (et(t >= 0 && t < this.od.length, "Invalid pane index"), this.od.splice(t, 1), this.Pa()); 4496 } 4497 Bd(t, e) { 4498 if (this.od.length < 2) 4499 return; 4500 et(t >= 0 && t < this.od.length, "Invalid pane index"); 4501 const i = this.od[t], r = this.od.reduce((d, f) => d + f.z_(), 0), n = this.od.reduce((d, f) => d + f.$t(), 0), a = n - 30 * (this.od.length - 1); 4502 e = Math.min(a, Math.max(30, e)); 4503 const o = r / n, l = i.$t(); 4504 i.O_(e * o); 4505 let h = e - l, c = this.od.length - 1; 4506 for (const d of this.od) 4507 if (d !== i) { 4508 const f = Math.min(a, Math.max(30, d.$t() - h / c)); 4509 h -= d.$t() - f, c -= 1; 4510 const m = f * o; 4511 d.O_(m); 4512 } 4513 this.Pa(); 4514 } 4515 Ed(t, e) { 4516 et(t >= 0 && t < this.od.length && e >= 0 && e < this.od.length, "Invalid pane index"); 4517 const i = this.od[t], r = this.od[e]; 4518 this.od[t] = r, this.od[e] = i, this.Pa(); 4519 } 4520 Ad(t, e) { 4521 if (et(t >= 0 && t < this.od.length && e >= 0 && e < this.od.length, "Invalid pane index"), t === e) 4522 return; 4523 const [i] = this.od.splice(t, 1); 4524 this.od.splice(e, 0, i), this.Pa(); 4525 } 4526 G_(t, e, i) { 4527 t.G_(e, i); 4528 } 4529 X_(t, e, i) { 4530 t.X_(e, i), this.Ra(), this.Cd(this.Ld(t, 2)); 4531 } 4532 J_(t, e) { 4533 t.J_(e), this.Cd(this.Ld(t, 2)); 4534 } 4535 Q_(t, e, i) { 4536 e.Eo() || t.Q_(e, i); 4537 } 4538 tu(t, e, i) { 4539 e.Eo() || (t.tu(e, i), this.Ra(), this.Cd(this.Ld(t, 2))); 4540 } 4541 iu(t, e) { 4542 e.Eo() || (t.iu(e), this.Cd(this.Ld(t, 2))); 4543 } 4544 eu(t, e) { 4545 t.eu(e), this.Cd(this.Ld(t, 2)); 4546 } 4547 zd(t) { 4548 this.ia.l_(t); 4549 } 4550 Od(t, e) { 4551 const i = this.Et(); 4552 if (i.Gi() || e === 0) 4553 return; 4554 const r = i.nn(); 4555 t = Math.max(1, Math.min(t, r)), i.Fc(t, e), this.Bc(); 4556 } 4557 Nd(t) { 4558 this.Fd(0), this.Wd(t), this.Hd(); 4559 } 4560 Ud(t) { 4561 this.ia.o_(t), this.Bc(); 4562 } 4563 $d() { 4564 this.ia.__(), this.mr(); 4565 } 4566 Fd(t) { 4567 this.ia.u_(t); 4568 } 4569 Wd(t) { 4570 this.ia.c_(t), this.Bc(); 4571 } 4572 Hd() { 4573 this.ia.d_(), this.mr(); 4574 } 4575 Jn() { 4576 return this._d; 4577 } 4578 Wn() { 4579 return this.ud === null && (this.ud = this._d.filter((t) => t.It())), this.ud; 4580 } 4581 ka() { 4582 this.ud = null; 4583 } 4584 jd(t, e, i, r, n) { 4585 this.Ct.In(t, e); 4586 let a = NaN, o = this.ia.Rc(t, true); 4587 const l = this.ia.Ee(); 4588 l !== null && (o = Math.min(Math.max(l.Oa(), o), l.bi())), o = this.Ct.Fn(o); 4589 const h = r.Pn(), c = h.Lt(); 4590 if (c !== null && (a = h.Tn(e, c)), a = this.Md.xl(a, o, r), this.Ct.An(o, a, r), this.qa(), !n) { 4591 const d = Wn(r, t, e); 4592 this.kd(d && { lu: d.lu, wu: d.wu, mu: d.mu || null, ee: d.ee }), this.pd.p(this.Ct.Bt(), { x: t, y: e }, i); 4593 } 4594 } 4595 qd(t, e, i) { 4596 const r = i.Pn(), n = r.Lt(), a = r.Nt(t, k(n)), o = this.ia.vc(e, true), l = this.ia.jt(k(o)); 4597 this.jd(l, a, null, i, true); 4598 } 4599 Yd(t) { 4600 this.Rd().zn(), this.qa(), t || this.pd.p(null, null, null); 4601 } 4602 Ra() { 4603 const t = this.Ct.Kn(); 4604 if (t !== null) { 4605 const e = this.Ct.Bn(), i = this.Ct.En(); 4606 this.jd(e, i, null, t); 4607 } 4608 this.Ct.Nn(); 4609 } 4610 Kd(t, e, i) { 4611 const r = this.ia.Rn(0); 4612 e !== void 0 && i !== void 0 && this.ia.kt(e, i); 4613 const n = this.ia.Rn(0), a = this.ia.Pc(), o = this.ia.Ee(); 4614 if (o !== null && r !== null && n !== null) { 4615 const l = o.ze(a), h = this.xu.key(r) > this.xu.key(n), c = t !== null && t > a && !h, d = this.ia.N().allowShiftVisibleRangeOnWhitespaceReplacement, f = l && (i !== void 0 || d) && this.ia.N().shiftVisibleRangeOnNewBar; 4616 if (c && !f) { 4617 const m = t - a; 4618 this.ia.gs(this.ia.Ac() - m); 4619 } 4620 } 4621 this.ia.Nc(t); 4622 } 4623 Va(t) { 4624 t !== null && t.hu(); 4625 } 4626 Ks(t) { 4627 if ((function(i) { 4628 return i instanceof cs; 4629 })(t)) 4630 return t; 4631 const e = this.od.find((i) => i.Dt().includes(t)); 4632 return e === void 0 ? null : e; 4633 } 4634 Bc() {
4635 this.od.forEach((t) => t.hu()), this.Ra(); 4636 } 4637 m() { 4638 this.od.forEach((t) => t.m()), this.od.length = 0, this.yn.localization.priceFormatter = void 0, this.yn.localization.percentageFormatter = void 0, this.yn.localization.timeFormatter = void 0; 4639 } 4640 Zd() { 4641 return this.wd; 4642 } 4643 Js() { 4644 return this.wd.N(); 4645 } 4646 L_() { 4647 return this.fd; 4648 } 4649 Gd(t, e) { 4650 const i = this.gd(e); 4651 this.Xd(t, i), this._d.push(t), this.ka(), this._d.length === 1 ? this.Pa() : this.mr(); 4652 } 4653 Jd(t) { 4654 const e = this.Ks(t), i = this._d.indexOf(t); 4655 et(i !== -1, "Series not found"); 4656 const r = k(e); 4657 this._d.splice(i, 1), r.r_(t), t.m && t.m(), this.ka(), this.ia._c(), this.Qd(r); 4658 } 4659 ya(t, e) { 4660 const i = k(this.Ks(t)); 4661 i.r_(t, true), i.s_(t, e, true); 4662 } 4663 Xc() { 4664 const t = tt.Cs(); 4665 t.us(), this.Cd(t); 4666 } 4667 tf(t) { 4668 const e = tt.Cs(); 4669 e.fs(t), this.Cd(e); 4670 } 4671 ws() { 4672 const t = tt.Cs(); 4673 t.ws(), this.Cd(t); 4674 } 4675 Ms(t) { 4676 const e = tt.Cs(); 4677 e.Ms(t), this.Cd(e); 4678 } 4679 gs(t) { 4680 const e = tt.Cs(); 4681 e.gs(t), this.Cd(e); 4682 } 4683 ps(t) { 4684 const e = tt.Cs(); 4685 e.ps(t), this.Cd(e); 4686 } 4687 cs() { 4688 const t = tt.Cs(); 4689 t.cs(), this.Cd(t); 4690 } 4691 if() { 4692 const t = this.yn.defaultVisiblePriceScaleId, e = this.yn.leftPriceScale.visible; 4693 return e !== this.yn.rightPriceScale.visible ? e ? "left" : "right" : t; 4694 } 4695 nf(t, e) { 4696 if (et(e >= 0, "Index should be greater or equal to 0"), e === this.sf(t)) 4697 return; 4698 const i = k(this.Ks(t)); 4699 i.r_(t); 4700 const r = this.gd(e); 4701 this.Xd(t, r); 4702 let n = false; 4703 i.Cl().length === 0 && (n = this.Qd(i)), n || this.Pa(); 4704 } 4705 ef() { 4706 return this.xd; 4707 } 4708 $() { 4709 return this.bd; 4710 } 4711 Ut(t) { 4712 const e = this.xd, i = this.bd; 4713 if (e === i) 4714 return e; 4715 if (t = Math.max(0, Math.min(100, Math.round(100 * t))), this.vd === null || this.vd.ah !== i || this.vd.oh !== e) 4716 this.vd = { ah: i, oh: e, rf: /* @__PURE__ */ new Map() }; 4717 else { 4718 const n = this.vd.rf.get(t); 4719 if (n !== void 0) 4720 return n; 4721 } 4722 const r = this.To.tt(i, e, t / 100); 4723 return this.vd.rf.set(t, r), r; 4724 } 4725 hf(t) { 4726 return this.od.indexOf(t); 4727 } 4728 Xi() { 4729 return this.To; 4730 } 4731 af() { 4732 return this.lf(); 4733 } 4734 lf(t) { 4735 const e = new cs(this.ia, this); 4736 this.od.push(e); 4737 const i = t != null ? t : this.od.length - 1, r = tt.ys(); 4738 return r.es(i, { rs: 0, hs: true }), this.Cd(r), e; 4739 } 4740 gd(t) { 4741 return et(t >= 0, "Index should be greater or equal to 0"), (t = Math.min(this.od.length, t)) < this.od.length ? this.od[t] : this.lf(t); 4742 } 4743 sf(t) { 4744 return this.od.findIndex((e) => e.U_().includes(t)); 4745 } 4746 Ld(t, e) { 4747 const i = new tt(e); 4748 if (t !== null) { 4749 const r = this.od.indexOf(t); 4750 i.es(r, { rs: e }); 4751 } 4752 return i; 4753 } 4754 yd(t, e) { 4755 return e === void 0 && (e = 2), this.Ld(this.Ks(t), e); 4756 } 4757 Cd(t) { 4758 this.md && this.md(t), this.od.forEach((e) => e.pu().wr().kt()); 4759 } 4760 Xd(t, e) { 4761 const i = t.N().priceScaleId, r = i !== void 0 ? i : this.if(); 4762 e.s_(t, r), xi(r) || t.vr(t.N()); 4763 } 4764 Sd(t) { 4765 const e = this.yn.layout; 4766 return e.background.type === "gradient" ? t === 0 ? e.background.topColor : e.background.bottomColor : e.background.color; 4767 } 4768 Qd(t) { 4769 return !t.H_() && t.Cl().length === 0 && this.od.length > 1 && (this.od.splice(this.hf(t), 1), this.Pa(), true); 4770 } 4771 }; 4772 function Qn(s) { 4773 if (s >= 1) 4774 return 0; 4775 let t = 0; 4776 for (; t < 8; t++) { 4777 const e = Math.round(s); 4778 if (Math.abs(e - s) < 1e-8) 4779 return t; 4780 s *= 10; 4781 } 4782 return t; 4783 } 4784 function us(s) { 4785 return !ve(s) && !Ve(s); 4786 } 4787 function Yn(s) { 4788 return ve(s); 4789 } 4790 (function(s) { 4791 s[s.Disabled = 0] = "Disabled", s[s.Continuous = 1] = "Continuous", s[s.OnDataUpdate = 2] = "OnD
4791ataUpdate"; 4792 })(Ar || (Ar = {})), (function(s) { 4793 s[s.LastBar = 0] = "LastBar", s[s.LastVisible = 1] = "LastVisible"; 4794 })(Tr || (Tr = {})), (function(s) { 4795 s.Solid = "solid", s.VerticalGradient = "gradient"; 4796 })(Ir || (Ir = {})), (function(s) { 4797 s[s.Year = 0] = "Year", s[s.Month = 1] = "Month", s[s.DayOfMonth = 2] = "DayOfMonth", s[s.Time = 3] = "Time", s[s.TimeWithSeconds = 4] = "TimeWithSeconds"; 4798 })(Rr || (Rr = {})); 4799 var Lr = (s) => s.getUTCFullYear(); 4800 function il(s, t, e) { 4801 return t.replace(/yyyy/g, ((i) => Ft(Lr(i), 4))(s)).replace(/yy/g, ((i) => Ft(Lr(i) % 100, 2))(s)).replace(/MMMM/g, ((i, r) => new Date(i.getUTCFullYear(), i.getUTCMonth(), 1).toLocaleString(r, { month: "long" }))(s, e)).replace(/MMM/g, ((i, r) => new Date(i.getUTCFullYear(), i.getUTCMonth(), 1).toLocaleString(r, { month: "short" }))(s, e)).replace(/MM/g, ((i) => Ft(((r) => r.getUTCMonth() + 1)(i), 2))(s)).replace(/dd/g, ((i) => Ft(((r) => r.getUTCDate())(i), 2))(s)); 4802 } 4803 var Kn = class { 4804 constructor(t = "yyyy-MM-dd", e = "default") { 4805 this._f = t, this.uf = e; 4806 } 4807 Cu(t) { 4808 return il(t, this._f, this.uf); 4809 } 4810 }; 4811 var sl = class { 4812 constructor(t) { 4813 this.cf = t || "%h:%m:%s"; 4814 } 4815 Cu(t) { 4816 return this.cf.replace("%h", Ft(t.getUTCHours(), 2)).replace("%m", Ft(t.getUTCMinutes(), 2)).replace("%s", Ft(t.getUTCSeconds(), 2)); 4817 } 4818 }; 4819 var rl = { df: "yyyy-MM-dd", ff: "%h:%m:%s", pf: " ", vf: "default" }; 4820 var nl = class { 4821 constructor(t = {}) { 4822 const e = M(M({}, rl), t); 4823 this.mf = new Kn(e.df, e.vf), this.wf = new sl(e.ff), this.Mf = e.pf; 4824 } 4825 Cu(t) { 4826 return `${this.mf.Cu(t)}${this.Mf}${this.wf.Cu(t)}`; 4827 } 4828 }; 4829 function ti(s) { 4830 return 60 * s * 60 * 1e3; 4831 } 4832 function ji(s) { 4833 return 60 * s * 1e3; 4834 } 4835 var ei = [{ gf: (Nr = 1, 1e3 * Nr), bf: 10 }, { gf: ji(1), bf: 20 }, { gf: ji(5), bf: 21 }, { gf: ji(30), bf: 22 }, { gf: ti(1), bf: 30 }, { gf: ti(3), bf: 31 }, { gf: ti(6), bf: 32 }, { gf: ti(12), bf: 33 }]; 4836 var Nr; 4837 function Br(s, t) { 4838 if (s.getUTCFullYear() !== t.getUTCFullYear()) 4839 return 70; 4840 if (s.getUTCMonth() !== t.getUTCMonth()) 4841 return 60; 4842 if (s.getUTCDate() !== t.getUTCDate()) 4843 return 50; 4844 for (let e = ei.length - 1; e >= 0; --e) 4845 if (Math.floor(t.getTime() / ei[e].gf) !== Math.floor(s.getTime() / ei[e].gf)) 4846 return ei[e].bf; 4847 return 0; 4848 } 4849 function Hi(s) { 4850 let t = s; 4851 if (Ve(s) && (t = As(s)), !us(t)) 4852 throw new Error("time must be of type BusinessDay"); 4853 const e = new Date(Date.UTC(t.year, t.month - 1, t.day, 0, 0, 0, 0)); 4854 return { Sf: Math.round(e.getTime() / 1e3), xf: t }; 4855 } 4856 function Or(s) { 4857 if (!Yn(s)) 4858 throw new Error("time must be of type isUTCTimestamp"); 4859 return { Sf: s }; 4860 } 4861 function As(s) { 4862 const t = new Date(s); 4863 if (isNaN(t.getTime())) 4864 throw new Error(`Invalid date string=${s}, expected format=yyyy-mm-dd`); 4865 return { day: t.getUTCDate(), month: t.getUTCMonth() + 1, year: t.getUTCFullYear() }; 4866 } 4867 function qr(s) { 4868 Ve(s.time) && (s.time = As(s.time)); 4869 } 4870 var Ur = class { 4871 options() { 4872 return this.yn; 4873 } 4874 setOptions(t) { 4875 this.yn = t, this.updateFormatter(t.localization); 4876 } 4877 preprocessData(t) { 4878 Array.isArray(t) ? (function(e) { 4879 e.forEach(qr); 4880 })(t) : qr(t); 4881 } 4882 createConverterToInternalObj(t) { 4883 return k((function(e) { 4884 return e.length === 0 ? null : us(e[0].time) || Ve(e[0].time) ? Hi : Or; 4885 })(t)); 4886 } 4887 key(t) { 4888 return typeof t == "object" && "Sf" in t ? t.Sf : this.key(this.convertHorzItemToInternal(t)); 4889 } 4890 cacheKey(t) { 4891 const e = t; 4892 return e.xf === void 0 ? new Date(1e3 * e.Sf).getTime() : new Date(Date.UTC(e.xf.year, e.xf.month - 1, e.xf.day)).getTime(); 4893 } 4894 convertHorzItemToInternal(t) { 4895 return Yn(e = t) ? Or(e) : us(e) ? Hi(e) : Hi(As(e)); 4896 var e; 4897 } 4898 updateFormatter(t) { 4899 if (!this.yn) 4900 return; 4901 const e = t.dateFormat; 4902 this.yn.timeScale.timeVisible ? this.Cf = new nl({ df: e, ff: this.yn.timeScale.secondsVisible ? "%h:%m:%s" : "%h:%m", pf: " ", vf: t.locale }) : this.Cf = new Kn(e, t.locale); 4903 } 4904 formatHorzItem(t) { 4905 const e = t; 4906 return this.Cf.Cu(new Date(1e3 * e.Sf)); 4907 } 4908 formatTickmark(t, e) { 4909 const i = (function(n, a, o) { 4910 switch (n) { 4911 case 0: 4912 case 10: 4913 return a ? o ? 4 : 3 : 2; 4914 case 20: 4915 case 21: 4916 case 22: 4917 case 30: 4918 case 31: 4919 case 32: 4920 case 33: 4921 return a ? 3 : 2; 4922 case 50: 4923 return 2; 4924 case 60: 4925 return 1; 4926 case 70: 4927 return 0; 4928 } 4929 })(t.weight, this.yn.timeScale.timeVisible, this.yn.timeScale.secondsVisible), r = this.yn.timeScale; 4930 if (r.tickMarkFormatter !== void 0) { 4931 const n = r.tickMarkFormatter(t.originalTime, i, e.locale); 4932 if (n !== null) 4933 return n; 4934 } 4935 return (function(n, a, o) { 4936 const l = {}; 4937 switch (a) { 4938 case 0: 4939 l.year = "numeric"; 4940 break; 4941 case 1: 4942 l.month = "short"; 4943 break; 4944 case 2: 4945 l.day = "numeric"; 4946 break; 4947 case 3: 4948 l.hour12 = false, l.hour = "2-digit", l.minute = "2-digit";
4949 break; 4950 case 4: 4951 l.hour12 = false, l.hour = "2-digit", l.minute = "2-digit", l.second = "2-digit"; 4952 } 4953 const h = n.xf === void 0 ? new Date(1e3 * n.Sf) : new Date(Date.UTC(n.xf.year, n.xf.month - 1, n.xf.day)); 4954 return new Date(h.getUTCFullYear(), h.getUTCMonth(), h.getUTCDate(), h.getUTCHours(), h.getUTCMinutes(), h.getUTCSeconds(), h.getUTCMilliseconds()).toLocaleString(o, l); 4955 })(t.time, i, e.locale); 4956 } 4957 maxTickMarkWeight(t) { 4958 let e = t.reduce(Jo, t[0]).weight; 4959 return e > 30 && e < 50 && (e = 30), e; 4960 } 4961 fillWeightsForPoints(t, e) { 4962 (function(i, r = 0) { 4963 if (i.length === 0) 4964 return; 4965 let n = r === 0 ? null : i[r - 1].time.Sf, a = n !== null ? new Date(1e3 * n) : null, o = 0; 4966 for (let l = r; l < i.length; ++l) { 4967 const h = i[l], c = new Date(1e3 * h.time.Sf); 4968 a !== null && (h.timeWeight = Br(c, a)), o += h.time.Sf - (n || h.time.Sf), n = h.time.Sf, a = c; 4969 } 4970 if (r === 0 && i.length > 1) { 4971 const l = Math.ceil(o / (i.length - 1)), h = new Date(1e3 * (i[0].time.Sf - l)); 4972 i[0].timeWeight = Br(new Date(1e3 * i[0].time.Sf), h); 4973 } 4974 })(t, e); 4975 } 4976 static yf(t) { 4977 return ft({ localization: { dateFormat: "dd MMM 'yy" } }, t != null ? t : {}); 4978 } 4979 }; 4980 var be = typeof window != "undefined"; 4981 function Vr() { 4982 return !!be && window.navigator.userAgent.toLowerCase().indexOf("firefox") > -1; 4983 } 4984 function Wi() { 4985 return !!be && /iPhone|iPad|iPod/.test(window.navigator.platform); 4986 } 4987 function al(s, t) { 4988 switch (s) { 4989 case "custom": 4990 return t !== void 0 ? "custom-object" : "series"; 4991 case "price-line": 4992 return "custom-price-line"; 4993 case "marker": 4994 return "series-marker"; 4995 case "primitive": 4996 return "primitive"; 4997 default: 4998 return "series"; 4999 } 5000 } 5001 function fs(s) { 5002 return s + s % 2; 5003 } 5004 function ol(s) { 5005 be && window.chrome !== void 0 && s.addEventListener("mousedown", (t) => { 5006 if (t.button === 1) 5007 return t.preventDefault(), false; 5008 }); 5009 } 5010 var Ci = class { 5011 constructor(t, e, i) { 5012 this.kf = 0, this.Pf = null, this.Tf = { _t: Number.NEGATIVE_INFINITY, ut: Number.POSITIVE_INFINITY }, this.Rf = 0, this.Df = null, this.If = { _t: Number.NEGATIVE_INFINITY, ut: Number.POSITIVE_INFINITY }, this.Vf = null, this.Bf = false, this.Ef = null, this.Af = null, this.Lf = false, this.zf = false, this.Of = false, this.Nf = null, this.Ff = null, this.Wf = null, this.Hf = null, this.Uf = null, this.$f = null, this.jf = null, this.qf = 0, this.Yf = false, this.Kf = false, this.Zf = false, this.Gf = 0, this.Xf = null, this.Jf = !Wi(), this.Qf = (r) => { 5013 this.tp(r); 5014 }, this.ip = (r) => { 5015 if (this.np(r)) { 5016 const n = this.sp(r); 5017 if (++this.Rf, this.Df && this.Rf > 1) { 5018 const { ep: a } = this.rp(Ct(r), this.If); 5019 a < 30 && !this.Of && this.hp(n, this.lp.ap), this.op(); 5020 } 5021 } else { 5022 const n = this.sp(r); 5023 if (++this.kf, this.Pf && this.kf > 1) { 5024 const { ep: a } = this.rp(Ct(r), this.Tf); 5025 a < 5 && !this.zf && this._p(n, this.lp.up), this.cp(); 5026 } 5027 } 5028 }, this.dp = t, this.lp = e, this.yn = i, this.fp(); 5029 } 5030 m() { 5031 this.Nf !== null && (this.Nf(), this.Nf = null), this.Ff !== null && (this.Ff(), this.Ff = null), this.Hf !== null && (this.Hf(), this.Hf = null), this.Uf !== null && (this.Uf(), this.Uf = null), this.$f !== null && (this.$f(), this.$f = null), this.Wf !== null && (this.Wf(), this.Wf = null), this.pp(), this.cp(); 5032 } 5033 vp(t) { 5034 this.Hf && this.Hf(); 5035 const e = this.mp.bind(this); 5036 if (this.Hf = () => { 5037 this.dp.removeEventListener("mousemove", e); 5038 }, this.dp.addEventListener("mousemove", e), this.np(t)) 5039 return; 5040 const i = this.sp(t); 5041 this._p(i, this.lp.wp), this.Jf = true; 5042 } 5043 cp() { 5044 this.Pf !== null && clearTimeout(this.Pf), this.kf = 0, this.Pf = null, this.Tf = { _t: Number.NEGATIVE_INFINITY, ut: Number.POSITIVE_INFINITY }; 5045 } 5046 op() { 5047 this.Df !== null && clearTimeout(this.Df), this.Rf = 0, this.Df = null, this.If = { _t: Number.NEGATIVE_INFINITY, ut: Number.POSITIVE_INFINITY }; 5048 } 5049 mp(t) { 5050 if (this.Zf || this.Af !== null || this.np(t)) 5051 return; 5052 const e = this.sp(t); 5053 this._p(e, this.lp.Mp), this.Jf = true; 5054 } 5055 gp(t) { 5056 const e = Qi(t.changedTouches, k(this.Xf)); 5057 if (e === null || (this.Gf = ii(t), this.jf !== null) || this.Kf) 5058 return; 5059 this.Yf = true; 5060 const i = this.rp(Ct(e), k(this.Af)), { bp: r, Sp: n, ep: a } = i; 5061 if (this.Lf || !(a < 5)) { 5062 if (!this.Lf) { 5063 const o = 0.5 * r, l = n >= o && !this.yn.xp(), h = o > n && !this.yn.Cp(); 5064 l || h || (this.Kf = true), this.Lf = true, this.Of = true, this.pp(), this.op(); 5065 } 5066 if (!this.Kf) { 5067 const o = this.sp(t, e); 5068 this.hp(o, this.lp.yp), le(t); 5069 } 5070 } 5071 } 5072 kp(t) { 5073 if (t.button !== 0) 5074 return; 5075 const e = this.rp(Ct(t), k(this.Ef)), { ep: i } = e; 5076 if (i >= 5 && (this.zf = true, this.cp()), this.zf) { 5077 const r = this.sp(t); 5078 this._p(r, this.lp.Pp); 5079 } 5080 } 5081 rp(t, e) { 5082 const i = Math.abs(e._t - t._t), r = Math.abs(e.ut - t.ut); 5083 return { bp: i, Sp: r, ep: i + r }; 5084 } 5085 Tp(t) { 5086 let e = Qi(t.changedTouches, k(this.Xf)); 5087 if (e === null && t.touches.length === 0 && (e = t.changedTouches[0]), e === null) 5088 return; 5089 this.Xf = null, this.Gf = ii(t), this.pp(), this.Af = null, this.$f && (this.$f(), this.$f = null); 5090 const i = this.sp(t, e); 5091 if (this.hp(i, this.lp.Rp), ++this.Rf, this.Df && this.Rf > 1) { 5092 const { ep: r } = this.rp(Ct(e), this.If); 5093 r < 30 && !this.Of && this.hp(i, this.lp.ap), this.op(); 5094 } else 5095 this.Of || (this.hp(i, this.lp.Dp), this.lp.Dp && le(t)); 5096 this.Rf === 0 && le(t), t.touches.length === 0 && this.Bf && (this.Bf = false, le(t)); 5097 } 5098 tp(t) { 5099 if (t.button !== 0) 5100 return; 5101 const e = this.sp(t); 5102 if (this.Ef = null, this.Zf = false, this.Uf && (this.Uf(), this.Uf = null), Vr() && this.dp.ownerDocument.documentElement.removeEventListener("mouseleave", this.Qf), !this.np(t)) 5103 if (this._p(e, this.lp.Ip), ++this.kf, this.Pf && this.kf > 1) { 5104 const { ep: i } = this.rp(Ct(t), this.Tf); 5105 i < 5 && !this.zf && this._p(e, this.lp.up), this.cp(); 5106 } else 5107 this.zf || this._p(e, this.lp.Vp); 5108 } 5109 pp() { 5110 this.Vf !== null && (clearTimeout(this.Vf), this.Vf = null); 5111 } 5112 Bp(t) { 5113 if (this.Xf !== null) 5114 return; 5115 const e = t.changedTouches[0]; 5116 this.Xf = e.identifier, this.Gf = ii(t); 5117 const i = this.dp.ownerDocument.documentElement; 5118 this.Of = false, this.Lf = false, this.Kf = false, this.Af = Ct(e), this.$f && (this.$f(), this.$f = null); 5119 { 5120 const n = this.gp.bind(this), a = this.Tp.bind(this); 5121 this.$f = () => { 5122 i.removeEventListener("touchmove", n), i.removeEventListener("touchend", a); 5123 }, i.addEventListener("touchmove", n, { passive: false }), i.addEventListener("touchend", a, { passive: false }), this.pp(), this.Vf = setTimeout(this.Ep.bind(this, t), 240); 5124 } 5125 const r = this.sp(t, e); 5126 this.hp(r, this.lp.Ap), this.Df || (this.Rf = 0, this.Df = setTimeout(this.op.bind(this), 500), this.If = Ct(e)); 5127 } 5128 Lp(t) { 5129 if (t.button !== 0) 5130 return; 5131 const e = this.dp.ownerDocument.documentElement; 5132 Vr() && e.addEventListener("mouseleave", this.Qf), this.zf = false, this.Ef = Ct(t), this.Uf && (this.Uf(), this.Uf = null); 5133 { 5134 const r = this.kp.bind(this), n = this.tp.bind(this); 5135 this.Uf = () => { 5136 e.removeEventListener("mousemove", r), e.removeEventListener("mouseup", n); 5137 }, e.addEventListener("mousemove", r), e.addEventListener("mouseup", n); 5138 } 5139 if (this.Zf = true, this.np(t)) 5140 return; 5141 const i = this.sp(t); 5142 this._p(i, this.lp.zp), this.Pf || (this.kf = 0, this.Pf = setTimeout(this.cp.bind(this), 500), this.Tf = Ct(t)); 5143 } 5144 fp() { 5145 this.dp.addEventListener("mouseenter", this.vp.bind(this)), this.dp.addEventListener("touchcancel", this.pp.bind(this)); 5146 { 5147 const t = this.dp.ownerDocument, e = (i) => {
5148 this.lp.Op && (i.composed && this.dp.contains(i.composedPath()[0]) || i.target && this.dp.contains(i.target) || this.lp.Op()); 5149 }; 5150 this.Ff = () => { 5151 t.removeEventListener("touchstart", e); 5152 }, this.Nf = () => { 5153 t.removeEventListener("mousedown", e); 5154 }, t.addEventListener("mousedown", e), t.addEventListener("touchstart", e, { passive: true }); 5155 } 5156 Wi() && (this.Wf = () => { 5157 this.dp.removeEventListener("dblclick", this.ip); 5158 }, this.dp.addEventListener("dblclick", this.ip)), this.dp.addEventListener("mouseleave", this.Np.bind(this)), this.dp.addEventListener("touchstart", this.Bp.bind(this), { passive: true }), ol(this.dp), this.dp.addEventListener("mousedown", this.Lp.bind(this)), this.Fp(), this.dp.addEventListener("touchmove", () => { 5159 }, { passive: false }); 5160 } 5161 Fp() { 5162 this.lp.Wp === void 0 && this.lp.Hp === void 0 && this.lp.Up === void 0 || (this.dp.addEventListener("touchstart", (t) => this.$p(t.touches), { passive: true }), this.dp.addEventListener("touchmove", (t) => { 5163 if (t.touches.length === 2 && this.jf !== null && this.lp.Hp !== void 0) { 5164 const e = jr(t.touches[0], t.touches[1]) / this.qf; 5165 this.lp.Hp(this.jf, e), le(t); 5166 } 5167 }, { passive: false }), this.dp.addEventListener("touchend", (t) => { 5168 this.$p(t.touches); 5169 })); 5170 } 5171 $p(t) { 5172 t.length === 1 && (this.Yf = false), t.length !== 2 || this.Yf || this.Bf ? this.jp() : this.qp(t); 5173 } 5174 qp(t) { 5175 const e = this.dp.getBoundingClientRect() || { left: 0, top: 0 }; 5176 this.jf = { _t: (t[0].clientX - e.left + (t[1].clientX - e.left)) / 2, ut: (t[0].clientY - e.top + (t[1].clientY - e.top)) / 2 }, this.qf = jr(t[0], t[1]), this.lp.Wp !== void 0 && this.lp.Wp(), this.pp(); 5177 } 5178 jp() { 5179 this.jf !== null && (this.jf = null, this.lp.Up !== void 0 && this.lp.Up()); 5180 } 5181 Np(t) { 5182 if (this.Hf && this.Hf(), this.np(t) || !this.Jf) 5183 return; 5184 const e = this.sp(t); 5185 this._p(e, this.lp.Yp), this.Jf = !Wi(); 5186 } 5187 Ep(t) { 5188 const e = Qi(t.touches, k(this.Xf)); 5189 if (e === null) 5190 return; 5191 const i = this.sp(t, e); 5192 this.hp(i, this.lp.Kp), this.Of = true, this.Bf = true; 5193 } 5194 np(t) { 5195 return t.sourceCapabilities && t.sourceCapabilities.firesTouchEvents !== void 0 ? t.sourceCapabilities.firesTouchEvents : ii(t) < this.Gf + 500; 5196 } 5197 hp(t, e) { 5198 e && e.call(this.lp, t); 5199 } 5200 _p(t, e) { 5201 e && e.call(this.lp, t); 5202 } 5203 sp(t, e) { 5204 const i = e || t, r = this.dp.getBoundingClientRect() || { left: 0, top: 0 }; 5205 return { clientX: i.clientX, clientY: i.clientY, pageX: i.pageX, pageY: i.pageY, screenX: i.screenX, screenY: i.screenY, localX: i.clientX - r.left, localY: i.clientY - r.top, ctrlKey: t.ctrlKey, altKey: t.altKey, shiftKey: t.shiftKey, metaKey: t.metaKey, Zp: !t.type.startsWith("mouse") && t.type !== "contextmenu" && t.type !== "click", Gp: t.type, Xp: i.target, gu: t.view, Jp: () => { 5206 t.type !== "touchstart" && le(t); 5207 } }; 5208 } 5209 }; 5210 function jr(s, t) { 5211 const e = s.clientX - t.clientX, i = s.clientY - t.clientY; 5212 return Math.sqrt(e * e + i * i); 5213 } 5214 function le(s) { 5215 s.cancelable && s.preventDefault(); 5216 } 5217 function Ct(s) { 5218 return { _t: s.pageX, ut: s.pageY }; 5219 } 5220 function ii(s) { 5221 return s.timeStamp || performance.now(); 5222 } 5223 function Qi(s, t) { 5224 for (let e = 0; e < s.length; ++e) 5225 if (s[e].identifier === t) 5226 return s[e]; 5227 return null; 5228 } 5229 var ll = class { 5230 constructor(t, e, i) { 5231 this.Qp = null, this.tv = null, this.iv = true, this.nv = null, this.sv = t, this.ev = t.rv()[e], this.hv = t.rv()[i], this.av = document.createElement("tr"), this.av.style.height = "1px", this.lv = document.createElement("td"), this.lv.style.position = "relative", this.lv.style.padding = "0", this.lv.style.margin = "0", this.lv.setAttribute("colspan", "3"), this.ov(), this.av.appendChild(this.lv), this.iv = this.sv.N().layout.panes.enableResize, this.iv ? this._v() : (this.Qp = null, this.tv = null); 5232 } 5233 m() { 5234 this.tv !== null && this.tv.m(); 5235 } 5236 uv() { 5237 return this.av; 5238 } 5239 cv() { 5240 return B({ width: this.ev.cv().width, height: 1 }); 5241 } 5242 dv() { 5243 return B({ width: this.ev.dv().width, height: 1 * window.devicePixelRatio }); 5244 } 5245 fv(t, e, i) { 5246 const r = this.dv(); 5247 t.fillStyle = this.sv.N().layout.panes.separatorColor, t.fillRect(e, i, r.width, r.height); 5248 } 5249 kt() { 5250 this.ov(), this.sv.N().layout.panes.enableResize !== this.iv && (this.iv = this.sv.N().layout.panes.enableResize, this.iv ? this._v() : (this.Qp !== null && (this.lv.removeChild(this.Qp.pv), this.lv.removeChild(this.Qp.vv), this.Qp = null), this.tv !== null && (this.tv.m(), this.tv = null))); 5251 } 5252 _v() { 5253 const t = document.createElement("div"), e = t.style; 5254 e.position = "fixed", e.display = "none", e.zIndex = "49", e.top = "0", e.left = "0", e.width = "100%", e.height = "100%", e.cursor = "row-resize", this.lv.appendChild(t); 5255 const i = document.createElement("div"), r = i.style; 5256 r.position = "absolute", r.zIndex = "50", r.top = "-4px", r.he
5256ight = "9px", r.width = "100%", r.backgroundColor = "", r.cursor = "row-resize", this.lv.appendChild(i); 5257 const n = { wp: this.mv.bind(this), Yp: this.wv.bind(this), zp: this.Mv.bind(this), Ap: this.Mv.bind(this), Pp: this.gv.bind(this), yp: this.gv.bind(this), Ip: this.bv.bind(this), Rp: this.bv.bind(this) }; 5258 this.tv = new Ci(i, n, { xp: () => false, Cp: () => true }), this.Qp = { vv: i, pv: t }; 5259 } 5260 ov() { 5261 this.lv.style.background = this.sv.N().layout.panes.separatorColor; 5262 } 5263 mv(t) { 5264 this.Qp !== null && (this.Qp.vv.style.backgroundColor = this.sv.N().layout.panes.separatorHoverColor); 5265 } 5266 wv(t) { 5267 this.Qp !== null && this.nv === null && (this.Qp.vv.style.backgroundColor = ""); 5268 } 5269 Mv(t) { 5270 if (this.Qp === null) 5271 return; 5272 const e = this.ev.Sv().z_() + this.hv.Sv().z_(), i = e / (this.ev.cv().height + this.hv.cv().height), r = 30 * i; 5273 e <= 2 * r || (this.nv = { xv: t.pageY, Cv: this.ev.Sv().z_(), yv: e - r, kv: e, Pv: i, Tv: r }, this.Qp.pv.style.display = "block"); 5274 } 5275 gv(t) { 5276 const e = this.nv; 5277 if (e === null) 5278 return; 5279 const i = (t.pageY - e.xv) * e.Pv, r = fe(e.Cv + i, e.Tv, e.yv); 5280 this.ev.Sv().O_(r), this.hv.Sv().O_(e.kv - r), this.sv.Qt().Pa(); 5281 } 5282 bv(t) { 5283 this.nv !== null && this.Qp !== null && (this.nv = null, this.Qp.pv.style.display = "none"); 5284 } 5285 }; 5286 function Yi(s, t) { 5287 return s.Rv - t.Rv; 5288 } 5289 function Ki(s, t, e) { 5290 const i = (s.Rv - t.Rv) / (s.wt - t.wt); 5291 return Math.sign(i) * Math.min(Math.abs(i), e); 5292 } 5293 var hl = class { 5294 constructor(t, e, i, r) { 5295 this.Dv = null, this.Iv = null, this.Vv = null, this.Bv = null, this.Ev = null, this.Av = 0, this.Lv = 0, this.zv = t, this.Ov = e, this.Nv = i, this.ks = r; 5296 } 5297 Fv(t, e) { 5298 if (this.Dv !== null) { 5299 if (this.Dv.wt === e) 5300 return void (this.Dv.Rv = t); 5301 if (Math.abs(this.Dv.Rv - t) < this.ks) 5302 return; 5303 } 5304 this.Bv = this.Vv, this.Vv = this.Iv, this.Iv = this.Dv, this.Dv = { wt: e, Rv: t }; 5305 } 5306 me(t, e) { 5307 if (this.Dv === null || this.Iv === null || e - this.Dv.wt > 50) 5308 return; 5309 let i = 0; 5310 const r = Ki(this.Dv, this.Iv, this.Ov), n = Yi(this.Dv, this.Iv), a = [r], o = [n]; 5311 if (i += n, this.Vv !== null) { 5312 const h = Ki(this.Iv, this.Vv, this.Ov); 5313 if (Math.sign(h) === Math.sign(r)) { 5314 const c = Yi(this.Iv, this.Vv); 5315 if (a.push(h), o.push(c), i += c, this.Bv !== null) { 5316 const d = Ki(this.Vv, this.Bv, this.Ov); 5317 if (Math.sign(d) === Math.sign(r)) { 5318 const f = Yi(this.Vv, this.Bv); 5319 a.push(d), o.push(f), i += f; 5320 } 5321 } 5322 } 5323 } 5324 let l = 0; 5325 for (let h = 0; h < a.length; ++h) 5326 l += o[h] / i * a[h]; 5327 Math.abs(l) < this.zv || (this.Ev = { Rv: t, wt: e }, this.Lv = l, this.Av = (function(h, c) { 5328 const d = Math.log(c); 5329 return Math.log(1 * d / -h) / d; 5330 })(Math.abs(l), this.Nv)); 5331 } 5332 qc(t) { 5333 const e = k(this.Ev), i = t - e.wt; 5334 return e.Rv + this.Lv * (Math.pow(this.Nv, i) - 1) / Math.log(this.Nv); 5335 } 5336 jc(t) { 5337 return this.Ev === null || this.Wv(t) === this.Av; 5338 } 5339 Wv(t) { 5340 const e = t - k(this.Ev).wt; 5341 return Math.min(e, this.Av); 5342 } 5343 }; 5344 var cl = class { 5345 constructor(t, e) { 5346 this.Hv = void 0, this.Uv = void 0, this.$v = void 0, this.vn = false, this.jv = t, this.qv = e, this.Yv(); 5347 } 5348 kt() { 5349 this.Yv(); 5350 } 5351 Kv() { 5352 this.Hv && this.jv.removeChild(this.Hv), this.Uv && this.jv.removeChild(this.Uv), this.Hv = void 0, this.Uv = void 0; 5353 } 5354 Zv() { 5355 return this.vn !== this.Gv() || this.$v !== this.Xv(); 5356 } 5357 Xv() { 5358 return this.qv.Qt().Xi().J(this.qv.N().layout.textColor) > 160 ? "dark" : "light"; 5359 } 5360 Gv() { 5361 return this.qv.N().layout.attributionLogo; 5362 } 5363 Jv() { 5364 const t = new URL(location.href); 5365 return t.hostname ? "&utm_source=" + t.hostname + t.pathname : ""; 5366 } 5367 Yv() { 5368 this.Zv() && (this.Kv(), this.vn = this.Gv(), this.vn && (this.$v = this.Xv(), this.Uv = document.createElement("style"), this.Uv.innerText = "a#tv-attr-logo{--fill:#131722;--stroke:#fff;position:absolute;
5368left:10px;bottom:10px;height:19px;width:35px;margin:0;padding:0;border:0;z-index:3;}a#tv-attr-logo[data-dark]{--fill:#D1D4DC;--stroke:#131722;}", this.Hv = document.createElement("a"), this.Hv.href = `https://www.tradingview.com/?utm_medium=lwc-link&utm_campaign=lwc-chart${this.Jv()}`, this.Hv.title = "Charting by TradingView", this.Hv.id = "tv-attr-logo", this.Hv.target = "_blank", this.Hv.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="35" height="19" fill="none"><g fill-rule="evenodd" clip-path="url(#a)" clip-rule="evenodd"><path fill="var(--stroke)" d="M2 0H0v10h6v9h21.4l.5-1.3 6-15 1-2.7H23.7l-.5 1.3-.2.6a5 5 0 0 0-7-.9V0H2Zm20 17h4l5.2-13 .8-2h-7l-1 2.5-.2.5-1.5 3.8-.3.7V17Zm-.8-10a3 3 0 0 0 .7-2.7A3 3 0 1 0 16.8 7h4.4ZM14 7V2H2v6h6v9h4V7h2Z"/><path fill="var(--fill)" d="M14 2H2v6h6v9h6V2Zm12 15h-7l6-15h7l-6 15Zm-7-9a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/></g><defs><clipPath id="a"><path fill="var(--stroke)" d="M0 0h35v19H0z"/></clipPath></defs></svg>', this.Hv.toggleAttribute("data-dark", this.$v === "dark"), this.jv.appendChild(this.Uv), this.jv.appendChild(this.Hv))); 5369 } 5370 }; 5371 function se(s, t) { 5372 const e = k(s.ownerDocument).createElement("canvas"); 5373 s.appendChild(e); 5374 const i = Wa(e, { type: "device-pixel-content-box", options: { allowResizeObserver: true }, transform: (r, n) => ({ width: Math.max(r.width, n.width), height: Math.max(r.height, n.height) }) }); 5375 return i.resizeCanvasElement(t), i; 5376 } 5377 function re(s) { 5378 var t; 5379 s.width = 1, s.height = 1, (t = s.getContext("2d")) == null || t.clearRect(0, 0, 1, 1); 5380 } 5381 function ms(s, t, e, i) { 5382 s.qh && s.qh(t, e, i); 5383 } 5384 function li(s, t, e, i) { 5385 s.st(t, e, i); 5386 } 5387 function ps(s, t, e, i) { 5388 const r = s(e, i); 5389 for (const n of r) { 5390 const a = n.Tt(i); 5391 a !== null && t(a); 5392 } 5393 } 5394 function Zi(s, t) { 5395 return (e) => { 5396 var i, r, n, a; 5397 return (function(o) { 5398 return o.Ft !== void 0; 5399 })(e) ? ((r = (i = e.Ft()) == null ? void 0 : i.cl()) != null ? r : "") !== t ? [] : (a = (n = e.Ga) == null ? void 0 : n.call(e, s)) != null ? a : [] : []; 5400 }; 5401 } 5402 function Hr(s, t, e, i) { 5403 if (!s.length) 5404 return; 5405 let r = 0; 5406 const n = s[0].$t(i, true); 5407 let a = t === 1 ? e / 2 - (s[0].Hi() - n / 2) : s[0].Hi() - n / 2 - e / 2; 5408 a = Math.max(0, a); 5409 for (let o = 1; o < s.length; o++) { 5410 const l = s[o], h = s[o - 1], c = h.$t(i, false), d = l.Hi(), f = h.Hi(); 5411 if (t === 1 ? d > f - c : d < f + c) { 5412 const m = f - c * t; 5413 l.Ui(m); 5414 const p = m - t * c / 2; 5415 if ((t === 1 ? p < 0 : p > e) && a > 0) { 5416 const v = t === 1 ? -1 - p : p - e, b = Math.min(v, a); 5417 for (let y = r; y < s.length; y++) 5418 s[y].Ui(s[y].Hi() + t * b); 5419 a -= b; 5420 } 5421 } else 5422 r = o, a = t === 1 ? f - c - d : d - (f + c); 5423 } 5424 } 5425 var Wr = class { 5426 constructor(t, e, i, r) { 5427 this.Ki = null, this.Qv = null, this.tm = false, this.im = new mi(200), this.nm = null, this.sm = 0, this.rm = false, this.hm = () => { 5428 this.rm || this.yt.am().Qt().mr(); 5429 }, this.lm = () => { 5430 this.rm || this.yt.am().Qt().mr(); 5431 }, this.yt = t, this.yn = e, this.ko = e.layout, this.wd = i, this.om = r === "left", this._m = Zi("normal", r), this.um = Zi("top", r), this.dm = Zi("bottom", r), this.lv = document.createElement("div"), this.lv.style.height = "100%", this.lv.style.overflow = "hidden", this.lv.style.width = "25px", this.lv.style.left = "0", this.lv.style.position = "relative", this.fm = se(this.lv, B({ width: 16, height: 16 })), this.fm.subscribeSuggestedBitmapSizeChanged(this.hm); 5432 const n = this.fm.canvasElement; 5433 n.style.position = "absolute", n.style.zIndex = "1", n.style.left = "0", n.style.top = "0", this.pm = se(this.lv, B({ width: 16, height: 16 })), this.pm.subscribeSuggestedBitmapSizeChanged(this.lm); 5434 const a = this.pm.canvasElement; 5435 a.style.position = "absolute", a.style.zIndex = "2", a.style.left = "0", a.style.top = "0"; 5436 const o = { zp: this.Mv.bind(this), Ap: this.Mv.bind(this), Pp: this.gv.bind(this), yp: this.gv.bind(this), Op: this.vm.bind(this), Ip: this.bv.bind(this), Rp: this.bv.bind(this), up: this.wm.bind(this), ap: this.wm.bind(this), wp: this.Mm.bind(this), Yp: this.wv.bind(this) }; 5437 this.tv = new Ci(this.pm.canvasElement, o, { xp: () => !this.yn.handleScroll.vertTouchDrag, Cp: () => true }); 5438 } 5439 m() { 5440 this.tv.m(), this.pm.unsubscribeSuggestedBitmapSizeChanged(this.lm), re
5440(this.pm.canvasElement), this.pm.dispose(), this.fm.unsubscribeSuggestedBitmapSizeChanged(this.hm), re(this.fm.canvasElement), this.fm.dispose(), this.Ki !== null && this.Ki.a_().u(this), this.Ki = null; 5441 } 5442 uv() { 5443 return this.lv; 5444 } 5445 k() { 5446 return this.ko.fontSize; 5447 } 5448 gm() { 5449 const t = this.wd.N(); 5450 return this.nm !== t.P && (this.im.Os(), this.nm = t.P), t; 5451 } 5452 bm() { 5453 if (this.Ki === null) 5454 return 0; 5455 let t = 0; 5456 const e = this.gm(), i = k(this.fm.canvasElement.getContext("2d", { colorSpace: this.yt.am().N().layout.colorSpace })); 5457 i.save(); 5458 const r = this.Ki.El(); 5459 i.font = this.Sm(), r.length > 0 && (t = Math.max(this.im.Ii(i, r[0].io), this.im.Ii(i, r[r.length - 1].io))); 5460 const n = this.xm(); 5461 for (let h = n.length; h--; ) { 5462 const c = this.im.Ii(i, n[h].ri()); 5463 c > t && (t = c); 5464 } 5465 const a = this.Ki.Lt(); 5466 if (a !== null && this.Qv !== null && (o = this.yn.crosshair).mode !== 2 && o.horzLine.visible && o.horzLine.labelVisible) { 5467 const h = this.Ki.Tn(1, a), c = this.Ki.Tn(this.Qv.height - 2, a); 5468 t = Math.max(t, this.im.Ii(i, this.Ki.Ji(Math.floor(Math.min(h, c)) + 0.11111111111111, a)), this.im.Ii(i, this.Ki.Ji(Math.ceil(Math.max(h, c)) - 0.11111111111111, a))); 5469 } 5470 var o; 5471 i.restore(); 5472 const l = t || 34; 5473 return fs(Math.ceil(e.S + e.C + e.V + e.B + 5 + l)); 5474 } 5475 Cm(t) { 5476 this.Qv !== null && Gt(this.Qv, t) || (this.Qv = t, this.rm = true, this.fm.resizeCanvasElement(t), this.pm.resizeCanvasElement(t), this.rm = false, this.lv.style.width = `${t.width}px`, this.lv.style.height = `${t.height}px`); 5477 } 5478 ym() { 5479 return k(this.Qv).width; 5480 } 5481 un(t) { 5482 this.Ki !== t && (this.Ki !== null && this.Ki.a_().u(this), this.Ki = t, t.a_().i(this.po.bind(this), this)); 5483 }
5484 Ft() { 5485 return this.Ki; 5486 } 5487 Os() { 5488 const t = this.yt.Sv(); 5489 this.yt.am().Qt().eu(t, k(this.Ft())); 5490 } 5491 km(t) { 5492 if (this.Qv === null) 5493 return; 5494 const e = { colorSpace: this.yt.am().N().layout.colorSpace }; 5495 if (t !== 1) { 5496 this.Pm(), this.fm.applySuggestedBitmapSize(); 5497 const r = ee(this.fm, e); 5498 r !== null && (r.useBitmapCoordinateSpace((n) => { 5499 this.Tm(n), this.Rm(n); 5500 }), this.yt.Dm(r, this.dm), this.Im(r), this.yt.Dm(r, this._m), this.Vm(r)); 5501 } 5502 this.pm.applySuggestedBitmapSize(); 5503 const i = ee(this.pm, e); 5504 i !== null && (i.useBitmapCoordinateSpace(({ context: r, bitmapSize: n }) => { 5505 r.clearRect(0, 0, n.width, n.height); 5506 }), this.Bm(i), this.yt.Dm(i, this.um)); 5507 } 5508 dv() { 5509 return this.fm.bitmapSize; 5510 } 5511 fv(t, e, i, r) { 5512 const n = this.dv(); 5513 if (n.width > 0 && n.height > 0 && (t.drawImage(this.fm.canvasElement, e, i), r)) { 5514 const a = this.pm.canvasElement; 5515 t.drawImage(a, e, i); 5516 } 5517 } 5518 kt() { 5519 var t; 5520 (t = this.Ki) == null || t.El(); 5521 } 5522 Mv(t) { 5523 if (this.Ki === null || this.Ki.Gi() || !this.yn.handleScale.axisPressedMouseMove.price) 5524 return; 5525 const e = this.yt.am().Qt(), i = this.yt.Sv(); 5526 this.tm = true, e.G_(i, this.Ki, t.localY); 5527 } 5528 gv(t) { 5529 if (this.Ki === null || !this.yn.handleScale.axisPressedMouseMove.price) 5530 return; 5531 const e = this.yt.am().Qt(), i = this.yt.Sv(), r = this.Ki; 5532 e.X_(i, r, t.localY); 5533 } 5534 vm() { 5535 if (this.Ki === null || !this.yn.handleScale.axisPressedMouseMove.price) 5536 return; 5537 const t = this.yt.am().Qt(), e = this.yt.Sv(), i = this.Ki; 5538 this.tm && (this.tm = false, t.J_(e, i)); 5539 } 5540 bv(t) { 5541 if (this.Ki === null || !this.yn.handleScale.axisPressedMouseMove.price) 5542 return; 5543 const e = this.yt.am().Qt(), i = this.yt.Sv(); 5544 this.tm = false, e.J_(i, this.Ki); 5545 } 5546 wm(t) { 5547 this.yn.handleScale.axisDoubleClickReset.price && this.Os(); 5548 } 5549 Mm(t) { 5550 this.Ki !== null && (!this.yt.am().Qt().N().handleScale.axisPressedMouseMove.price || this.Ki.je() || this.Ki.Lo() || this.Em(1)); 5551 } 5552 wv(t) { 5553 this.Em(0); 5554 } 5555 xm() { 5556 const t = [], e = this.Ki === null ? void 0 : this.Ki; 5557 return ((i) => { 5558 for (let r = 0; r < i.length; ++r) { 5559 const n = i[r].qn(this.yt.Sv(), e); 5560 for (let a = 0; a < n.length; a++) 5561 t.push(n[a]); 5562 } 5563 })(this.yt.Sv().Dt()), t; 5564 } 5565 Tm({ context: t, bitmapSize: e }) { 5566 const { width: i, height: r } = e, n = this.yt.Sv().Qt(), a = n.$(), o = n.ef(); 5567 a === o ? yi(t, 0, 0, i, r, a) : In(t, 0, 0, i, r, a, o); 5568 } 5569 Rm({ context: t, bitmapSize: e, horizontalPixelRatio: i }) { 5570 if (this.Qv === null || this.Ki === null || !this.Ki.N().borderVisible) 5571 return; 5572 t.fillStyle = this.Ki.N().borderColor; 5573 const r = Math.max(1, Math.floor(this.gm().S * i)); 5574 let n; 5575 n = this.om ? e.width - r : 0, t.fillRect(n, 0, r, e.height); 5576 } 5577 Im(t) { 5578 if (this.Qv === null || this.Ki === null) 5579 return; 5580 const e = this.Ki.El(), i = this.Ki.N(), r = this.gm(), n = this.om ? this.Qv.width - r.C : 0; 5581 i.borderVisible && i.ticksVisible && t.useBitmapCoordinateSpace(({ context: a, horizontalPixelRatio: o, verticalPixelRatio: l }) => { 5582 a.fillStyle = i.borderColor; 5583 const h = Math.max(1, Math.floor(l)), c = Math.floor(0.5 * l), d = Math.round(r.C * o); 5584 a.beginPath(); 5585 for (const f of e) 5586 a.rect(Math.floor(n * o), Math.round(f.Rl * l) - c, d, h); 5587 a.fill(); 5588 }), t.useMediaCoordinateSpace(({ context: a }) => { 5589 var h; 5590 a.font = this.Sm(), a.fillStyle = (h = i.textColor) != null ? h : this.ko.textColor, a.textAlign = this.om ? "right" : "left", a.textBaseline = "middle"; 5591 const o = this.om ? Math.round(n - r.V) : Math.round(n + r.C + r.V), l = e.map((c) => this.im.Di(a, c.io)); 5592 for (let c = e.length; c--; ) { 5593 const d = e[c]; 5594 a.fillText(d.io, o, d.Rl + l[c]); 5595 } 5596 }); 5597 } 5598 Pm() { 5599 if (this.Qv === null || this.Ki === null) 5600 return; 5601 let t = this.Qv.height / 2; 5602 const e = [], i = this.Ki.Dt().slice(), r = this.yt.Sv(), n = this.gm();
5603 this.Ki === r.Gs() && this.yt.Sv().Dt().forEach((l) => { 5604 r.Zs(l) && i.push(l); 5605 }); 5606 const a = this.Ki.Cl()[0], o = this.Ki; 5607 i.forEach((l) => { 5608 const h = l.qn(r, o); 5609 h.forEach((c) => { 5610 c.$i() && c.Wi() === null && (c.Ui(null), e.push(c)); 5611 }), a === l && h.length > 0 && (t = h[0].Ei()); 5612 }), this.Ki.N().alignLabels && this.Am(e, n, t); 5613 } 5614 Am(t, e, i) { 5615 if (this.Qv === null) 5616 return; 5617 const r = t.filter((a) => a.Ei() <= i), n = t.filter((a) => a.Ei() > i); 5618 r.sort((a, o) => o.Ei() - a.Ei()), r.length && n.length && n.push(r[0]), n.sort((a, o) => a.Ei() - o.Ei()); 5619 for (const a of t) { 5620 const o = Math.floor(a.$t(e) / 2), l = a.Ei(); 5621 l > -o && l < o && a.Ui(o), l > this.Qv.height - o && l < this.Qv.height + o && a.Ui(this.Qv.height - o); 5622 } 5623 Hr(r, 1, this.Qv.height, e), Hr(n, -1, this.Qv.height, e); 5624 } 5625 Vm(t) { 5626 if (this.Qv === null) 5627 return; 5628 const e = this.xm(), i = this.gm(), r = this.om ? "right" : "left"; 5629 e.forEach((n) => { 5630 n.ji() && n.Tt(k(this.Ki)).st(t, i, this.im, r); 5631 }); 5632 } 5633 Bm(t) { 5634 if (this.Qv === null || this.Ki === null) 5635 return; 5636 const e = this.yt.am().Qt(), i = [], r = this.yt.Sv(), n = e.Rd().qn(r, this.Ki); 5637 n.length && i.push(n); 5638 const a = this.gm(), o = this.om ? "right" : "left"; 5639 i.forEach((l) => { 5640 l.forEach((h) => { 5641 h.Tt(k(this.Ki)).st(t, a, this.im, o); 5642 }); 5643 }); 5644 } 5645 Em(t) { 5646 this.lv.style.cursor = t === 1 ? "ns-resize" : "default"; 5647 } 5648 po() { 5649 const t = this.bm(); 5650 this.sm < t && this.yt.am().Qt().Pa(), this.sm = t; 5651 } 5652 Sm() { 5653 return fi(this.ko.fontSize, this.ko.fontFamily); 5654 } 5655 }; 5656 function dl(s, t) { 5657 var e, i; 5658 return (i = (e = s.Ka) == null ? void 0 : e.call(s, t)) != null ? i : []; 5659 } 5660 function Qr(s, t) { 5661 var e, i; 5662 return (i = (e = s.jn) == null ? void 0 : e.call(s, t)) != null ? i : []; 5663 } 5664 function Yr(s, t) { 5665 var e, i; 5666 return (i = (e = s.cn) == null ? void 0 : e.call(s, t)) != null ? i : []; 5667 } 5668 function ul(s, t) { 5669 var e, i; 5670 return (i = (e = s.ja) == null ? void 0 : e.call(s, t)) != null ? i : []; 5671 } 5672 var Ts = class _Ts { 5673 constructor(t, e) { 5674 this.Qv = B({ width: 0, height: 0 }), this.Lm = null, this.zm = null, this.Om = null, this.Nm = null, this.Fm = false, this.Wm = new Y(), this.Hm = new Y(), this.Um = 0, this.$m = false, this.jm = null, this.qm = false, this.Ym = null, this.Km = null, this.rm = false, this.hm = () => { 5675 this.rm || this.Zm === null || this.sn().mr(); 5676 }, this.lm = () => { 5677 this.rm || this.Zm === null || this.sn().mr(); 5678 }, this.qv = t, this.Zm = e, this.Zm.fu().i(this.Gm.bind(this), this, true), this.Xm = document.createElement("td"), this.Xm.style.padding = "0", this.Xm.style.position = "relative"; 5679 const i = document.createElement("div"); 5680 i.style.width = "100%", i.style.height = "100%", i.style.position = "relative", i.style.overflow = "hidden", this.Jm = document.createElement("td"), this.Jm.style.padding = "0", this.Qm = document.createElement("td"), this.Qm.style.padding = "0", this.Xm.appendChild(i), this.fm = se(i, B({ width: 16, height: 16 })), this.fm.subscribeSuggestedBitmapSizeChanged(this.hm); 5681 const r = this.fm.canvasElement; 5682 r.style.position = "absolute", r.style.zIndex = "1", r.style.left = "0", r.style.top = "0", this.pm = se(i, B({ width: 16, height: 16 })), this.pm.subscribeSuggestedBitmapSizeChanged(this.lm); 5683 const n = this.pm.canvasElement; 5684 n.style.position = "absolute", n.style.zIndex = "2", n.style.left = "0", n.style.top = "0", this.av = document.createElement("tr"), this.av.appendChild(this.Jm), this.av.appendChild(this.Xm), this.av.appendChild(this.Qm), this.tw(), this.tv = new Ci(this.pm.canvasElement, this, { xp: () => this.jm === null && !this.qv.N().handleScroll.vertTouchDrag, Cp: () => this.jm === null && !this.qv.N().handleScroll.horzTouchDrag }); 5685 } 5686 m() { 5687 this.Lm !== null && this.Lm.m(), this.zm !== null && this.zm.m(), this.Om = null, this.pm.unsubscribeSuggestedBitmapSizeChanged(this.lm), re
5687(this.pm.canvasElement), this.pm.dispose(), this.fm.unsubscribeSuggestedBitmapSizeChanged(this.hm), re(this.fm.canvasElement), this.fm.dispose(), this.Zm !== null && (this.Zm.fu().u(this), this.Zm.m()), this.tv.m(); 5688 } 5689 Sv() { 5690 return k(this.Zm); 5691 } 5692 iw(t) { 5693 var e, i; 5694 this.Zm !== null && this.Zm.fu().u(this), this.Zm = t, this.Zm !== null && this.Zm.fu().i(_Ts.prototype.Gm.bind(this), this, true), this.tw(), this.qv.rv().indexOf(this) === this.qv.rv().length - 1 ? (this.Om = (e = this.Om) != null ? e : new cl(this.Xm, this.qv), this.Om.kt()) : ((i = this.Om) == null || i.Kv(), this.Om = null); 5695 } 5696 am() { 5697 return this.qv; 5698 } 5699 uv() { 5700 return this.av; 5701 } 5702 tw() { 5703 if (this.Zm !== null && (this.nw(), this.sn().Jn().length !== 0)) { 5704 if (this.Lm !== null) { 5705 const t = this.Zm.K_(); 5706 this.Lm.un(k(t)); 5707 } 5708 if (this.zm !== null) { 5709 const t = this.Zm.Z_(); 5710 this.zm.un(k(t)); 5711 } 5712 } 5713 } 5714 sw() { 5715 this.Lm !== null && this.Lm.kt(), this.zm !== null && this.zm.kt(); 5716 } 5717 z_() { 5718 return this.Zm !== null ? this.Zm.z_() : 0; 5719 } 5720 O_(t) { 5721 this.Zm && this.Zm.O_(t); 5722 } 5723 wp(t) { 5724 if (!this.Zm) 5725 return; 5726 this.ew(); 5727 const e = t.localX, i = t.localY; 5728 this.rw(e, i, t); 5729 } 5730 zp(t) { 5731 this.ew(), this.hw(), this.rw(t.localX, t.localY, t); 5732 } 5733 Mp(t) { 5734 if (!this.Zm) 5735 return; 5736 this.ew(); 5737 const e = t.localX, i = t.localY; 5738 this.rw(e, i, t); 5739 } 5740 Vp(t) { 5741 this.Zm !== null && (this.ew(), this.rw(t.localX, t.localY, t), this.aw(t)); 5742 } 5743 up(t) { 5744 this.Zm !== null && this.lw(this.Hm, t); 5745 } 5746 ap(t) { 5747 this.up(t); 5748 } 5749 Pp(t) { 5750 this.ew(), this.ow(t), this.rw(t.localX, t.localY, t); 5751 } 5752 Ip(t) { 5753 this.Zm !== null && (this.ew(), this.$m = false, this._w(t)); 5754 } 5755 Dp(t) { 5756 this.Zm !== null && this.aw(t); 5757 } 5758 Kp(t) { 5759 if (this.$m = true, this.jm === null) { 5760 const e = { x: t.localX, y: t.localY }; 5761 this.uw(e, e, t); 5762 } 5763 } 5764 Yp(t) { 5765 this.Zm !== null && (this.ew(), this.Zm.Qt().kd(null), this.cw()); 5766 } 5767 dw() { 5768 return this.Wm; 5769 } 5770 fw() { 5771 return this.Hm; 5772 } 5773 Wp() { 5774 this.Um = 1, this.sn().cs(); 5775 } 5776 Hp(t, e) { 5777 if (!this.qv.N().handleScale.pinch) 5778 return; 5779 const i = 5 * (e - this.Um); 5780 this.Um = e, this.sn().Od(t._t, i); 5781 } 5782 Ap(t) { 5783 this.$m = false, this.qm = this.jm !== null, this.hw(); 5784 const e = this.sn().Rd(); 5785 this.jm !== null && e.It() && (this.Ym = { x: e.ni(), y: e.si() }, this.jm = { x: t.localX, y: t.localY }); 5786 } 5787 yp(t) { 5788 if (this.Zm === null) 5789 return; 5790 const e = t.localX, i = t.localY; 5791 if (this.jm === null) 5792 this.ow(t); 5793 else { 5794 this.qm = false; 5795 const r = k(this.Ym), n = r.x + (e - this.jm.x), a = r.y + (i - this.jm.y); 5796 this.rw(n, a, t); 5797 } 5798 } 5799 Rp(t) { 5800 this.am().N().trackingMode.exitMode === 0 && (this.qm = true), this.pw(), this._w(t); 5801 } 5802 Qs(t, e) { 5803 const i = this.Zm; 5804 return i === null ? null : Wn(i, t, e); 5805 } 5806 mw(t, e) { 5807 k(e === "left" ? this.Lm : this.zm).Cm(B({ width: t, height: this.Qv.height })); 5808 } 5809 cv() { 5810 return this.Qv; 5811 } 5812 Cm(t) { 5813 Gt(this.Qv, t) || (this.Qv = t, this.rm = true, this.fm.resizeCanvasElement(t), this.pm.resizeCanvasElement(t), this.rm = false, this.Xm.style.width = t.width + "px", this.Xm.style.height = t.height + "px"); 5814 } 5815 ww() { 5816 const t = k(this.Zm); 5817 t.q_(t.K_()), t.q_(t.Z_()); 5818 for (const e of t.Cl()) 5819 if (t.Zs(e)) { 5820 const i = e.Ft(); 5821 i !== null && t.q_(i), e.Nn(); 5822 } 5823 for (const e of t.vu()) 5824 e.Nn(); 5825 } 5826 dv() { 5827 return this.fm.bitmapSize; 5828 } 5829 fv(t, e, i, r) { 5830 const n = this.dv(); 5831 if (n.width > 0 && n.height > 0 && (t.drawImage(this.fm.canvasElement, e, i), r)) { 5832 const a = this.pm.canvasElement; 5833 t !== null && t.drawImage(a, e, i); 5834 } 5835 } 5836 km(t) { 5837 if (t === 0 || this.Zm === null) 5838 return; 5839 t > 1 && this.ww(), this.Lm !== null && this.Lm.km(t), this.zm !== null && this.zm.km(t); 5840 const e = { colorSpace: this.qv.N().layout.colorSpace }; 5841 if (t !== 1) { 5842 this.fm.applySuggestedBitmapSize(); 5843 const r = ee(this.fm, e); 5844 r !== null && (r.useBitmapCoordinateSpace((n) => { 5845 this.Tm(n); 5846 }), this.Zm && (this.Mw(r, dl), this.gw(r), this.Mw(r, Qr), this.Mw(r, Yr))); 5847 } 5848 this.pm.applySuggestedBitmapSize(); 5849 const i = ee(this.pm, e); 5850 i !== null && (i.useBitmapCoordinateSpace(({ context: r, bitmapSize: n }) => { 5851 r.clearRect(0, 0, n.width, n.height); 5852 }), this.bw(i), this.Mw(i, ul), this.Mw(i, Yr)); 5853 } 5854 Sw() { 5855 return this.Lm;
5856 } 5857 xw() { 5858 return this.zm; 5859 } 5860 Dm(t, e) { 5861 this.Mw(t, e); 5862 } 5863 Gm() { 5864 this.Zm !== null && this.Zm.fu().u(this), this.Zm = null; 5865 } 5866 aw(t) { 5867 this.lw(this.Wm, t); 5868 } 5869 lw(t, e) { 5870 const i = e.localX, r = e.localY; 5871 t.v() && t.p(this.sn().Et().Rc(i), { x: i, y: r }, e); 5872 } 5873 Tm({ context: t, bitmapSize: e }) { 5874 const { width: i, height: r } = e, n = this.sn(), a = n.$(), o = n.ef(); 5875 a === o ? yi(t, 0, 0, i, r, o) : In(t, 0, 0, i, r, a, o); 5876 } 5877 gw(t) { 5878 const e = k(this.Zm), i = e.pu().wr().Tt(e); 5879 i !== null && i.st(t, false); 5880 } 5881 bw(t) { 5882 this.Cw(t, Qr, li, this.sn().Rd()); 5883 } 5884 Mw(t, e) { 5885 const i = k(this.Zm), r = i.au(), n = i.vu(); 5886 for (const a of n) 5887 this.Cw(t, e, ms, a); 5888 for (const a of r) 5889 this.Cw(t, e, ms, a); 5890 for (const a of n) 5891 this.Cw(t, e, li, a); 5892 for (const a of r) 5893 this.Cw(t, e, li, a); 5894 } 5895 Cw(t, e, i, r) { 5896 const n = k(this.Zm), a = n.Qt().ou(), o = a !== null && a.lu === r, l = a !== null && o && a.wu !== void 0 ? a.wu.ie : void 0; 5897 ps(e, (h) => i(h, t, o, l), r, n); 5898 } 5899 nw() { 5900 if (this.Zm === null) 5901 return; 5902 const t = this.qv, e = this.Zm.K_().N().visible, i = this.Zm.Z_().N().visible; 5903 e || this.Lm === null || (this.Jm.removeChild(this.Lm.uv()), this.Lm.m(), this.Lm = null), i || this.zm === null || (this.Qm.removeChild(this.zm.uv()), this.zm.m(), this.zm = null); 5904 const r = t.Qt().Zd(); 5905 e && this.Lm === null && (this.Lm = new Wr(this, t.N(), r, "left"), this.Jm.appendChild(this.Lm.uv())), i && this.zm === null && (this.zm = new Wr(this, t.N(), r, "right"), this.Qm.appendChild(this.zm.uv())); 5906 } 5907 yw(t) { 5908 return t.Zp && this.$m || this.jm !== null; 5909 } 5910 rw(t, e, i) { 5911 t = Math.max(0, Math.min(t, this.Qv.width - 1)), e = Math.max(0, Math.min(e, this.Qv.height - 1)), this.sn().jd(t, e, i, k(this.Zm)); 5912 } 5913 cw() { 5914 this.sn().Yd(); 5915 } 5916 pw() { 5917 this.qm && (this.jm = null, this.cw()); 5918 } 5919 uw(t, e, i) { 5920 this.jm = t, this.qm = false, this.rw(e.x, e.y, i); 5921 const r = this.sn().Rd(); 5922 this.Ym = { x: r.ni(), y: r.si() }; 5923 } 5924 sn() { 5925 return this.qv.Qt(); 5926 } 5927 _w(t) { 5928 if (!this.Fm) 5929 return; 5930 const e = this.sn(), i = this.Sv(); 5931 if (e.iu(i, i.Pn()), this.Nm = null, this.Fm = false, e.Hd(), this.Km !== null) { 5932 const r = performance.now(), n = e.Et(); 5933 this.Km.me(n.Ac(), r), this.Km.jc(r) || e.ps(this.Km); 5934 } 5935 } 5936 ew() { 5937 this.jm = null; 5938 } 5939 hw() { 5940 if (this.Zm) { 5941 if (this.sn().cs(), document.activeElement !== document.body && document.activeElement !== document.documentElement) 5942 k(document.activeElement).blur(); 5943 else { 5944 const t = document.getSelection(); 5945 t !== null && t.removeAllRanges(); 5946 } 5947 !this.Zm.Pn().Gi() && this.sn().Et().Gi(); 5948 } 5949 } 5950 ow(t) { 5951 if (this.Zm === null) 5952 return; 5953 const e = this.sn(), i = e.Et(); 5954 if (i.Gi()) 5955 return; 5956 const r = this.qv.N(), n = r.handleScroll, a = r.kineticScroll; 5957 if ((!n.pressedMouseMove || t.Zp) && (!n.horzTouchDrag && !n.vertTouchDrag || !t.Zp)) 5958 return; 5959 const o = this.Zm.Pn(), l = performance.now(); 5960 if (this.Nm !== null || this.yw(t) || (this.Nm = { x: t.clientX, y: t.clientY, Sf: l, kw: t.localX, Pw: t.localY }), this.Nm !== null && !this.Fm && (this.Nm.x !== t.clientX || this.Nm.y !== t.clientY)) { 5961 if (t.Zp && a.touch || !t.Zp && a.mouse) { 5962 const h = i.fl(); 5963 this.Km = new hl(0.2 / h, 7 / h, 0.997, 15 / h), this.Km.Fv(i.Ac(), this.Nm.Sf); 5964 } else 5965 this.Km = null; 5966 o.Gi() || e.Q_(this.Zm, o, t.localY), e.Fd(t.localX), this.Fm = true; 5967 } 5968 this.Fm && (o.Gi() || e.tu(this.Zm, o, t.localY), e.Wd(t.localX), this.Km !== null && this.Km.Fv(i.Ac(), l)); 5969 } 5970 }; 5971 var Kr = class { 5972 constructor(t, e, i, r, n) { 5973 this.xt = true, this.Qv = B({ width: 0, height: 0 }), this.hm = () => this.km(3), this.om = t === "left", this.wd = i.Zd, this.yn = e, this.Tw = r, this.Rw = n, this.lv = document.createElement("div"), this.lv.style.width = "25px", this.lv.style.height = "100%", this.lv.style.overflow = "hidden", this.fm = se(this.lv, B({ width: 16, height: 16 })), this.fm.subscribeSuggestedBitmapSizeChanged(this.hm); 5974 } 5975 m() { 5976 this.fm.unsubscribeSuggestedBitmapSizeChanged(this.hm), re(this.fm.canvasElement), this.fm.dispose(); 5977 } 5978 uv() { 5979 return this.lv; 5980 } 5981 cv() { 5982 return this.Qv; 5983 } 5984 Cm(t) { 5985 Gt(this.Qv, t) || (this.Qv = t, this.fm.resizeCanvasElement(t), this.lv.style.width = `${t.width}px`, this.lv.style.height = `${t.height}px`, this.xt = true); 5986 } 5987 km(t) { 5988 if (t < 3 && !this.xt || this.Qv.width === 0 || this.Qv.height === 0) 5989 return; 5990 this.xt = false, this.fm.applySuggestedBitmapSize(); 5991 const e = ee(this.fm, { colorSpace: this.yn.layout.colorSpace }); 5992 e !== null && e.useBitmapCoordinateSpace((i) => { 5993 this.Tm(i), this.Rm(i); 5994 }); 5995 } 5996 dv() { 5997 return this.fm.bitmapSize; 5998 } 5999 fv(t, e, i) { 6000 const r = this.dv(); 6001 r.width > 0 && r.height > 0 && t.drawImage(this.fm.canvasElement, e, i); 6002 } 6003 Rm({ context: t, bitmapSize: e, horizontalPixelRatio: i, verticalPixelRatio: r }) { 6004 if (!this.Tw()) 6005 return; 6006 t.fillStyle = this.yn.timeScale.borderColor; 6007 const n = Math.floor(this.wd.N().S * i), a = Math.floor(this.wd.N().S * r), o = this.om ? e.width - n : 0; 6008 t.fillRect(o, 0, n, a); 6009 } 6010 Tm({ context: t, bitmapSize: e }) { 6011 yi(t, 0, 0, e.width, e.height, this.Rw()); 6012 } 6013 }; 6014 function Is(s) { 6015 return (t) => { 6016 var e, i; 6017 return (i = (e = t.Xa) == null ? void 0 : e.call(t, s)) != null ? i : []; 6018 }; 6019 } 6020 var fl = Is("normal"); 6021 var ml = Is("top"); 6022 var pl = Is("bottom"); 6023 var gl = class { 6024 constructor(t, e) { 6025 this.Dw = null, this.Iw = null, this.M = null, this.Vw = false, this.Qv = B({ width: 0, height: 0 }), this.Bw = new Y(), this.im = new mi(5), this.rm = false, this.hm = () => { 6026 this.rm || this.qv.Qt().mr(); 6027 }, this.lm = () => { 6028 this.rm || this.qv.Qt().mr(); 6029 }, this.qv = t, this.xu = e, this.yn = t.N().layout, this.Hv = document.createElement("tr"), this.Ew = document.createElement("td"), this.Ew.style.padding = "0", this.Aw = document.createElement("td"), this.Aw.style.padding = "0", this.lv = document.createElement("td"), this.lv.style.height = "25px", this.lv.style.padding = "0", this.Lw = document.createElement("div"), this.Lw.style.width = "100%", this.Lw.style.height = "100%", this.Lw.style.position = "relative", this.Lw.style.overflow = "hidden", this.lv.appendChild(this.Lw), this.fm = se(this.Lw, B({ width: 16, height: 16 })), this.fm.subscribeSuggestedBitmapSizeChanged(this.hm); 6030 const i = this.fm.canvasElement; 6031 i.style.position = "absolute", i.style.zIndex = "1", i.style.left = "0", i.style.top = "0", this.pm = se(this.Lw, B({ width: 16, height: 16 })), this.pm.subscribeSuggestedBitmapSizeChanged(this.lm); 6032 const r = this.pm.canvasElement; 6033 r.style.position = "absolute", r.style.zIndex = "2", r.style.left = "0", r.style.top = "0", this.Hv.appendChild(this.Ew), this.Hv.appendChild(this.lv), this.Hv.appendChild(this.Aw), this.zw(), this.qv.Qt().L_().i(this.zw.bind(this), this), this.tv = new Ci(this.pm.canvasElement, this, { xp: () => true, Cp: () => !this.qv.N().handleScroll.horzTouchDrag }); 6034 } 6035 m() { 6036 this.tv.m(), this.Dw !== null && this.Dw.m(), this.Iw !== null && this.Iw.m(), this.pm.unsubscribeSuggestedBitmapSizeChanged(this.lm), re
6036(this.pm.canvasElement), this.pm.dispose(), this.fm.unsubscribeSuggestedBitmapSizeChanged(this.hm), re(this.fm.canvasElement), this.fm.dispose(); 6037 } 6038 uv() { 6039 return this.Hv; 6040 } 6041 Ow() { 6042 return this.Dw; 6043 } 6044 Nw() { 6045 return this.Iw; 6046 } 6047 zp(t) { 6048 if (this.Vw) 6049 return; 6050 this.Vw = true; 6051 const e = this.qv.Qt(); 6052 !e.Et().Gi() && this.qv.N().handleScale.axisPressedMouseMove.time && e.zd(t.localX); 6053 } 6054 Ap(t) { 6055 this.zp(t); 6056 } 6057 Op() { 6058 const t = this.qv.Qt(); 6059 !t.Et().Gi() && this.Vw && (this.Vw = false, this.qv.N().handleScale.axisPressedMouseMove.time && t.$d()); 6060 } 6061 Pp(t) { 6062 const e = this.qv.Qt(); 6063 !e.Et().Gi() && this.qv.N().handleScale.axisPressedMouseMove.time && e.Ud(t.localX); 6064 } 6065 yp(t) { 6066 this.Pp(t); 6067 } 6068 Ip() { 6069 this.Vw = false; 6070 const t = this.qv.Qt(); 6071 t.Et().Gi() && !this.qv.N().handleScale.axisPressedMouseMove.time || t.$d(); 6072 } 6073 Rp() { 6074 this.Ip(); 6075 } 6076 up() { 6077 this.qv.N().handleScale.axisDoubleClickReset.time && this.qv.Qt().ws(); 6078 } 6079 ap() { 6080 this.up(); 6081 } 6082 wp() { 6083 this.qv.Qt().N().handleScale.axisPressedMouseMove.time && this.Em(1); 6084 } 6085 Yp() { 6086 this.Em(0); 6087 } 6088 cv() { 6089 return this.Qv; 6090 } 6091 Fw() { 6092 return this.Bw; 6093 } 6094 Ww(t, e, i) { 6095 Gt(this.Qv, t) || (this.Qv = t, this.rm = true, this.fm.resizeCanvasElement(t), this.pm.resizeCanvasElement(t), this.rm = false, this.lv.style.width = `${t.width}px`, this.lv.style.height = `${t.height}px`, this.Bw.p(t)), this.Dw !== null && this.Dw.Cm(B({ width: e, height: t.height })), this.Iw !== null && this.Iw.Cm(B({ width: i, height: t.height })); 6096 } 6097 Hw() { 6098 const t = this.Uw(); 6099 return Math.ceil(t.S + t.C + t.k + t.A + t.I + t.$w); 6100 } 6101 kt() { 6102 this.qv.Qt().Et().El(); 6103 } 6104 dv() { 6105 return this.fm.bitmapSize; 6106 } 6107 fv(t, e, i, r) { 6108 const n = this.dv(); 6109 if (n.width > 0 && n.height > 0 && (t.drawImage(this.fm.canvasElement, e, i), r)) { 6110 const a = this.pm.canvasElement; 6111 t.drawImage(a, e, i); 6112 } 6113 } 6114 km(t) { 6115 if (t === 0) 6116 return; 6117 const e = { colorSpace: this.yn.colorSpace }; 6118 if (t !== 1) { 6119 this.fm.applySuggestedBitmapSize(); 6120 const r = ee(this.fm, e); 6121 r !== null && (r.useBitmapCoordinateSpace((n) => { 6122 this.Tm(n), this.Rm(n), this.jw(r, pl); 6123 }), this.Im(r), this.jw(r, fl)), this.Dw !== null && this.Dw.km(t), this.Iw !== null && this.Iw.km(t); 6124 } 6125 this.pm.applySuggestedBitmapSize(); 6126 const i = ee(this.pm, e); 6127 i !== null && (i.useBitmapCoordinateSpace(({ context: r, bitmapSize: n }) => { 6128 r.clearRect(0, 0, n.width, n.height); 6129 }), this.qw([...this.qv.Qt().Jn(), this.qv.Qt().Rd()], i), this.jw(i, ml)); 6130 } 6131 jw(t, e) { 6132 const i = this.qv.Qt().Jn(); 6133 for (const r of i) 6134 ps(e, (n) => ms(n, t, false, void 0), r, void 0); 6135 for (const r of i) 6136 ps(e, (n) => li(n, t, false, void 0), r, void 0); 6137 } 6138 Tm({ context: t, bitmapSize: e }) { 6139 yi(t, 0, 0, e.width, e.height, this.qv.Qt().ef()); 6140 } 6141 Rm({ context: t, bitmapSize: e, verticalPixelRatio: i }) { 6142 if (this.qv.N().timeScale.borderVisible) { 6143 t.fillStyle = this.Yw(); 6144 const r = Math.max(1, Math.floor(this.Uw().S * i)); 6145 t.fillRect(0, 0, e.width, r); 6146 } 6147 } 6148 Im(t) { 6149 const e = this.qv.Qt().Et(), i = e.El(); 6150 if (!i || i.length === 0) 6151 return; 6152 const r = this.xu.maxTickMarkWeight(i), n = this.Uw(), a = e.N(); 6153 a.borderVisible && a.ticksVisible && t.useBitmapCoordinateSpace(({ context: o, horizontalPixelRatio: l, verticalPixelRatio: h }) => { 6154 o.strokeStyle = this.Yw(), o.fillStyle = this.Yw(); 6155 const c = Math.max(1, Math.floor(l)), d = Math.floor(0.5 * l); 6156 o.beginPath(); 6157 const f = Math.round(n.C * h); 6158 for (let m = i.length; m--; ) { 6159 const p = Math.round(i[m].coord * l); 6160 o.rect(p - d, 0, c, f); 6161 } 6162 o.fill(); 6163 }), t.useMediaCoordinateSpace(({ context: o }) => { 6164 const l = n.S + n.C + n.A + n.k / 2; 6165 o.textAlign = "center", o.textBaseline = "middle", o.fillStyle = this.H(), o.font = this.Sm(); 6166 for (const h of i) 6167 if (h.weight < r) { 6168 const c = h.needAlignCoordinate ? this.Kw(o, h.coord, h.label) : h.coord; 6169 o.fillText(h.label, c, l); 6170 } 6171 this.qv.N().timeScale.allowBoldLabels && (o.font = this.Zw()); 6172 for (const h of i) 6173 if (h.weight >= r) { 6174 const c = h.needAlignCoordinate ? this.Kw(o, h.coord, h.label) : h.coord; 6175 o.fillText(h.label, c, l); 6176 } 6177 }); 6178 } 6179 Kw(t, e, i) { 6180 const r = this.im.Ii(t, i), n = r / 2, a = Math.floor(e - n) + 0.5; 6181 return a < 0 ? e += Math.abs(0 - a) : a + r > this.Qv.width && (e -= Math.abs(this.Qv.width - (a + r))), e; 6182 } 6183 qw(t, e) { 6184 const i = this.Uw(); 6185 for (const r of t) 6186 for (const n of r.dn()) 6187 n.Tt().st(e, i); 6188 } 6189 Yw() { 6190 return this.qv.N().timeScale.borderColor; 6191 } 6192 H() { 6193 return this.yn.textColor; 6194 } 6195 F() { 6196 return this.yn.fontSize; 6197 } 6198 Sm() { 6199 return fi(this.F(), this.yn.fontFamily); 6200 } 6201 Zw() { 6202 return fi(this.F(), this.yn.fontFamily, "bold"); 6203 } 6204 Uw() { 6205 this.M === null && (this.M = { S: 1, L: NaN, A: NaN, I: NaN, tn: NaN, C: 5, k: NaN, P: "", Qi: new mi(), $w: 0 }); 6206 const t = this.M, e = this.Sm(); 6207 if (t.P !== e) { 6208 const i = this.F(); 6209 t.k = i, t.P = e, t.A = 3 * i / 12, t.I = 3 * i / 12, t.tn = 9 * i / 12, t.L = 0, t.$w = 4 * i / 12, t.Qi.Os(); 6210 } 6211 return this.M; 6212 } 6213 Em(t) { 6214 this.lv.style.cursor = t === 1 ? "ew-resize" : "default"; 6215 } 6216 zw() { 6217 const t = this.qv.Qt(), e = t.N(); 6218 e.leftPriceScale.visible || this.Dw === null || (this.Ew.removeChild(this.Dw.uv()), this.Dw.m(), this.Dw = null), e.rightPriceScale.visible || this.Iw === null || (this.Aw.removeChild(this.Iw.uv()), this.Iw.m(), this.Iw = null); 6219 const i = { Zd: this.qv.Qt().Zd() }, r = () => e.leftPriceScale.borderVisible && t.Et().N().borderVisible, n = () => t.ef(); 6220 e.leftPriceScale.visible && this.Dw === null && (this.Dw = new Kr("left", e, i, r, n), this.Ew.appendChild(this.Dw.uv())), e.rightPriceScale.visible && this.Iw === null && (this.Iw = new Kr("right", e, i, r, n), this.Aw.appendChild(this.Iw.uv())); 6221 } 6222 }; 6223 var wn; 6224 var vl = !!be && !!navigator.userAgentData && navigator.userAgentData.brands.some((s) => s.brand.includes("Chromium")) && !!be && ((wn = navigator == null ? void 0 : navigator.userAgentData) != null && wn.platform ? navigator.userAgentData.platform === "Windows" : navigator.userAgent.toLowerCase().indexOf("win") >= 0); 6225 var bl = class { 6226 constructor(t, e, i) { 6227 var r; 6228 this.Gw = [], this.Xw = [], this.Jw = 0, this.ho = 0, this.C_ = 0, this.Qw = 0, this.tM = 0, this.iM = null, this.nM = false, this.Wm = new Y(), this.Hm = new Y(), this.pd = new Y(), this.sM = null, this.eM = null, this.jv = t, this.yn = e, this.xu = i, this.Hv = document.createElement("div"), this.Hv.classList.add("tv-lightweight-charts"), this.Hv.style.overflow = "hidden", this.Hv.style.direction = "ltr", this.Hv.style.width = "100%", this.Hv.style.height = "100%", (r = this.Hv).style.userSelect = "none", r.style.webkitUserSelect = "none", r.style.msUserSelect = "none", r.style.MozUserSelect = "none", r.style.webkitTapHighlightColor = "transparent", this.rM = document.createElement("table"), this.rM.setAttribute("cellspacing", "0"), this.Hv.appendChild(this.rM), this.hM = this.aM.bind(this), Gi(this.yn) && this.lM(true), this.sn = new el(this.md.bind(this), this.yn, i), this.Qt().Dd().i(this.oM.bind(this), this), this._M = new gl(this, this.xu), this.rM.appendChild(this._M.uv()); 6229 const n = e.autoSize && this.uM(); 6230 let a = this.yn.width, o = this.yn.height; 6231 if (n || a === 0 || o === 0) { 6232 const l = t.getBoundingClientRect(); 6233 a = a || l.width, o = o || l.height; 6234 } 6235 this.cM(a, o), this.dM(), t.appendChild(this.Hv), this.fM(), this.sn.Et().Zc().i(this.sn.Pa.bind(this.sn), this), this.sn.L_().i(this.sn.Pa.bind(this.sn), this); 6236 } 6237 Qt() { 6238 return this.sn; 6239 } 6240 N() { 6241 return this.yn; 6242 } 6243 rv() { 6244 return this.Gw; 6245 } 6246 pM() { 6247 return this._M; 6248 } 6249 m() { 6250 this.lM(false), this.Jw !== 0 && window.cancelAnimationFrame(this.Jw), this.sn.Dd().u(this), this.sn.Et().Zc().u(this), this.sn.L_().u(this), this.sn.m(); 6251 for (const t of this.Gw) 6252 this.rM.removeChild(t.uv()), t.dw().u(this), t.fw().u(this), t.m(); 6253 this.Gw = []; 6254 for (const t of this.Xw) 6255 this.vM(t); 6256 this.Xw = [], k(this._M).m(), this.Hv.parentElement !== null && this.Hv.parentElement.removeChild(this.Hv), this.pd.m(), this.Wm.m(), this.Hm.m(), this.mM(); 6257 } 6258 cM(t, e, i = false) { 6259 if (this.ho === e && this.C_ === t) 6260 return; 6261 const r = (function(o) { 6262 const l = Math.floor(o.width), h = Math.floor(o.height); 6263 return B({ width: l - l % 2, height: h - h % 2 }); 6264 })(B({ width: t, height: e })); 6265 this.ho = r.height, this.C_ = r.width; 6266 const n = this.ho + "px", a = this.C_ + "px"; 6267 if (this.wM() || (k(this.Hv).style.height = n, k(this.Hv).style.width = a), this.rM.style.height = n, this.rM.style.width = a, i) { 6268 this.Jw !== 0 && (window.cancelAnimationFrame(this.Jw), this.Jw = 0), this.nM = false;
6269 const o = tt.ys(); 6270 this.iM !== null && (o.Ss(this.iM), this.iM = null), this.MM(o, performance.now()); 6271 } else 6272 this.sn.Pa(); 6273 } 6274 km(t) { 6275 t === void 0 && (t = tt.ys()); 6276 for (let e = 0; e < this.Gw.length; e++) 6277 this.Gw[e].km(t._s(e).rs); 6278 this.yn.timeScale.visible && this._M.km(t.ls()); 6279 } 6280 vr(t) { 6281 var r; 6282 const e = Gi(this.yn); 6283 this.sn.vr(t); 6284 const i = Gi(this.yn); 6285 i !== e && this.lM(i), (r = t.layout) != null && r.panes && this.gM(), this.fM(), this.bM(t); 6286 } 6287 dw() { 6288 return this.Wm; 6289 } 6290 fw() { 6291 return this.Hm; 6292 } 6293 Dd() { 6294 return this.pd; 6295 } 6296 SM(t = false) { 6297 this.iM !== null && (this.MM(this.iM, performance.now()), this.iM = null); 6298 const e = this.xM(null), i = document.createElement("canvas"); 6299 i.width = e.width, i.height = e.height; 6300 const r = k(i.getContext("2d")); 6301 return this.xM(r, t), i; 6302 } 6303 CM(t) { 6304 return t === "left" && !this.yM() || t === "right" && !this.kM() || this.Gw.length === 0 ? 0 : k(t === "left" ? this.Gw[0].Sw() : this.Gw[0].xw()).ym(); 6305 } 6306 wM() { 6307 return this.yn.autoSize && this.sM !== null; 6308 } 6309 vv() { 6310 return this.Hv; 6311 } 6312 PM(t) { 6313 this.eM = t, this.eM ? this.vv().style.setProperty("cursor", t) : this.vv().style.removeProperty("cursor"); 6314 } 6315 TM() { 6316 return this.eM; 6317 } 6318 RM(t) { 6319 return ct(this.Gw[t]).cv(); 6320 } 6321 gM() { 6322 this.Xw.forEach((t) => { 6323 t.kt(); 6324 }); 6325 } 6326 bM(t) { 6327 (t.autoSize !== void 0 || !this.sM || t.width === void 0 && t.height === void 0) && (t.autoSize && !this.sM && this.uM(), t.autoSize === false && this.sM !== null && this.mM(), t.autoSize || t.width === void 0 && t.height === void 0 || this.cM(t.width || this.C_, t.height || this.ho)); 6328 } 6329 xM(t, e) { 6330 let i = 0, r = 0; 6331 const n = this.Gw[0], a = (l, h) => { 6332 let c = 0; 6333 for (let d = 0; d < this.Gw.length; d++) { 6334 const f = this.Gw[d], m = k(l === "left" ? f.Sw() : f.xw()), p = m.dv(); 6335 if (t !== null && m.fv(t, h, c, e), c += p.height, d < this.Gw.length - 1) { 6336 const v = this.Xw[d], b = v.dv(); 6337 t !== null && v.fv(t, h, c), c += b.height; 6338 } 6339 } 6340 }; 6341 this.yM() && (a("left", 0), i += k(n.Sw()).dv().width); 6342 for (let l = 0; l < this.Gw.length; l++) { 6343 const h = this.Gw[l], c = h.dv(); 6344 if (t !== null && h.fv(t, i, r, e), r += c.height, l < this.Gw.length - 1) { 6345 const d = this.Xw[l], f = d.dv(); 6346 t !== null && d.fv(t, i, r), r += f.height; 6347 } 6348 } 6349 i += n.dv().width, this.kM() && (a("right", i), i += k(n.xw()).dv().width); 6350 const o = (l, h, c) => { 6351 k(l === "left" ? this._M.Ow() : this._M.Nw()).fv(k(t), h, c); 6352 }; 6353 if (this.yn.timeScale.visible) { 6354 const l = this._M.dv(); 6355 if (t !== null) { 6356 let h = 0; 6357 this.yM() && (o("left", h, r), h = k(n.Sw()).dv().width), this._M.fv(t, h, r, e), h += l.width, this.kM() && o("right", h, r); 6358 } 6359 r += l.height; 6360 } 6361 return B({ width: i, height: r }); 6362 } 6363 DM() { 6364 let t = 0, e = 0, i = 0; 6365 for (const b of this.Gw) 6366 this.yM() && (e = Math.max(e, k(b.Sw()).bm(), this.yn.leftPriceScale.minimumWidth)), this.kM() && (i = Math.max(i, k(b.xw()).bm(), this.yn.rightPriceScale.minimumWidth)), t += b.z_(); 6367 e = fs(e), i = fs(i); 6368 const r = this.C_, n = this.ho, a = Math.max(r - e - i, 0), o = 1 * this.Xw.length, l = this.yn.timeScale.visible; 6369 let h = l ? Math.max(this._M.Hw(), this.yn.timeScale.minimumHeight) : 0; 6370 var c; 6371 h = (c = h) + c % 2; 6372 const d = o + h, f = n < d ? 0 : n - d, m = f / t; 6373 let p = 0; 6374 const v = window.devicePixelRatio || 1; 6375 for (let b = 0; b < this.Gw.length; ++b) { 6376 const y = this.Gw[b]; 6377 y.iw(this.sn.Zn()[b]); 6378 let x = 0, S = 0; 6379 S = b === this.Gw.length - 1 ? Math.ceil((f - p) * v) / v : Math.round(y.z_() * m * v) / v, x = Math.max(S, 2), p += x, y.Cm(B({ width: a, height: x })), this.yM() && y.mw(e, "left"), this.kM() && y.mw(i, "right"), y.Sv() && this.sn.Id(y.Sv(), x); 6380 } 6381 this._M.Ww(B({ width: l ? a : 0, height: h }), l ? e : 0, l ? i : 0), this.sn.N_(a), this.Qw !== e && (this.Qw = e), this.tM !== i && (this.tM = i); 6382 } 6383 lM(t) { 6384 t ? this.Hv.addEventListener("wheel", this.hM, { passive: false }) : this.Hv.removeEventListener("wheel", this.hM); 6385 } 6386 IM(t) { 6387 switch (t.deltaMode) { 6388 case t.DOM_DELTA_PAGE: 6389 return 120; 6390 case t.DOM_DELTA_LINE: 6391 return 32; 6392 } 6393 return vl ? 1 / window.devicePixelRatio : 1; 6394 } 6395 aM(t) { 6396 if (!(t.deltaX !== 0 && this.yn.handleScroll.mouseWheel || t.deltaY !== 0 && this.yn.handleScale.mouseWheel)) 6397 return; 6398 const e = this.IM(t), i = e * t.deltaX / 100, r = -e * t.deltaY / 100; 6399 if (t.cancelable && t.preventDefault(), r !== 0 && this.yn.handleScale.mouseWheel) { 6400 const n = Math.sign(r) * Math.min(1, Math.abs(r)), a = t.clientX - this.Hv.getBoundingClientRect().left; 6401 this.Qt().Od(a, n); 6402 } 6403 i !== 0 && this.yn.handleScroll.mouseWheel && this.Qt().Nd(-80 * i); 6404 } 6405 MM(t, e) { 6406 var r; 6407 const i = t.ls(); 6408 i === 3 && this.VM(), i !== 3 && i !== 2 || (this.BM(t), this.EM(t, e), this._M.kt(), this.Gw.forEac
6408h((n) => { 6409 n.sw(); 6410 }), ((r = this.iM) == null ? void 0 : r.ls()) === 3 && (this.iM.Ss(t), this.VM(), this.BM(this.iM), this.EM(this.iM, e), t = this.iM, this.iM = null)), this.km(t); 6411 } 6412 EM(t, e) { 6413 for (const i of t.bs()) 6414 this.xs(i, e); 6415 } 6416 BM(t) { 6417 const e = this.sn.Zn(); 6418 for (let i = 0; i < e.length; i++) 6419 t._s(i).hs && e[i].ru(); 6420 } 6421 xs(t, e) { 6422 const i = this.sn.Et(); 6423 switch (t.ds) { 6424 case 0: 6425 i.Xc(); 6426 break; 6427 case 1: 6428 i.Jc(t.Wt); 6429 break; 6430 case 2: 6431 i.Ms(t.Wt); 6432 break; 6433 case 3: 6434 i.gs(t.Wt); 6435 break; 6436 case 4: 6437 i.Oc(); 6438 break; 6439 case 5: 6440 t.Wt.jc(e) || i.gs(t.Wt.qc(e)); 6441 } 6442 } 6443 md(t) { 6444 this.iM !== null ? this.iM.Ss(t) : this.iM = t, this.nM || (this.nM = true, this.Jw = window.requestAnimationFrame((e) => { 6445 if (this.nM = false, this.Jw = 0, this.iM !== null) { 6446 const i = this.iM; 6447 this.iM = null, this.MM(i, e); 6448 for (const r of i.bs()) 6449 if (r.ds === 5 && !r.Wt.jc(e)) { 6450 this.Qt().ps(r.Wt); 6451 break; 6452 } 6453 } 6454 })); 6455 } 6456 VM() { 6457 this.dM(); 6458 } 6459 vM(t) { 6460 this.rM.removeChild(t.uv()), t.m(); 6461 } 6462 dM() { 6463 const t = this.sn.Zn(), e = t.length, i = this.Gw.length; 6464 for (let r = e; r < i; r++) { 6465 const n = ct(this.Gw.pop()); 6466 this.rM.removeChild(n.uv()), n.dw().u(this), n.fw().u(this), n.m(); 6467 const a = this.Xw.pop(); 6468 a !== void 0 && this.vM(a); 6469 } 6470 for (let r = i; r < e; r++) { 6471 const n = new Ts(this, t[r]); 6472 if (n.dw().i(this.AM.bind(this, n), this), n.fw().i(this.LM.bind(this, n), this), this.Gw.push(n), r > 0) { 6473 const a = new ll(this, r - 1, r); 6474 this.Xw.push(a), this.rM.insertBefore(a.uv(), this._M.uv()); 6475 } 6476 this.rM.insertBefore(n.uv(), this._M.uv()); 6477 } 6478 for (let r = 0; r < e; r++) { 6479 const n = t[r], a = this.Gw[r]; 6480 a.Sv() !== n ? a.iw(n) : a.tw(); 6481 } 6482 this.fM(), this.DM(); 6483 } 6484 zM(t, e, i, r) { 6485 var c; 6486 const n = /* @__PURE__ */ new Map();
6487 t !== null && this.sn.Jn().forEach((d) => { 6488 const f = d.Un().Hn(t); 6489 f !== null && n.set(d, f); 6490 }); 6491 let a; 6492 if (t !== null) { 6493 const d = (c = this.sn.Et().en(t)) == null ? void 0 : c.originalTime; 6494 d !== void 0 && (a = d); 6495 } 6496 const o = this.Qt().ou(), l = this.OM(r), h = (function(d, f) { 6497 var x; 6498 const m = d !== null && d.lu instanceof Si ? d.lu : void 0, p = (x = d == null ? void 0 : d.wu) == null ? void 0 : x.te, v = f !== void 0 && f !== -1 ? f : void 0; 6499 return d === null || d.ee === void 0 ? { NM: m, FM: p } : { NM: m, FM: p, WM: { ds: d.ee, HM: (b = d.lu, y = d.ee, b instanceof cs ? "pane-primitive" : y === "marker" || y === "primitive" ? "series-primitive" : "series"), UM: al(d.ee, p), U_: m, $M: p, jM: v } }; 6500 var b, y; 6501 })(o, l); 6502 return { Qr: a, $n: t != null ? t : void 0, qM: e != null ? e : void 0, jM: l !== -1 ? l : void 0, NM: h.NM, YM: n, FM: h.FM, WM: h.WM, KM: i != null ? i : void 0 }; 6503 } 6504 OM(t) { 6505 let e = -1; 6506 if (t) 6507 e = this.Gw.indexOf(t); 6508 else { 6509 const i = this.Qt().Rd().Kn(); 6510 i !== null && (e = this.Qt().Zn().indexOf(i)); 6511 } 6512 return e; 6513 } 6514 AM(t, e, i, r) { 6515 this.Wm.p(() => this.zM(e, i, r, t)); 6516 } 6517 LM(t, e, i, r) { 6518 this.Hm.p(() => this.zM(e, i, r, t)); 6519 } 6520 oM(t, e, i) { 6521 var r, n; 6522 this.PM((n = (r = this.Qt().ou()) == null ? void 0 : r.mu) != null ? n : null), this.pd.p(() => this.zM(t, e, i)); 6523 } 6524 fM() { 6525 const t = this.yn.timeScale.visible ? "" : "none"; 6526 this._M.uv().style.display = t; 6527 } 6528 yM() { 6529 return this.Gw[0].Sv().K_().N().visible; 6530 } 6531 kM() { 6532 return this.Gw[0].Sv().Z_().N().visible; 6533 } 6534 uM() { 6535 return "ResizeObserver" in window && (this.sM = new ResizeObserver((t) => { 6536 const e = t[t.length - 1]; 6537 if (!e) 6538 return; 6539 const i = e.contentRect.width, r = e.contentRect.height; 6540 this.cM(i, r, true); 6541 }), this.sM.observe(this.jv, { box: "border-box" }), true); 6542 } 6543 mM() { 6544 this.sM !== null && this.sM.disconnect(), this.sM = null; 6545 } 6546 }; 6547 function Gi(s) { 6548 return !!(s.handleScroll.mouseWheel || s.handleScale.mouseWheel); 6549 } 6550 function yl(s) { 6551 return s.open === void 0 && s.value === void 0; 6552 } 6553 function wl(s) { 6554 return (function(t) { 6555 return t.open !== void 0; 6556 })(s) || (function(t) { 6557 return t.value !== void 0; 6558 })(s); 6559 } 6560 function Zr(s, t, e, i) { 6561 const r = e.value, n = { $n: t, wt: s, Wt: [r, r, r, r], Qr: i }; 6562 return e.color !== void 0 && (n.R = e.color), n; 6563 } 6564 function xl(s, t, e, i) { 6565 const r = e.value, n = { $n: t, wt: s, Wt: [r, r, r, r], Qr: i }; 6566 return e.lineColor !== void 0 && (n.vt = e.lineColor), e.topColor !== void 0 && (n.ah = e.topColor), e.bottomColor !== void 0 && (n.oh = e.bottomColor), n; 6567 } 6568 function kl(s, t, e, i) { 6569 const r = e.value, n = { $n: t, wt: s, Wt: [r, r, r, r], Qr: i }; 6570 return e.topLineColor !== void 0 && (n._h = e.topLineColor), e.bottomLineColor !== void 0 && (n.uh = e.bottomLineColor), e.topFillColor1 !== void 0 && (n.dh = e.topFillColor1), e.topFillColor2 !== void 0 && (n.fh = e.topFillColor2), e.bottomFillColor1 !== void 0 && (n.ph = e.bottomFillColor1), e.bottomFillColor2 !== void 0 && (n.mh = e.bottomFillColor2), n; 6571 } 6572 function Sl(s, t, e, i) { 6573 const r = { $n: t, wt: s, Wt: [e.open, e.high, e.low, e.close], Qr: i }; 6574 return e.color !== void 0 && (r.R = e.color), r; 6575 } 6576 function Cl(s, t, e, i) { 6577 const r = { $n: t, wt: s, Wt: [e.open, e.high, e.low, e.close], Qr: i }; 6578 return e.color !== void 0 && (r.R = e.color), e.borderColor !== void 0 && (r.Ht = e.borderColor), e.wickColor !== void 0 && (r.hh = e.wickColor), r; 6579 } 6580 function _l(s, t, e, i, r) { 6581 const n = ct(r)(e), a = Math.max(...n), o = Math.min(...n), l = n[n.length - 1], h = [l, a, o, l], m = e, { time: c, color: d } = m, f = tr(m, ["time", "color"]); 6582 return { $n: t, wt: s, Wt: h, Qr: i, ue: f, R: d }; 6583 } 6584 function he(s) { 6585 return s.Wt !== void 0; 6586 } 6587 function Gr(s, t) { 6588 return t.customValues !== void 0 && (s.ZM = t.customValues), s; 6589 } 6590 function Qt(s) { 6591 return (t, e, i, r, n, a) => (function(o, l) { 6592 return l ? l(o) : yl(o); 6593 })(i, a) ? Gr({ wt: t, $n: e, Qr: r }, i) : Gr(s(t, e, i, r, n), i); 6594 } 6595 function Xr(s) { 6596 return { Candlestick: Qt(Cl), Bar: Qt(Sl), Area: Qt(xl), Baseline: Qt(kl), Histogram: Qt(Zr), Line: Qt(Zr), Custom: Qt(_l) }[s]; 6597 } 6598 function Jr(s) { 6599 return { $n: 0, GM: /* @__PURE__ */ new Map(), za: s }; 6600 } 6601 function tn(s, t) { 6602 if (s !== void 0 && s.length !== 0) 6603 return { XM: t.key(s[0].wt), JM: t.key(s[s.length - 1].wt) }; 6604 } 6605 function en(s) { 6606 let t;
6607 return s.forEach((e) => { 6608 t === void 0 && (t = e.Qr); 6609 }), ct(t); 6610 } 6611 var $l = class { 6612 constructor(t) { 6613 this.QM = /* @__PURE__ */ new Map(), this.tg = /* @__PURE__ */ new Map(), this.ig = /* @__PURE__ */ new Map(), this.ng = [], this.xu = t; 6614 } 6615 m() { 6616 this.QM.clear(), this.tg.clear(), this.ig.clear(), this.ng = []; 6617 } 6618 sg(t, e) { 6619 let i = this.QM.size !== 0, r = false; 6620 const n = this.tg.get(t); 6621 if (n !== void 0) 6622 if (this.tg.size === 1) 6623 i = false, r = true, this.QM.clear(); 6624 else 6625 for (const l of this.ng) 6626 l.pointData.GM.delete(t) && (r = true); 6627 let a = []; 6628 if (e.length !== 0) { 6629 const l = e.map((m) => m.time), h = this.xu.createConverterToInternalObj(e), c = Xr(t.bh()), d = t.ll(), f = t.ol(); 6630 a = e.map((m, p) => { 6631 const v = h(m.time), b = this.xu.key(v); 6632 let y = this.QM.get(b); 6633 y === void 0 && (y = Jr(v), this.QM.set(b, y), r = true); 6634 const x = c(v, y.$n, m, l[p], d, f); 6635 return y.GM.set(t, x), x; 6636 }); 6637 } 6638 i && this.eg(), this.rg(t, a); 6639 let o = -1; 6640 if (r) { 6641 const l = []; 6642 this.QM.forEach((h) => { 6643 l.push({ timeWeight: 0, time: h.za, pointData: h, originalTime: en(h.GM) }); 6644 }), l.sort((h, c) => this.xu.key(h.time) - this.xu.key(c.time)), o = this.hg(l); 6645 } 6646 return this.ag(t, o, (function(l, h, c) { 6647 const d = tn(l, c), f = tn(h, c); 6648 if (d !== void 0 && f !== void 0) 6649 return { lg: false, Ia: d.JM >= f.JM && d.XM >= f.XM }; 6650 })(this.tg.get(t), n, this.xu)); 6651 } 6652 Jd(t) { 6653 return this.sg(t, []); 6654 } 6655 og(t, e, i) { 6656 if (i && t.Na()) 6657 throw new Error("Historical updates are not supported when conflation is enabled. Conflation requires data to be processed in order."); 6658 const r = e; 6659 (function(y) { 6660 y.Qr === void 0 && (y.Qr = y.time); 6661 })(r), this.xu.preprocessData(e); 6662 const n = this.xu.createConverterToInternalObj([e])(e.time), a = this.ig.get(t); 6663 if (!i && a !== void 0 && this.xu.key(n) < this.xu.key(a)) 6664 throw new Error(`Cannot update oldest data, last time=${a}, new time=${n}`); 6665 let o = this.QM.get(this.xu.key(n)); 6666 if (i && o === void 0) 6667 throw new Error("Cannot update non-existing data point when historicalUpdate is true"); 6668 const l = o === void 0; 6669 o === void 0 && (o = Jr(n), this.QM.set(this.xu.key(n), o)); 6670 const h = Xr(t.bh()), c = t.ll(), d = t.ol(), f = h(n, o.$n, e, r.Qr, c, d), m = !i && !l && a !== void 0 && this.xu.key(n) === this.xu.key(a); 6671 o.GM.set(t, f), i ? this._g(t, f, o.$n) : m && t.Na() && he(f) ? (t.Rr(f), this.ug(t, f)) : this.ug(t, f); 6672 const p = { Ia: he(f), lg: i }; 6673 if (!l) 6674 return this.ag(t, -1, p); 6675 const v = { timeWeight: 0, time: o.za, pointData: o, originalTime: en(o.GM) }, b = ie(this.ng, this.xu.key(v.time), (y, x) => this.xu.key(y.time) < x); 6676 this.ng.splice(b, 0, v); 6677 for (let y = b; y < this.ng.length; ++y) 6678 si(this.ng[y].pointData, y); 6679 return this.xu.fillWeightsForPoints(this.ng, b), this.ag(t, b, p); 6680 } 6681 cg(t, e) { 6682 const i = this.tg.get(t); 6683 if (i === void 0 || e <= 0) 6684 return [[], this.dg()]; 6685 e = Math.min(e, i.length); 6686 const r = i.splice(-e).reverse(); 6687 i.length === 0 ? this.ig.delete(t) : this.ig.set(t, i[i.length - 1].wt); 6688 for (const n of r) { 6689 const a = this.QM.get(this.xu.key(n.wt)); 6690 if (a && (a.GM.delete(t), a.GM.size === 0)) { 6691 this.QM.delete(this.xu.key(a.za)), this.ng.splice(a.$n, 1); 6692 for (let o = a.$n; o < this.ng.length; ++o) 6693 si(this.ng[o].pointData, o); 6694 } 6695 } 6696 return [r, this.ag(t, this.ng.length - 1, { lg: false, Ia: false })]; 6697 } 6698 ug(t, e) { 6699 let i = this.tg.get(t); 6700 i === void 0 && (i = [], this.tg.set(t, i)); 6701 const r = i.length !== 0 ? i[i.length - 1] : null; 6702 r === null || this.xu.key(e.wt) > this.xu.key(r.wt) ? he(e) && i.push(e) : he(e) ? i[i.length - 1] = e : i.splice(-1, 1), this.ig.set(t, e.wt); 6703 } 6704 _g(t, e, i) { 6705 const r = this.tg.get(t); 6706 if (r === void 0) 6707 return; 6708 const n = ie(r, i, (a, o) => a.$n < o); 6709 he(e) ? r[n] = e : r.splice(n, 1); 6710 } 6711 rg(t, e) { 6712 e.length !== 0 ? (this.tg.set(t, e.filter(he)), this.ig.set(t, e[e.length - 1].wt)) : (this.tg.delete(t), this.ig.delete(t)); 6713 } 6714 eg() { 6715 for (const t of this.ng) 6716 t.pointData.GM.size === 0 && this.QM.delete(this.xu.key(t.time)); 6717 } 6718 hg(t) { 6719 let e = -1; 6720 for (let i = 0; i < this.ng.length && i < t.length; ++i) { 6721 const r = this.ng[i], n = t[i]; 6722 if (this.xu.key(r.time) !== this.xu.key(n.time)) { 6723 e = i; 6724 break; 6725 } 6726 n.timeWeight = r.timeWeight, si(n.pointData, i); 6727 } 6728 if (e === -1 && this.ng.length !== t.length && (e = Math.min(this.ng.length, t.length)), e === -1) 6729 return -1; 6730 for (let i = e; i < t.length; ++i) 6731 si(t[i].pointData, i); 6732 return this.xu.fillWeightsForPoints(t, e), this.ng = t, e; 6733 } 6734 fg() { 6735 if (this.tg.size === 0) 6736 return null; 6737 let t = 0; 6738 return this.tg.forEach((e) => { 6739 e.length !== 0 && (t = Math.max(t, e[e.length - 1].$n)); 6740 }), t; 6741 } 6742 ag(t, e, i) { 6743 const r = this.dg(); 6744 if (e !== -1) 6745 this.tg.forEach((n, a) => { 6746 r.U_.set(a, { ue: n, pg: a === t ? i : void 0 }); 6747 }), this.tg.has(t) || r.U_.set(t, { ue: [], pg: i }), r.Et.vg = this.ng, r.Et.mg = e; 6748 else { 6749 const n = this.tg.get(t); 6750 r.U_.set(t, { ue: n || [], pg: i }); 6751 } 6752 return r; 6753 }
6754 dg() { 6755 return { U_: /* @__PURE__ */ new Map(), Et: { Pc: this.fg() } }; 6756 } 6757 }; 6758 function si(s, t) { 6759 s.$n = t, s.GM.forEach((e) => { 6760 e.$n = t; 6761 }); 6762 } 6763 function Dl(s, t) { 6764 return s._t < t; 6765 } 6766 function Ml(s, t) { 6767 return t < s._t; 6768 } 6769 function gs(s, t, e, i) { 6770 return ie(s, t, Dl, e, i); 6771 } 6772 function vs(s, t, e, i) { 6773 return Ps(s, t, Ml, e, i); 6774 } 6775 function hi(s, t, e) { 6776 return { ne: s, se: t, ee: e }; 6777 } 6778 function sn(s, t, e, i) { 6779 return s >= t - i && s <= e + i; 6780 } 6781 function ze(s, t, e, i, r, n) { 6782 const a = r - e, o = n - i; 6783 if (a === 0 && o === 0) 6784 return Math.hypot(s - e, t - i); 6785 const l = ((s - e) * a + (t - i) * o) / (a * a + o * o), h = Math.max(0, Math.min(1, l)), c = e + a * h, d = i + o * h; 6786 return Math.hypot(s - c, t - d); 6787 } 6788 var Xi = [0, 0]; 6789 function El(s, t, e) { 6790 return t === void 0 || t.wt !== s.wt - 1 ? s._t - e / 2 : (t._t + s._t) / 2; 6791 } 6792 function zl(s, t, e) { 6793 return t === void 0 || t.wt !== s.wt + 1 ? s._t + e / 2 : (s._t + t._t) / 2; 6794 } 6795 function Fl(s, t, e, i, r, n, a) { 6796 if (t === null || t.from >= t.to || s.length === 0) 6797 return null; 6798 const o = r / 2 + n, l = gs(s, e - o, t.from, t.to), h = vs(s, e + o, l, t.to); 6799 if (l >= h) 6800 return null; 6801 let c = Number.POSITIVE_INFINITY; 6802 for (let d = l; d < h; d++) { 6803 const f = s[d], m = d > t.from ? s[d - 1] : void 0, p = d < t.to - 1 ? s[d + 1] : void 0, v = El(f, m, r) - n, b = zl(f, p, r) + n; 6804 if (e < v || e > b) 6805 continue; 6806 a(f, Xi); 6807 const y = Xi[0], x = Xi[1], S = Math.min(y, x), w = Math.max(y, x), _ = S - n, D = w + n; 6808 if (i >= S && i <= w) 6809 c = Math.min(c, 0); 6810 else if (i >= _ && i <= D) { 6811 const z = Math.min(Math.abs(i - S), Math.abs(w - i)); 6812 c = Math.min(c, z); 6813 } 6814 } 6815 return Number.isFinite(c) ? hi(c, 0, "series-range") : null; 6816 } 6817 function Pl(s, t) { 6818 return s.wt < t; 6819 } 6820 function Al(s, t) { 6821 return t < s.wt; 6822 } 6823 function Tl(s, t, e) { 6824 const i = t.Oa(), r = t.bi(), n = ie(s, i, Pl), a = Ps(s, r, Al); 6825 if (!e) 6826 return { from: n, to: a }; 6827 let o = n, l = a; 6828 return n > 0 && n < s.length && s[n].wt >= i && (o = n - 1), a > 0 && a < s.length && s[a - 1].wt <= r && (l = a + 1), { from: o, to: l }; 6829 } 6830 var Zn = class { 6831 constructor(t, e, i) { 6832 this.wg = true, this.Mg = true, this.gg = true, this.bg = [], this.Sg = null, this.xg = -1, this.ae = t, this.le = e, this.Cg = i; 6833 } 6834 kt(t) { 6835 this.wg = true, t === "data" && (this.Mg = true), t === "options" && (this.gg = true); 6836 } 6837 Tt() { 6838 return this.ae.It() ? (this.yg(), this.Sg === null ? null : this.kg) : null; 6839 } 6840 Qs(t, e) { 6841 return this.ae.It() ? (this.yg(), this.Sg === null ? null : this.Pg(t, e)) : null; 6842 } 6843 Pg(t, e) { 6844 return null; 6845 } 6846 Tg() { 6847 this.bg = this.bg.map((t) => M(M({}, t), this.ae.Sa().Sh(t.wt))); 6848 } 6849 Rg() { 6850 this.Sg = null; 6851 } 6852 yg() { 6853 const t = this.le.Et(), e = t.N().enableConflation ? t.Qc() : 0; 6854 e !== this.xg && (this.Mg = true, this.xg = e), this.Mg && (this.Dg(), this.Mg = false), this.gg && (this.Tg(), this.gg = false), this.wg && (this.Ig(), this.wg = false); 6855 } 6856 Ig() { 6857 const t = this.ae.Ft(), e = this.le.Et(); 6858 if (this.Rg(), e.Gi() || t.Gi()) 6859 return; 6860 const i = e.Ee(); 6861 if (i === null || this.ae.Un().Th() === 0) 6862 return; 6863 const r = this.ae.Lt(); 6864 r !== null && (this.Sg = Tl(this.bg, i, this.Cg), this.Vg(t, e, r.Wt), this.Bg()); 6865 } 6866 }; 6867 var Il = class { 6868 constructor(t, e) { 6869 this.Eg = t, this.Ki = e; 6870 } 6871 st(t, e, i) { 6872 this.Eg.draw(t, this.Ki, e, i); 6873 } 6874 }; 6875 function Rl(s) { 6876 switch (s) { 6877 case "point": 6878 return 2; 6879 case "range": 6880 return 0; 6881 default: 6882 return 1; 6883 } 6884 } 6885 var Ll = class extends Zn { 6886 constructor(t, e, i) { 6887 super(t, e, false), this.Yh = i, this.Eg = this.Yh.renderer(), this.kg = new Il(this.Eg, (r) => this.Ag(r)); 6888 } 6889 get ga() { 6890 return this.Yh.conflationReducer; 6891 } 6892 Wa(t) { 6893 return this.Yh.priceValueBuilder(t); 6894 } 6895 _l(t) { 6896 return this.Yh.isWhitespace(t); 6897 } 6898 Pg(t, e) { 6899 var a, o; 6900 const i = (o = (a = this.Eg).hitTest) == null ? void 0 : o.call(a, t, e, (l) => this.Ag(l)); 6901 if (i != null) 6902 return { ne: (r = i).distance, se: Rl(r.type), ee: "custom", mu: r.cursorStyle, te: r.objectId, ie: r.hitTestData }; 6903 var r; 6904 const n = Fl(this.bg, this.Sg, t, e, this.le.Et().fl(), this.ae.N().hitTestTolerance, (l, h) => { 6905 const c = l.Lg; 6906 let d = NaN, f = NaN; 6907 if (c !== void 0 && !this.Yh.isWhitespace(c)) 6908 for (const m of this.Yh.priceValueBuilder(c)) { 6909 const p = this.Ag(m); 6910 p !== null && (d = Number.isNaN(d) ? p : Math.min(d, p), f = Number.isNaN(f) ? p : Math.max(f, p)); 6911 } 6912 h[0] = d, h[1] = f; 6913 }); 6914 return n === null ? null : G(M({}, n), { ee: "custom" }); 6915 } 6916 Dg() { 6917 const t = this.ae.Sa(); 6918 this.bg = this.ae.Ha().Bh().map((e) => G(M({ wt: e.$n, _t: NaN }, t.Sh(e.$n)), { Lg: e.ue })); 6919 } 6920 Vg(t, e) { 6921 e.Tc(this.bg, ls(this.Sg)); 6922 } 6923 Bg() { 6924 this.Yh.update({ bars: this.bg.map(Nl), barSpacing: this.le.Et().fl(), visibleRange: this.Sg, conflationFactor: this.le.Et().Qc() }, this.ae.N()); 6925 } 6926 Ag(t) { 6927 const e = this.ae.Lt(); 6928 return e === null ? null : this.ae.Ft().Nt(t, e.Wt); 6929 } 6930 }; 6931 function Nl(s) { 6932 return { x: s._t, time: s.wt, originalData: s.Lg, barColor: s.sh }; 6933 } 6934 var Bl = { color: "#2196f3" }; 6935 var Ol = (s, t, e) => { 6936 const i = Ot(e); 6937 return new Ll(s, t, i); 6938 }; 6939 function Rs(s) { 6940 const t = { value: s.Wt[3], time: s.Qr }; 6941 return s.ZM !== void 0 && (t.customValues = s.ZM), t; 6942 } 6943 function rn(s) { 6944 const t = Rs(s); 6945 return s.R !== void 0 && (t.color = s.R), t; 6946 } 6947 function ql(s) { 6948 const t = Rs(s); 6949 return s.vt !== void 0 && (t.lineColor = s.vt), s.ah !== void 0 && (t.topColor = s.ah), s.oh !== void 0 && (t.bottomColor = s.oh), t; 6950 } 6951 function Ul(s) { 6952 const t = Rs(s); 6953 return s._h !== void 0 && (t.topLineColor = s._h), s.uh !== void 0 && (t.bottomLineColor = s.uh), s.dh !== void 0 && (t.topFillColor1 = s.dh), s.fh !== void 0 && (t.topFillColor2 = s.fh), s.ph !== void 0 && (t.bottomFillColor1 = s.ph), s.mh !== void 0 && (t.bottomFillColor2 = s.mh), t;
6954 } 6955 function Gn(s) { 6956 const t = { open: s.Wt[0], high: s.Wt[1], low: s.Wt[2], close: s.Wt[3], time: s.Qr }; 6957 return s.ZM !== void 0 && (t.customValues = s.ZM), t; 6958 } 6959 function Vl(s) { 6960 const t = Gn(s); 6961 return s.R !== void 0 && (t.color = s.R), t; 6962 } 6963 function jl(s) { 6964 const t = Gn(s), { R: e, Ht: i, hh: r } = s; 6965 return e !== void 0 && (t.color = e), i !== void 0 && (t.borderColor = i), r !== void 0 && (t.wickColor = r), t; 6966 } 6967 function ci(s) { 6968 return { Area: ql, Line: rn, Baseline: Ul, Histogram: rn, Bar: Vl, Candlestick: jl, Custom: Hl }[s]; 6969 } 6970 function Hl(s) { 6971 const t = s.Qr; 6972 return G(M({}, s.ue), { time: t }); 6973 } 6974 var Wl = { vertLine: { color: "#9598A1", width: 1, style: 3, visible: true, labelVisible: true, labelBackgroundColor: "#131722" }, horzLine: { color: "#9598A1", width: 1, style: 3, visible: true, labelVisible: true, labelBackgroundColor: "#131722" }, mode: 1, doNotSnapToHiddenSeriesIndices: false }; 6975 var Ql = { vertLines: { color: "#D6DCDE", style: 0, visible: true }, horzLines: { color: "#D6DCDE", style: 0, visible: true } }; 6976 var Yl = { background: { type: "solid", color: "#FFFFFF" }, textColor: "#191919", fontSize: 12, fontFamily: An, panes: { enableResize: true, separatorColor: "#E0E3EB", separatorHoverColor: "rgba(178, 181, 189, 0.2)" }, attributionLogo: true, colorSpace: "srgb", colorParsers: [] }; 6977 var Ji = { autoScale: true, mode: 0, invertScale: false, alignLabels: true, borderVisible: true, borderColor: "#2B2B43", entireTextOnly: false, visible: false, ticksVisible: false, scaleMargins: { bottom: 0.1, top: 0.2 }, minimumWidth: 0, ensureEdgeTickMarksVisible: false, tickMarkDensity: 2.5 }; 6978 var Kl = { rightOffset: 0, barSpacing: 6, minBarSpacing: 0.5, maxBarSpacing: 0, fixLeftEdge: false, fixRightEdge: false, lockVisibleTimeRangeOnResize: false, rightBarStaysOnScroll: false, borderVisible: true, borderColor: "#2B2B43", visible: true, timeVisible: false, secondsVisible: true, shiftVisibleRangeOnNewBar: true, allowShiftVisibleRangeOnWhitespaceReplacement: false, ticksVisible: false, uniformDistribution: false, minimumHeight: 0, allowBoldLabels: true, ignoreWhitespaceIndices: false, enableConflation: false, conflationThresholdFactor: 1, precomputeConflationOnInit: false, precomputeConflationPriority: "background" }; 6979 function nn() { 6980 return { addDefaultPane: true, hoveredSeriesOnTop: true, width: 0, height: 0, autoSize: false, layout: Yl, crosshair: Wl, grid: Ql, overlayPriceScales: M({}, Ji), leftPriceScale: G(M({}, Ji), { visible: false }), rightPriceScale: G(M({}, Ji), { visible: true }), defaultVisiblePriceScaleId: "right", timeScale: Kl, localization: { locale: be ? navigator.language : "", dateFormat: "dd MMM 'yy" }, handleScroll: { mouseWheel: true, pressedMouseMove: true, horzTouchDrag: true, vertTouchDrag: true }, handleScale: { axisPressedMouseMove: { time: true, price: true }, axisDoubleClickReset: { time: true, price: true }, mouseWheel: true, pinch: true }, kineticScroll: { mouse: false, touch: true }, trackingMode: { exitMode: 1 } }; 6981 } 6982 var Xn = class { 6983 constructor(t, e, i) { 6984 this.sv = t, this.zg = e, this.Og = i != null ? i : 0; 6985 } 6986 applyOptions(t) { 6987 this.sv.Qt().Pd(this.zg, t, this.Og); 6988 } 6989 options() { 6990 return this.Ki().N(); 6991 } 6992 width() { 6993 return xi(this.zg) ? this.sv.CM(this.zg) : 0; 6994 } 6995 setVisibleRange(t) { 6996 this.setAutoScale(false), this.Ki().qo(new ot(t.from, t.to)); 6997 } 6998 getVisibleRange() { 6999 let t, e, i = this.Ki().ar(); 7000 if (i === null) 7001 return null; 7002 if (this.Ki().so()) { 7003 const r = this.Ki().M_(), n = Qn(r); 7004 i = ue(i, this.Ki().ro()), t = Number((Math.round(i.Je() / r) * r).toFixed(n)), e = Number((Math.round(i.Qe() / r) * r).toFixed(n)); 7005 } else 7006 t = i.Je(), e = i.Qe(); 7007 return { from: t, to: e }; 7008 } 7009 setAutoScale(t) { 7010 this.applyOptions({ autoScale: t }); 7011 } 7012 Ki() { 7013 return k(this.sv.Qt().Td(this.zg, this.Og)).Ft; 7014 } 7015 }; 7016 var Zl = class { 7017 constructor(t, e, i, r) { 7018 this.sv = t, this.yt = i, this.Ng = e, this.Fg = r; 7019 } 7020 getHeight() { 7021 return this.yt.$t(); 7022 } 7023 setHeight(t) { 7024 const e = this.sv.Qt(), i = e.hf(this.yt); 7025 e.Bd(i, t); 7026 } 7027 getStretchFactor() { 7028 return this.yt.z_(); 7029 } 7030 setStretchFactor(t) { 7031 this.yt.O_(t), this.sv.Qt().Pa(); 7032 } 7033 paneIndex() { 7034 return this.sv.Qt().hf(this.yt); 7035 } 7036 moveTo(t) { 7037 const e = this.paneIndex(); 7038 e !== t && (et(t >= 0 && t < this.sv.rv().length, "Invalid pane index"), this.sv.Qt().Ad(e, t)); 7039 } 7040 getSeries() { 7041 var t; 7042 return (t = this.yt.U_().map((e) => this.Ng(e))) != null ? t : []; 7043 } 7044 getHTMLElement() { 7045 const t = this.sv.rv(); 7046 return t && t.length !== 0 && t[this.paneIndex()] ? t[this.paneIndex()].uv() : null; 7047 } 7048 attachPrimitive(t) { 7049 this.yt.hl(t), t.attached && t.attached({ chart: this.Fg, requestUpdate: () => this.yt.Qt().Pa() }); 7050 } 7051 detachPrimitive(t) { 7052 this.yt.al(t); 7053 } 7054 priceScale(t) { 7055 if (this.yt.A_(t) === null) 7056 throw new Error(`Cannot find price scale with id: ${t}`); 7057 return new Xn(this.sv, t, this.paneIndex()); 7058 } 7059 setPreserveEmptyPane(t) { 7060 this.yt.W_(t); 7061 } 7062 preserveEmptyPane() { 7063 return this.yt.H_(); 7064 } 7065 addCustomSeries(t, e = {}, i = 0) { 7066 return this.Fg.addCustomSeries(t, e, i); 7067 } 7068 addSeries(t, e = {}) { 7069 return this.Fg.addSeries(t, e, this.paneIndex()); 7070 } 7071 }; 7072 var Gl = { color: "#FF0000", price: 0, lineStyle: 2, lineWidth: 1, lineVisible: true, axisLabelVisible: true, title: "", axisLabelColor: "", axisLabelTextColor: "" }; 7073 var an = class { 7074 constructor(t) { 7075 this._r = t; 7076 } 7077 applyOptions(t) { 7078 this._r.vr(t); 7079 } 7080 options() { 7081 return this._r.N(); 7082 } 7083 Wg() { 7084 return this._r; 7085 } 7086 }; 7087 var Xl = class { 7088 constructor(t, e, i, r, n, a) { 7089 this.Hg = new Y(), this.ae = t, this.Ug = e, this.$g = i, this.xu = n, this.Fg = r, this.jg = a; 7090 } 7091 m() { 7092 this.Hg.m(); 7093 } 7094 priceFormatter() { 7095 return this.ae.tl(); 7096 } 7097 priceToCoordinate(t) { 7098 const e = this.ae.Lt(); 7099 return e === null ? null : this.ae.Ft().Nt(t, e.Wt); 7100 } 7101 coordinateToPrice(t) { 7102 const e = this.ae.Lt(); 7103 return e === null ? null : this.ae.Ft().Tn(t, e.Wt); 7104 } 7105 barsInLogicalRange(t) { 7106 if (t === null) 7107 return null; 7108 const e = new me(new Ae(t.from, t.to)).Fu(), i = this.ae.Un(); 7109 if (i.Gi()) 7110 return null; 7111 const r = i.Hn(e.Oa(), 1), n = i.Hn(e.bi(), -1), a = k(i.Rh()), o = k(i.Qn()); 7112 if (r !== null && n !== null && r.$n > n.$n) 7113 return { barsBefore: t.from - a, barsAfter: o - t.to }; 7114 const l = { barsBefore: r === null || r.$n === a ? t.from - a : r.$n - a, barsAfter: n === null || n.$n === o ? o - t.to : o - n.$n }; 7115 return r !== null && n !== null && (l.from = r.Qr, l.to = n.Qr), l; 7116 } 7117 setData(t) { 7118 this.xu, this.ae.bh(), this.Ug.qg(this.ae, t), this.Yg("full"); 7119 } 7120 update(t, e = false) { 7121 this.ae.bh(), this.Ug.Kg(this.ae, t, e), this.Yg("update"); 7122 } 7123 pop(t = 1) { 7124 const e = this.Ug.Zg(this.ae, t); 7125 e.length !== 0 && this.Yg("update"); 7126 const i = ci(this.seriesType()); 7127 return e.map((r) => i(r)); 7128 } 7129 dataByIndex(t, e) { 7130 const i = this.ae.Un().Hn(t, e); 7131 return i === null ? null : ci(this.seriesType())(i); 7132 } 7133 data() { 7134 const t = ci(this.seriesType()); 7135 return this.ae.Un().Bh().map((e) => t(e)); 7136 } 7137 subscribeDataChanged(t) { 7138 this.Hg.i(t); 7139 } 7140 unsubscribeDataChanged(t) { 7141 this.Hg._(t); 7142 } 7143 applyOptions(t) { 7144 this.ae.vr(t); 7145 } 7146 options() { 7147 return zt(this.ae.N()); 7148 } 7149 priceScale() { 7150 return this.$g.priceScale(this.ae.Ft().cl(), this.getPane().paneIndex()); 7151 }
7152 createPriceLine(t) { 7153 const e = ft(zt(Gl), t), i = this.ae.Ba(e); 7154 return new an(i); 7155 } 7156 removePriceLine(t) { 7157 this.ae.Ea(t.Wg()); 7158 } 7159 priceLines() { 7160 return this.ae.Aa().map((t) => new an(t)); 7161 } 7162 seriesType() { 7163 return this.ae.bh(); 7164 } 7165 lastValueData(t) { 7166 const e = this.ae.Ae(t); 7167 return e.Le ? { noData: true } : { noData: false, price: e.Mt, color: e.R }; 7168 } 7169 attachPrimitive(t) { 7170 this.ae.hl(t), t.attached && t.attached({ chart: this.Fg, series: this, requestUpdate: () => this.ae.Qt().Pa(), horzScaleBehavior: this.xu }); 7171 } 7172 detachPrimitive(t) { 7173 this.ae.al(t), t.detached && t.detached(), this.ae.Qt().Pa(); 7174 } 7175 getPane() { 7176 const t = this.ae, e = k(this.ae.Qt().Ks(t)); 7177 return this.jg(e); 7178 } 7179 moveToPane(t) { 7180 this.ae.Qt().nf(this.ae, t); 7181 } 7182 seriesOrder() { 7183 const t = this.ae.Qt().Ks(this.ae); 7184 return t === null ? -1 : t.U_().indexOf(this.ae); 7185 } 7186 setSeriesOrder(t) { 7187 const e = this.ae.Qt().Ks(this.ae); 7188 e !== null && e.du(this.ae, t); 7189 } 7190 Yg(t) { 7191 this.Hg.v() && this.Hg.p(t); 7192 } 7193 }; 7194 var Jl = class { 7195 constructor(t, e, i) { 7196 this.Gg = new Y(), this.Gu = new Y(), this.Bw = new Y(), this.sn = t, this.ia = t.Et(), this._M = e, this.ia.Yc().i(this.Xg.bind(this)), this.ia.Kc().i(this.Jg.bind(this)), this._M.Fw().i(this.Qg.bind(this)), this.xu = i; 7197 } 7198 m() { 7199 this.ia.Yc().u(this), this.ia.Kc().u(this), this._M.Fw().u(this), this.Gg.m(), this.Gu.m(), this.Bw.m(); 7200 } 7201 scrollPosition() { 7202 return this.ia.Ac(); 7203 } 7204 scrollToPosition(t, e) { 7205 e ? this.ia.$c(t, 1e3) : this.sn.gs(t); 7206 } 7207 scrollToRealTime() { 7208 this.ia.Uc(); 7209 } 7210 getVisibleRange() { 7211 const t = this.ia.gc(); 7212 return t === null ? null : { from: t.from.originalTime, to: t.to.originalTime }; 7213 } 7214 setVisibleRange(t) { 7215 const e = { from: this.xu.convertHorzItemToInternal(t.from), to: this.xu.convertHorzItemToInternal(t.to) }, i = this.ia.Cc(e); 7216 this.sn.tf(i); 7217 } 7218 getVisibleLogicalRange() { 7219 const t = this.ia.Mc(); 7220 return t === null ? null : { from: t.Oa(), to: t.bi() }; 7221 } 7222 setVisibleLogicalRange(t) { 7223 et(t.from <= t.to, "The from index cannot be after the to index."), this.sn.tf(t); 7224 } 7225 resetTimeScale() { 7226 this.sn.ws(); 7227 } 7228 fitContent() { 7229 this.sn.Xc(); 7230 } 7231 logicalToCoordinate(t) { 7232 const e = this.sn.Et(); 7233 return e.Gi() ? null : e.jt(t); 7234 } 7235 coordinateToLogical(t) { 7236 return this.ia.Gi() ? null : this.ia.Rc(t); 7237 } 7238 timeToIndex(t, e) { 7239 const i = this.xu.convertHorzItemToInternal(t); 7240 return this.ia.vc(i, e); 7241 } 7242 timeToCoordinate(t) { 7243 const e = this.timeToIndex(t, false); 7244 return e === null ? null : this.ia.jt(e); 7245 } 7246 coordinateToTime(t) { 7247 const e = this.sn.Et(), i = e.Rc(t), r = e.en(i); 7248 return r === null ? null : r.originalTime; 7249 } 7250 width() { 7251 return this._M.cv().width; 7252 } 7253 height() { 7254 return this._M.cv().height; 7255 } 7256 subscribeVisibleTimeRangeChange(t) { 7257 this.Gg.i(t); 7258 } 7259 unsubscribeVisibleTimeRangeChange(t) { 7260 this.Gg._(t); 7261 } 7262 subscribeVisibleLogicalRangeChange(t) { 7263 this.Gu.i(t); 7264 } 7265 unsubscribeVisibleLogicalRangeChange(t) { 7266 this.Gu._(t); 7267 } 7268 subscribeSizeChange(t) { 7269 this.Bw.i(t); 7270 } 7271 unsubscribeSizeChange(t) { 7272 this.Bw._(t); 7273 } 7274 applyOptions(t) { 7275 this.ia.vr(t); 7276 } 7277 options() { 7278 return G(M({}, zt(this.ia.N())), { barSpacing: this.ia.fl() }); 7279 } 7280 Xg() { 7281 this.Gg.v() && this.Gg.p(this.getVisibleRange()); 7282 } 7283 Jg() { 7284 this.Gu.v() && this.Gu.p(this.getVisibleLogicalRange()); 7285 } 7286 Qg(t) { 7287 this.Bw.p(t.width, t.height); 7288 } 7289 }; 7290 function on(s) { 7291 return (function(t) { 7292 if (Ze(t.handleScale)) { 7293 const i = t.handleScale; 7294 t.handleScale = { axisDoubleClickReset: { time: i, price: i }, axisPressedMouseMove: { time: i, price: i }, mouseWheel: i, pinch: i }; 7295 } else if (t.handleScale !== void 0) { 7296 const { axisPressedMouseMove: i, axisDoubleClickReset: r } = t.handleScale; 7297 Ze(i) && (t.handleScale.axisPressedMouseMove = { time: i, price: i }), Ze(r) && (t.handleScale.axisDoubleClickReset = { time: r, price: r }); 7298 } 7299 const e = t.handleScroll; 7300 Ze(e) && (t.handleScroll = { horzTouchDrag: e, vertTouchDrag: e, mouseWheel: e, pressedMouseMove: e }); 7301 })(s), s; 7302 } 7303 var th = class { 7304 constructor(t, e, i) { 7305 this.tb = /* @__PURE__ */ new Map(), this.ib = /* @__PURE__ */ new Map(), this.nb = new Y(), this.sb = new Y(), this.eb = new Y(), this.od = /* @__PURE__ */ new WeakMap(), this.rb = new $l(e); 7306 const r = i === void 0 ? zt(nn()) : ft(zt(nn()), on(i)); 7307 this.hb = e, this.sv = new bl(t, r, e), this.sv.dw().i((a) => { 7308 this.nb.v() && this.nb.p(this.ab(a())); 7309 }, this), this.sv.fw().i((a) => { 7310 this.sb.v() && this.sb.p(this.ab(a())); 7311 }, this), this.sv.Dd().i((a) => { 7312 this.eb.v() && this.eb.p(this.ab(a())); 7313 }, this); 7314 const n = this.sv.Qt(); 7315 this.lb = new Jl(n, this.sv.pM(), this.hb); 7316 } 7317 remove() { 7318 this.sv.dw().u(this), this.sv.fw().u(this), this.sv.Dd().u(this), this.lb.m(), this.sv.m(), this.tb.clear(), this.ib.clear(), this.nb.m(), this.sb.m(), this.eb.m(), this.rb.m(); 7319 } 7320 resize(t, e, i) { 7321 this.autoSizeActive() || this.sv.cM(t, e, i); 7322 } 7323 addCustomSeries(t, e = {}, i = 0) { 7324 const r = ((n) =>
7324 ({ type: "Custom", isBuiltIn: false, defaultOptions: M(M({}, Bl), n.defaultOptions()), ob: Ol, _b: n }))(Ot(t)); 7325 return this.ub(r, e, i); 7326 } 7327 addSeries(t, e = {}, i = 0) { 7328 return this.ub(t, e, i); 7329 } 7330 removeSeries(t) { 7331 const e = ct(this.tb.get(t)), i = this.rb.Jd(e); 7332 this.sv.Qt().Jd(e), this.cb(i), this.tb.delete(t), this.ib.delete(e); 7333 } 7334 qg(t, e) { 7335 this.cb(this.rb.sg(t, e)); 7336 } 7337 Kg(t, e, i) { 7338 this.cb(this.rb.og(t, e, i)); 7339 } 7340 Zg(t, e) { 7341 const [i, r] = this.rb.cg(t, e); 7342 return i.length !== 0 && this.cb(r), i; 7343 } 7344 subscribeClick(t) { 7345 this.nb.i(t); 7346 } 7347 unsubscribeClick(t) { 7348 this.nb._(t); 7349 } 7350 subscribeCrosshairMove(t) { 7351 this.eb.i(t); 7352 } 7353 unsubscribeCrosshairMove(t) { 7354 this.eb._(t); 7355 } 7356 subscribeDblClick(t) { 7357 this.sb.i(t); 7358 } 7359 unsubscribeDblClick(t) { 7360 this.sb._(t); 7361 } 7362 priceScale(t, e = 0) { 7363 return new Xn(this.sv, t, e); 7364 } 7365 timeScale() { 7366 return this.lb; 7367 } 7368 applyOptions(t) { 7369 this.sv.vr(on(t)); 7370 } 7371 options() { 7372 return this.sv.N(); 7373 } 7374 takeScreenshot(t = false, e = false) { 7375 let i, r; 7376 try { 7377 e || (i = this.sv.Qt().N().crosshair.mode, this.sv.vr({ crosshair: { mode: 2 } })), r = this.sv.SM(t); 7378 } finally { 7379 e || i === void 0 || this.sv.Qt().vr({ crosshair: { mode: i } }); 7380 } 7381 return r; 7382 } 7383 addPane(t = false) { 7384 const e = this.sv.Qt().af(); 7385 return e.W_(t), this.fb(e); 7386 } 7387 removePane(t) { 7388 this.sv.Qt().Vd(t); 7389 } 7390 swapPanes(t, e) { 7391 this.sv.Qt().Ed(t, e); 7392 } 7393 autoSizeActive() { 7394 return this.sv.wM(); 7395 } 7396 chartElement() { 7397 return this.sv.vv(); 7398 } 7399 panes() { 7400 return this.sv.Qt().Zn().map((t) => this.fb(t)); 7401 } 7402 paneSize(t = 0) { 7403 const e = this.sv.RM(t); 7404 return { height: e.height, width: e.width }; 7405 } 7406 setCrosshairPosition(t, e, i) { 7407 const r = this.tb.get(i); 7408 if (r === void 0) 7409 return; 7410 const n = this.sv.Qt().Ks(r); 7411 n !== null && this.sv.Qt().qd(t, e, n); 7412 } 7413 clearCrosshairPosition() { 7414 this.sv.Qt().Yd(true); 7415 } 7416 horzBehaviour() { 7417 return this.hb; 7418 } 7419 ub(t, e = {}, i = 0) { 7420 et(t.ob !== void 0), (function(l) { 7421 if (l === void 0 || l.type === "custom") 7422 return; 7423 const h = l; 7424 h.minMove !== void 0 && h.precision === void 0 && (h.precision = Qn(h.minMove)); 7425 })(e.priceFormat), t.type === "Candlestick" && (function(l) { 7426 l.borderColor !== void 0 && (l.borderUpColor = l.borderColor, l.borderDownColor = l.borderColor), l.wickColor !== void 0 && (l.wickUpColor = l.wickColor, l.wickDownColor = l.wickColor); 7427 })(e); 7428 const r = ft(zt(Fn), zt(t.defaultOptions), e), n = t.ob, a = new Si(this.sv.Qt(), t.type, r, n, t._b); 7429 this.sv.Qt().Gd(a, i); 7430 const o = new Xl(a, this, this, this, this.hb, (l) => this.fb(l)); 7431 return this.tb.set(o, a), this.ib.set(a, o), o; 7432 } 7433 cb(t) { 7434 const e = this.sv.Qt(); 7435 e.Kd(t.Et.Pc, t.Et.vg, t.Et.mg), t.U_.forEach((i, r) => r.ht(i.ue, i.pg)), e.Et()._c(), e.Bc(); 7436 } 7437 pb(t) { 7438 return ct(this.ib.get(t)); 7439 } 7440 mb(t) { 7441 return t !== void 0 && this.ib.has(t) ? this.pb(t) : void 0; 7442 } 7443 ab(t) { 7444 const e = /* @__PURE__ */ new Map(); 7445 t.YM.forEach((n, a) => { 7446 const o = a.bh(), l = ci(o)(n); 7447 if (o !== "Custom") 7448 et(wl(l)); 7449 else { 7450 const h = a.ol(); 7451 et(!h || h(l) === false); 7452 } 7453 e.set(this.pb(a), l); 7454 }); 7455 const i = this.mb(t.NM), r = t.WM === void 0 ? void 0 : { type: t.WM.ds, sourceKind: t.WM.HM, objectKind: t.WM.UM, series: this.mb(t.WM.U_), objectId: t.WM.$M, paneIndex: t.WM.jM }; 7456 return { time: t.Qr, logical: t.$n, point: t.qM, paneIndex: t.jM, hoveredInfo: r, hoveredSeries: i, hoveredObjectId: t.FM, seriesData: e, sourceEvent: t.KM }; 7457 } 7458 fb(t) { 7459 let e = this.od.get(t); 7460 return e || (e = new Zl(this.sv, (i) => this.pb(i), t, this), this.od.set(t, e)), e; 7461 } 7462 }; 7463 function eh(s) { 7464 if (Ve(s)) { 7465 const t = document.getElementById(s); 7466 return et(t !== null, `Cannot find element in DOM with id=${s}`), t; 7467 } 7468 return s; 7469 } 7470 function ih(s, t, e) { 7471 const i = eh(s), r = new th(i, t, e); 7472 return t.setOptions(r.options()), r; 7473 } 7474 function sh(s, t) { 7475 return ih(s, new Ur(), Ur.yf(t)); 7476 } 7477 function Me(s, t, e, i) { 7478 return Math.hypot(e - s, i - t); 7479 } 7480 function Jn(s, t, e, i, r, n, a, o = 0) { 7481 if (t.length === 0 || i.from >= t.length || i.to <= 0) 7482 return; 7483 const { context: l, horizontalPixelRatio: h, verticalPixelRatio: c } = s, d = t[i.from]; 7484 let f = n(s, d), m = d; 7485 if (i.to - i.from < 2) { 7486 const p = r / 2; 7487 l.beginPath(); 7488 const v = { _t: d._t - p, ut: d.ut }, b = { _t: d._t + p, ut: d.ut }; 7489 l.moveTo(v._t * h, v.ut * c), l.lineTo(b._t * h, b.ut * c), a(s, f, v, b); 7490 } else { 7491 const p = o > 0; 7492 let v = 0; 7493 const b = (x, S) => { 7494 if (a(s, f, m, S), l.beginPath(), f = x, m = S, p) { 7495 const w = v % o; 7496 l.lineDashOffset = w, v = w; 7497 } 7498 }; 7499 let y = m; 7500 l.beginPath(), l.moveTo(d._t * h, d.ut * c); 7501 for (let x = i.from + 1; x < i.to; ++x) { 7502 y = t[x]; 7503 const S = y._t * h, w = y.ut * c, _ = n(s, y); 7504 switch (e) { 7505 case 0: 7506 if (l.lineTo(S, w), p) { 7507 const D = t[x - 1], z = D._t * h, P = D.ut * c; 7508 v += Me(z, P, S, w); 7509 } 7510 break; 7511 case 1: { 7512 const D = t[x - 1], z = D.ut * c; 7513 l.lineTo(S, z), p && (v += Math.abs(y._t - D._t) * h), _ !== f && (b(_, y), l.lineTo(S, z)), l.lineTo(S, w), p && (v += Math.abs(y.ut - D.ut) * c); 7514 break; 7515 } 7516 case 2: { 7517 const [D, z] = Ls(t, x - 1, x), P = D._t * h, E = D.ut * c, H
7517= z._t * h, J = z.ut * c; 7518 if (l.bezierCurveTo(P, E, H, J, S, w), p) { 7519 const j = t[x - 1], Q = j._t * h, N = j.ut * c, W = Me(Q, N, S, w), at = Me(Q, N, P, E) + Me(P, E, H, J) + Me(H, J, S, w); 7520 v += (W + at) / 2; 7521 } 7522 break; 7523 } 7524 } 7525 e !== 1 && _ !== f && (b(_, y), l.moveTo(S, w)); 7526 } 7527 (m !== y || m === y && e === 1) && a(s, f, m, y), p && (l.lineDashOffset = 0); 7528 } 7529 } 7530 var ln = 6; 7531 function ts(s, t) { 7532 return { _t: s._t - t._t, ut: s.ut - t.ut }; 7533 } 7534 function hn(s, t) { 7535 return { _t: s._t / t, ut: s.ut / t }; 7536 } 7537 function Ls(s, t, e) { 7538 const i = Math.max(0, t - 1), r = Math.min(s.length - 1, e + 1); 7539 var n, a; 7540 return [(n = s[t], a = hn(ts(s[e], s[i]), ln), { _t: n._t + a._t, ut: n.ut + a.ut }), ts(s[e], hn(ts(s[r], s[t]), ln))]; 7541 } 7542 function rh(s, t) { 7543 const e = s.context; 7544 e.strokeStyle = t, e.stroke(); 7545 } 7546 var nh = class extends ne { 7547 constructor() { 7548 super(...arguments), this.rt = null; 7549 } 7550 ht(t) { 7551 this.rt = t; 7552 } 7553 et(t) { 7554 if (this.rt === null) 7555 return; 7556 const { ot: e, lt: i, wb: r, Mb: n, ct: a, Zt: o, gb: l } = this.rt; 7557 if (i === null) 7558 return; 7559 const h = t.context; 7560 h.lineCap = "butt", h.lineWidth = a * t.verticalPixelRatio; 7561 const c = Ut(h, o); 7562 h.lineJoin = "round"; 7563 const d = this.bb.bind(this), f = (function(m) { 7564 return m.reduce((p, v) => p + v, 0); 7565 })(c); 7566 n !== void 0 && Jn(t, e, n, i, r, d, rh, f), l && (function(m, p, v, b, y) { 7567 if (b.to - b.from <= 0) 7568 return; 7569 const { horizontalPixelRatio: x, verticalPixelRatio: S, context: w } = m; 7570 let _ = null; 7571 const D = Math.max(1, Math.floor(x)) % 2 / 2, z = v * S + D; 7572 for (let P = b.to - 1; P >= b.from; --P) { 7573 const E = p[P]; 7574 if (E) { 7575 const H = y(m, E); 7576 H !== _ && (_ !== null && w.fill(), w.beginPath(), w.fillStyle = H, _ = H); 7577 const J = Math.round(E._t * x) + D, j = E.ut * S; 7578 w.moveTo(J, j), w.arc(J, j, z, 0, 2 * Math.PI); 7579 } 7580 } 7581 w.fill(); 7582 })(t, e, l, i, d); 7583 } 7584 }; 7585 var ta = class extends nh { 7586 bb(t, e) { 7587 return e.vt; 7588 } 7589 }; 7590 function cn(s, t, e, i, r) { 7591 const n = 1 - r; 7592 return n * n * n * s + 3 * n * n * r * t + 3 * n * r * r * e + r * r * r * i; 7593 } 7594 function ah(s, t, e, i, r) { 7595 if (e === 2) { 7596 const [n, a] = Ls(i, r - 1, r); 7597 return [Math.min(s._t, t._t, n._t, a._t), Math.max(s._t, t._t, n._t, a._t)]; 7598 } 7599 return [Math.min(s._t, t._t), Math.max(s._t, t._t)]; 7600 } 7601 function oh(s, t, e, i, r, n, a, o) { 7602 switch (r) { 7603 case 1: { 7604 const l = ze(s, t, e._t, e.ut, i._t, e.ut), h = ze(s, t, i._t, e.ut, i._t, i.ut), c = Math.min(l, h); 7605 return c <= o ? c : null; 7606 } 7607 case 2: { 7608 const [l, h] = Ls(n, a - 1, a), c = (function(d, f, m) { 7609 let p = Number.POSITIVE_INFINITY, v = m[0]; 7610 for (let b = 1; b <= 12; b++) { 7611 const y = b / 12, x = { _t: cn(m[0]._t, m[1]._t, m[2]._t, m[3]._t, y), ut: cn(m[0].ut, m[1].ut, m[2].ut, m[3].ut, y) }; 7612 p = Math.min(p, ze(d, f, v._t, v.ut, x._t, x.ut)), v = x; 7613 } 7614 return p; 7615 })(s, t, [e, l, h, i]); 7616 return c <= o ? c : null; 7617 } 7618 default: { 7619 const l = ze(s, t, e._t, e.ut, i._t, i.ut); 7620 return l <= o ? l : null; 7621 } 7622 } 7623 } 7624 var lh = class extends Zn { 7625 constructor(t, e) { 7626 super(t, e, true); 7627 } 7628 Vg(t, e, i) { 7629 e.Tc(this.bg, ls(this.Sg)), t.Zo(this.bg, i, ls(this.Sg)); 7630 } 7631 Sb(t, e) { 7632 return { wt: t, Mt: e, _t: NaN, ut: NaN }; 7633 } 7634 Dg() { 7635 const t = this.ae.Sa(); 7636 this.bg = this.ae.Ha().Bh().map((e) => { 7637 var r; 7638 let i; 7639 if (((r = e.Zr) != null ? r : 1) > 1) { 7640 const n = e.Wt[1], a = e.Wt[2], o = e.Wt[3]; 7641 i = Math.abs(n - o) > Math.abs(a - o) ? n : a; 7642 } else 7643 i = e.Wt[3]; 7644 return this.xb(e.$n, i, t); 7645 }); 7646 } 7647 }; 7648 var ea = class extends lh { 7649 Pg(t, e) { 7650 const i = this.ae.N(); 7651 return (function(r, n, a, o, l, h, c, d = 0, f = 0) { 7652 if (n === null || n.from >= n.to || r.length === 0) 7653 return null; 7654 const m = Math.max(h / 2, c != null ? c : 0) + f; 7655 let p = Number.POSITIVE_INFINITY; 7656 if (c !== void 0) { 7657 const w = c + f, _ = gs(r, a - w, n.from, n.to), D = vs(r, a + w, _, n.to); 7658 for (let z = _; z < D; z++) { 7659 const P = r[z]; 7660 if (!sn(a, P._t, P._t, c + f)) 7661 continue; 7662 const E = Math.hypot(a - P._t, o - P.ut); 7663 E <= c + f && (p = Math.min(p, E)); 7664 } 7665 } 7666 if (n.to - n.from < 2) { 7667 const w = r[n.from], _ = Math.max(d / 2, m), D = ze(a, o, w._t - _, w.ut, w._t + _, w.ut); 7668 return D <= m && (p = Math.min(p, D)), Number.isFinite(p) ? hi(p, 2, "series-point") : null; 7669 } 7670 let v = Number.POSITIVE_INFINITY; 7671 const b = gs(r, a - m, n.from, n.to), y = vs(r, a + m, b, n.to), x = Math.max(n.from + 1, b), S = Math.min(n.to, y + 1); 7672 for (let w = x; w < S; w++) { 7673 const _ = r[w - 1], D = r[w], [z, P] = ah(_, D, l, r, w); 7674 if (!sn(a, z, P, m)) 7675 continue; 7676 const E = oh(a, o, _, D, l, r, w, m); 7677 E !== null && (v = Math.min(v, E)); 7678 } 7679 return Number.isFinite(p) ? hi(p, 2, "series-point") : Number.isFinite(v) ? hi(v, 1, "series-line") : null; 7680 })(this.bg, this.Sg, t, e, i.lineType, i.lineVisible ? i.lineWidth : 1, i.pointMarkersVisible ? i.pointMarkersRadius || i.lineWidth / 2 + 2 : void 0, this.le.Et().fl(), i.hitTestTolerance); 7681 } 7682 }; 7683 var hh = class extends ea { 7684 constructor() { 7685 super(...arguments), this.kg = new ta(); 7686 } 7687 xb(t, e, i) { 7688 return M(M({}, this.Sb(t, e)), i.Sh(t)); 7689 } 7690 Bg() { 7691 const t = this.ae.N(), e = { ot: this.bg, Zt: t.lineStyle, Mb: t.lineVisible ? t.lineType : void 0, ct: t.lineWidth, gb: t.pointMarkersVisible ? t.pointMarkersRadius || t.lineWidth / 2 + 2 : void 0, lt: this.Sg, wb: this.le.Et().fl() }; 7692 this.kg.ht(e); 7693 } 7694 }; 7695 var dn = { type: "Line", isBuiltIn: true, defaultOptions: { color: "#2196f3", lineStyle: 0, lineWidth: 3, lineType: 0, lineVisible: true, crosshairMarkerVisible: true, crosshairMarkerRadius: 4, crosshairMarkerBorderColor: "", crosshairMarkerBorderWidth: 2, crosshairMarkerBackgroun
7695dColor: "", lastPriceAnimation: 0, pointMarkersVisible: false }, ob: (s, t) => new hh(s, t) }; 7696 function ch(s, t, e, i, r) { 7697 const { context: n, horizontalPixelRatio: a, verticalPixelRatio: o } = t; 7698 n.lineTo(r._t * a, s * o), n.lineTo(i._t * a, s * o), n.closePath(), n.fillStyle = e, n.fill(); 7699 } 7700 var dh = class extends ne { 7701 constructor() { 7702 super(...arguments), this.rt = null; 7703 } 7704 ht(t) { 7705 this.rt = t; 7706 } 7707 et(t) { 7708 var c; 7709 if (this.rt === null) 7710 return; 7711 const { ot: e, lt: i, wb: r, ct: n, Zt: a, Mb: o } = this.rt, l = (c = this.rt.Db) != null ? c : this.rt.Ib ? 0 : t.mediaSize.height; 7712 if (i === null) 7713 return; 7714 const h = t.context; 7715 h.lineCap = "butt", h.lineJoin = "round", h.lineWidth = n, Ut(h, a), h.lineWidth = 1, Jn(t, e, o, i, r, this.Vb.bind(this), ch.bind(null, l)); 7716 } 7717 }; 7718 var uh = class { 7719 Bb(t, e) { 7720 const i = this.Eb, { Ab: r, Lb: n, zb: a, Ob: o, Db: l, Nb: h, Fb: c } = e; 7721 if (this.Wb === void 0 || i === void 0 || i.Ab !== r || i.Lb !== n || i.zb !== a || i.Ob !== o || i.Db !== l || i.Nb !== h || i.Fb !== c) { 7722 const { verticalPixelRatio: d } = t, f = l || h > 0 ? d : 1, m = h * f, p = c === t.bitmapSize.height ? c : c * f, v = (l != null ? l : 0) * f, b = t.context.createLinearGradient(0, m, 0, p); 7723 if (b.addColorStop(0, r), l != null) { 7724 const y = fe((v - m) / (p - m), 0, 1); 7725 b.addColorStop(y, n), b.addColorStop(y, a); 7726 } 7727 b.addColorStop(1, o), this.Wb = b, this.Eb = e; 7728 } 7729 return this.Wb; 7730 } 7731 }; 7732 var fh = class extends dh { 7733 constructor() { 7734 super(...arguments), this.Hb = new uh(); 7735 } 7736 Vb(t, e) { 7737 var i, r; 7738 return this.Hb.Bb(t, { Ab: e.ah, Lb: "", zb: "", Ob: e.oh, Nb: (r = (i = this.rt) == null ? void 0 : i.Nb) != null ? r : 0, Fb: t.bitmapSize.height }); 7739 } 7740 }; 7741 var mh = class extends ea { 7742 constructor(t, e) { 7743 super(t, e), this.kg = new Tn(), this.qb = new fh(), this.Yb = new ta(), this.kg.nt([this.qb, this.Yb]); 7744 } 7745 xb(t, e, i) { 7746 return M(M({}, this.Sb(t, e)), i.Sh(t)); 7747 } 7748 Bg() { 7749 const t = this.ae.N(); 7750 if (this.Sg === null || this.bg.length === 0) 7751 return; 7752 let e; 7753 if (t.relativeGradient) { 7754 e = this.bg[this.Sg.from].ut; 7755 for (let i = this.Sg.from; i < this.Sg.to; i++) { 7756 const r = this.bg[i]; 7757 r.ut < e && (e = r.ut); 7758 } 7759 } 7760 this.qb.ht({ Mb: t.lineType, ot: this.bg, Zt: t.lineStyle, ct: t.lineWidth, Db: null, Nb: e, Ib: t.invertFilledArea, lt: this.Sg, wb: this.le.Et().fl() }), this.Yb.ht({ Mb: t.lineVisible ? t.lineType : void 0, ot: this.bg, Zt: t.lineStyle, ct: t.lineWidth, lt: this.Sg, wb: this.le.Et().fl(), gb: t.pointMarkersVisible ? t.pointMarkersRadius || t.lineWidth / 2 + 2 : void 0 }); 7761 } 7762 }; 7763 var ph = { type: "Area", isBuiltIn: true, defaultOptions: { topColor: "rgba( 46, 220, 135, 0.4)", bottomColor: "rgba( 40, 221, 100, 0)", invertFilledArea: false, relativeGradient: false, lineColor: "#33D778", lineStyle: 0, lineWidth: 3, lineType: 0, lineVisible: true, crosshairMarkerVisible: true, crosshairMarkerRadius: 4, crosshairMarkerBorderColor: "", crosshairMarkerBorderWidth: 2, crosshairMarkerBackgroundColor: "", lastPriceAnimation: 0, pointMarkersVisible: false }, ob: (s, t) => new mh(s, t) }; 7764 G(M({}, Fn), { color: "#2196f3" }); 7765 var gh = { ATTRIBUTE: 1, CHILD: 2, PROPERTY: 3, BOOLEAN_ATTRIBUTE: 4, EVENT: 5, ELEMENT: 6 }; 7766 var vh = (s) => (...t) => ({ _$litDirective$: s, values: t }); 7767 var bh = class { 7768 constructor(t) { 7769 } 7770 get _$AU() { 7771 return this._$AM._$AU; 7772 } 7773 _$AT(t, e, i) { 7774 this._$Ct = t, this._$AM = e, this._$Ci = i; 7775 } 7776 _$AS(t, e) { 7777 return this.update(t, e); 7778 } 7779 update(t, e) { 7780 return this.render(...e); 7781 } 7782 }; 7783 var bs = class extends bh { 7784 constructor(t) { 7785 if (super(t), this.et = I, t.type !== gh.CHILD) 7786 throw Error(this.constructor.directiveName + "() can only be used in child bindings"); 7787 } 7788 render(t) { 7789 if (t === I || t == null) 7790 return this.ft = void 0, this.et = t; 7791 if (t === te) 7792 return t; 7793 if (typeof t != "string") 7794 throw Error(this.constructor.directiveName + "() called with a non-string value"); 7795 if (t === this.et) 7796 return this.ft; 7797 this.et = t; 7798 const e = [t]; 7799 return e.raw = e, this.ft = { _$litType$: this.constructor.resultType, strings: e, values: [] }; 7800 } 7801 }; 7802 bs.directiveName = "unsafeHTML", bs.resultType = 1; 7803 var ia = vh(bs); 7804 var Ns = K` 7805 :host { 7806 display: block; 7807 font-family: var(--stock-font-family, Arial, sans-serif); 7808 padding: var(--stock-padding, 24px); 7809 border-radius: var(--stock-border-radius, 16px);
7810 box-shadow: var(--stock-box-shadow, 0 10px 25px rgba(0, 0, 0, 0.08)); 7811 max-width: var(--stock-max-width, 100%); 7812 margin: 0 auto; 7813 transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); 7814 background-color: var(--stock-background-color, #ffffff); 7815 color: var(--stock-text-color, #2c3e50); 7816 border: 1px solid var(--stock-border-color, rgba(230, 230, 230, 0.8)); 7817 overflow: hidden; 7818 } 7819 7820 7821 7822 /* TÃtulos y encabezados */ 7823 h2, .section-title { 7824 font-size: var(--stock-title-font-size, 1.5rem); 7825 font-weight: var(--stock-title-weight, 700); 7826 margin-top: 0; 7827 margin-bottom: 1rem; 7828 color: var(--stock-title-color, #1e293b); 7829 } 7830 7831 .section-title { 7832 font-size: var(--stock-section-title-font-size, 1.1rem); 7833 padding-bottom: 0.5rem; 7834 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 7835 } 7836 7837 /* Estados de carga y error */ 7838 .loading { 7839 display: flex; 7840 align-items: center; 7841 justify-content: center; 7842 padding: 30px; 7843 font-size: var(--stock-text-size, 15px); 7844 color: var(--stock-muted-color, #64748b); 7845 font-weight: 500; 7846 position: relative; 7847 text-align: center; 7848 visibility: hidden; 7849 opacity: 0; 7850 animation: showLoading 0.2s ease-in 0.15s forwards; 7851 } 7852 7853 .loading::before { 7854 content: ''; 7855 display: block; 7856 width: 24px; 7857 height: 24px; 7858 margin-right: 12px; 7859 border: 3px solid var(--stock-accent-color, #3b82f6); 7860 border-radius: 50%; 7861 border-top-color: transparent; 7862 animation: spinner 0.8s linear infinite; 7863 } 7864 7865 @keyframes showLoading { 7866 to { visibility: visible; opacity: 1; } 7867 } 7868 7869 @keyframes spinner { 7870 to { transform: rotate(360deg); } 7871 } 7872 7873 @media (prefers-reduced-motion: reduce) { 7874 .loading { 7875 visibility: visible; 7876 opacity: 1; 7877 animation: none; 7878 } 7879 7880 .loading::before { 7881 animation: none; 7882 border-top-color: var(--stock-accent-color, #3b82f6); 7883 opacity: 0.4; 7884 } 7885 } 7886 7887 .error { 7888 color: var(--stock-error-color, #ef4444); 7889 padding: 16px; 7890 border: 1px solid var(--stock-error-border-color, rgba(239, 68, 68, 0.2)); 7891 border-radius: 12px; 7892 font-size: var(--stock-small-text-size, 14px); 7893 font-weight: 500; 7894 background-color: var(--stock-error-background, rgba(239, 68, 68, 0.05)); 7895 text-align: center; 7896 margin: 12px 0; 7897 display: flex; 7898 align-items: center; 7899 justify-content: center; 7900 } 7901 7902 .error::before { 7903 content: 'â ï¸'; 7904 margin-right: 8px; 7905 font-size: 18px; 7906 } 7907 7908 /* Contenedores de información */ 7909 .info-container { 7910 display: grid; 7911 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); 7912 gap: 20px; 7913 } 7914 7915 .info-header { 7916 grid-column: 1 / -1; 7917 display: flex; 7918 align-items: center; 7919 margin-bottom: 20px; 7920 padding-bottom: 16px; 7921 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 7922 } 7923 7924 /* Imágenes de acciones */ 7925 .stock-image { 7926 width: 64px; 7927 height: 64px; 7928 object-fit: contain; 7929 border-radius: 12px; 7930 background-color: var(--stock-image-bg, #f8fafc); 7931 padding: 8px; 7932 margin-right: 20px; 7933 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); 7934 transition: transform 0.3s ease; 7935 } 7936 7937 /* TÃtulos de acciones */ 7938 .stock-name { 7939 margin: 0; 7940 font-size: var(--stock-title-size, 22px); 7941 font-weight: var(--stock-title-weight, 700); 7942 color: var(--stock-title-color, #1e293b); 7943 letter-spacing: -0.01em; 7944 } 7945 7946 .stock-symbol { 7947 color: var(--stock-muted-color, #64748b); 7948 margin: 6px 0 0; 7949 font-size: var(--stock-small-text-size, 15px); 7950 font-weight: 500; 7951 padding: 4px 10px; 7952 background-color: var(--stock-symbol-bg, rgba(226, 232, 240, 0.5)); 7953 border-radius: 6px; 7954 display: inline-block; 7955 } 7956 7957 /* Elementos detallados */ 7958 .detail-item, .ratio-item { 7959 padding: 18px; 7960 background-color: var(--stock-detail-background, #f8fafc); 7961 border-radius: 12px; 7962 transition: all 0.3s ease; 7963 border: 1px solid var(--stock-detail-border, rgba(226, 232, 240, 0.6)); 7964 } 7965 7966 .detail-label, .ratio-label { 7967 font-weight: var(--stock-label-weight, 600); 7968 color: var(--stock-label-color, #475569); 7969 margin-bottom: 10px; 7970 font-size: var(--stock-label-size, 14px); 7971 display: flex; 7972 align-items: center; 7973 text-transform: uppercase; 7974 letter-spacing: 0.5px; 7975 } 7976 7977 .detail-value, .ratio-value { 7978 font-size: var(--stock-value-size, 16px); 7979 line-height: 1.6; 7980 color: var(--stock-value-color, #334155);
7981 font-weight: var(--stock-value-weight, 600); 7982 } 7983 7984 /* Estilos especÃficos de ratios */ 7985 .ratios-grid { 7986 display: grid; 7987 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 7988 gap: 0.75rem; 7989 } 7990 7991 .ratio-item { 7992 display: flex; 7993 justify-content: space-between; 7994 align-items: center; 7995 padding: 0.5rem; 7996 } 7997 7998 /* Colores de valores */ 7999 .negative { 8000 color: var(--stock-negative-color, #d32f2f); 8001 } 8002 8003 .positive { 8004 color: var(--stock-positive-color, #388e3c); 8005 } 8006 8007 .high-debt, .warning { 8008 color: var(--stock-warning-color, #f57c00); 8009 } 8010 8011 /* Enlaces */ 8012 .website-link { 8013 color: var(--stock-link-color, #0d6efd); 8014 text-decoration: none; 8015 } 8016 8017 .website-link:hover { 8018 text-decoration: underline; 8019 } 8020 8021 /* Elemento horizontal con scroll */ 8022 .horizontal-scroll-element { 8023 width: 100%; 8024 display: block; 8025 position: relative; 8026 box-sizing: border-box; 8027 } 8028 8029 .horizontal-scroll-element.initiated { 8030 width: calc(100% + var(--stock-padding, 16px) * 2); 8031 margin-left: calc(-1 * var(--stock-padding, 16px)); 8032 margin-right: calc(-1 * var(--stock-padding, 16px)); 8033 overflow: hidden; 8034 } 8035 8036 .horizontal-scroll-element.initiated::before, 8037 .horizontal-scroll-element.initiated::after { 8038 content: ''; 8039 position: absolute; 8040 top: 0; 8041 bottom: 0; 8042 width: var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)); 8043 pointer-events: none; 8044 z-index: 1; 8045 } 8046 8047 .horizontal-scroll-element.initiated::before { 8048 left: 0; 8049 background: linear-gradient(to right, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); 8050 opacity: 0; 8051 transition: opacity 0.2s ease; 8052 } 8053 8054 .horizontal-scroll-element.initiated.scrolled-left::before { 8055 opacity: 1; 8056 } 8057 8058 .horizontal-scroll-element.initiated::after { 8059 right: 0; 8060 background: linear-gradient(to left, 8061 rgba(255, 255, 255, 1) 0px, 8062 rgba(255, 255, 255, 0.9) 10px, 8063 rgba(255, 255, 255, 0) 100% 8064 ); 8065 width: calc(var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)) * 1.6); 8066 opacity: 1; 8067 transition: opacity 0.2s ease; 8068 } 8069 8070 /* Hide right fade when scrolled to the end */ 8071 .horizontal-scroll-element.initiated.scrolled-right::after { 8072 opacity: 0; 8073 } 8074 8075 .horizontal-scroll-element-inner { 8076 display: flex; 8077 flex-direction: row; 8078 align-items: center; 8079 gap: 8px; 8080 width: 100%; 8081 overflow-x: auto; 8082 -webkit-overflow-scrolling: touch; 8083 scrollbar-width: none; 8084 padding-bottom: 5px; 8085 scroll-behavior: smooth; 8086 box-sizing: border-box; 8087 } 8088 8089 .horizontal-scroll-element-inner::-webkit-scrollbar {
8090 display: none; 8091 } 8092 8093 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner { 8094 padding-left: var(--stock-padding, 16px); 8095 padding-right: var(--stock-padding, 16px); 8096 cursor: grab; 8097 user-select: none; 8098 } 8099 8100 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner:active { 8101 cursor: grabbing; 8102 } 8103 8104 /* 8105 * Fallback SSR: cuando \`renderNoData()\`/\`renderError()\` proyectan el outerHTML 8106 * de \`.rnk-SeoStaticData\` dentro del shadow via \`unsafeHTML\` (TDT-RNK-2015), 8107 * el CSS de Rankia que normalmente estiliza esa clase queda fuera del shadow. 8108 * Estos estilos minimos garantizan una rejilla legible (dl/dt/dd) aunque el 8109 * bundle externo no aplique aqui. 8110 */ 8111 .ssr-fallback { 8112 display: block; 8113 } 8114 8115 .ssr-fallback dl { 8116 display: grid; 8117 grid-template-columns: max-content 1fr; 8118 gap: 0.25rem 0.75rem; 8119 margin: 0; 8120 } 8121 8122 .ssr-fallback dt { 8123 font-weight: 600; 8124 } 8125 8126 .ssr-fallback dd { 8127 margin: 0; 8128 } 8129 8130 /* Responsive */ 8131 @media (max-width: 600px) { 8132 :host { 8133 padding: 16px; 8134 } 8135 8136 .info-header { 8137 flex-direction: column; 8138 align-items: center; 8139 text-align: center; 8140 } 8141 8142 .stock-image { 8143 margin: 0 auto 12px; 8144 } 8145 8146 .ratios-grid { 8147 grid-template-columns: 1fr; 8148 } 8149 } 8150`; 8151 var F = class { 8152 /** 8153 * Formats a number for display with support for large numbers (T/B/M/K) 8154 * @param value Number to format 8155 * @param locale Locale for number formatting (e.g., 'en-US', 'es-ES') 8156 * @param options Optional configuration 8157 * @param options.showDashForZero If true, returns '-' for zero values (default: false) 8158 * @returns Formatted string 8159 */ 8160 static formatNumber(t, e, i) { 8161 const r = e || void 0; 8162 if (t == null || isNaN(t)) 8163 return "N/A"; 8164 if (i != null && i.showDashForZero && t === 0) 8165 return "-"; 8166 const n = Math.abs(t); 8167 if (n >= 1e12) { 8168 const a = t / 1e12; 8169 return `${new Intl.NumberFormat(r, { 8170 minimumFractionDigits: 0, 8171 maximumFractionDigits: 2 8172 }).format(a)}${u("T", { desc: "Abbreviation for trillions" })}`; 8173 } 8174 if (n >= 1e9) { 8175 const a = t / 1e9; 8176 return `${new Intl.NumberFormat(r, { 8177 minimumFractionDigits: 0, 8178 maximumFractionDigits: 2 8179 }).format(a)}${u("B", { desc: "Abbreviation for billions" })}`; 8180 } 8181 if (n >= 1e6) { 8182 const a = t / 1e6; 8183 return `${new Intl.NumberFormat(r, { 8184 minimumFractionDigits: 0, 8185 maximumFractionDigits: 2 8186 }).format(a)}${u("M", { desc: "Abbreviation for millions" })}`; 8187 } 8188 if (n >= 1e3) { 8189 const a = t / 1e3; 8190 return `${new Intl.NumberFormat(r, { 8191 minimumFractionDigits: 0, 8192 maximumFractionDigits: 2 8193 }).format(a)}${u("K", { desc: "Abbreviation for thousands" })}`; 8194 } 8195 return new Intl.NumberFormat(r).format(t); 8196 } 8197 /** 8198 * Formats a date based on interval and locale 8199 * @param date Date to format 8200 * @param interval Time interval 8201 * @param locale Locale setting 8202 * @returns Formatted date string 8203 */ 8204 static formatDate(t, e, i) { 8205 const r = i || void 0; 8206 return e === "1month" ? t.toLocaleDateString(r, { month: "short", year: "numeric" }) : e === "1week" ? t.toLocaleDateString(r, { day: "2-digit", month: "short" }) : ["1min", "5min", "15min", "1hour"].includes(e) ? t.toLocaleTimeString(r, { 8207 hour: "2-digit", 8208 minute: "2-digit", 8209 hour12: false 8210 }) : e === "30min" || e === "4hour" ? t.toLocaleDateString(r, { day: "2-digit", month: "short" }) : t.toLocaleDateString(r, { day: "2-digit", month: "short" }); 8211 } 8212 /** 8213 * Formats a date for tooltips 8214 * @param date Date to format 8215 * @param interval Time interval 8216 * @param locale Locale setting 8217 * @returns Formatted date string 8218 */ 8219 static formatTooltipDate(t, e, i) { 8220 const r = i || void 0; 8221 return e === "1month" ? t.toLocaleDateString(r, { month: "short", year: "numeric" }) : ["1min", "5min", "15min", "30min", "1hour", "4hour"].includes(e) ? `${t.toLocaleDateString(r)} ${t.toLocaleTimeString(r, { hour: "2-digit", minute: "2-digit" })}` : t.toLocaleDateString(r); 8222 } 8223 /** 8224 * Formats a decimal number with locale-aware formatting 8225 * @param value Number to format 8226 * @param locale Locale for number formatting (default: 'en-US') 8227 * @param decimals Number of decimal places (default: 2) 8228 * @returns Formatted string or '-' for null/undefined 8229 */ 8230 static formatDecimal(t, e = "en-US", i = 2) { 8231 const r = e || "en-US"; 8232 return t == null ? "-" : new Intl.NumberFormat(r, {
8233 minimumFractionDigits: i, 8234 maximumFractionDigits: i 8235 }).format(t); 8236 } 8237 /** 8238 * Formats a value as percentage (value in decimal form: 0.05 = 5%) 8239 * @param value Number to format (as decimal, e.g., 0.05 for 5%) 8240 * @param locale Locale for number formatting (default: 'en-US') 8241 * @returns Formatted percentage string or '-' for null/undefined 8242 */ 8243 static formatPercentage(t, e = "en-US") { 8244 const i = e || "en-US"; 8245 return t == null ? "-" : new Intl.NumberFormat(i, { 8246 style: "percent", 8247 minimumFractionDigits: 2, 8248 maximumFractionDigits: 2 8249 }).format(t); 8250 } 8251 /** 8252 * Formats a value as currency with symbol 8253 * @param value Number to format 8254 * @param locale Locale for number formatting (default: 'en-US') 8255 * @param currency Currency code (default: 'EUR') 8256 * @param decimals Number of decimal places (default: 2) 8257 * @returns Formatted currency string or '-' for null/undefined 8258 */ 8259 static formatCurrency(t, e = "en-US", i = "EUR", r = 2) { 8260 const n = e || "en-US"; 8261 return t == null ? "-" : new Intl.NumberFormat(n, { 8262 style: "currency", 8263 currency: i, 8264 minimumFractionDigits: r, 8265 maximumFractionDigits: r 8266 }).format(t); 8267 } 8268 /** 8269 * Formats a percentage change with sign display (e.g., +5.00% or -3.50%) 8270 * @param value Number to format (as decimal, e.g., 0.05 for +5%) 8271 * @param locale Locale for number formatting (default: 'en-US') 8272 * @returns Formatted percentage string with sign or '-' for null/undefined 8273 */ 8274 static formatPercentageChange(t, e = "en-US") { 8275 const i = e || "en-US"; 8276 return t == null ? "-" : new Intl.NumberFormat(i, { 8277 style: "percent", 8278 minimumFractionDigits: 2, 8279 maximumFractionDigits: 2, 8280 signDisplay: "exceptZero" 8281 }).format(t); 8282 } 8283 /** 8284 * Gets the currency symbol from currency code 8285 * @param currencyCode Currency code (e.g., 'USD', 'EUR', 'GBP') 8286 * @param locale Locale for formatting (default: 'en-US') 8287 * @returns Currency symbol (e.g., '$', 'â¬', '£') 8288 */ 8289 static getCurrencySymbol(t, e = "en-US") { 8290 const i = e || "en-US"; 8291 try { 8292 const a = new Intl.NumberFormat(i, { 8293 style: "currency", 8294 currency: t, 8295 minimumFractionDigits: 0, 8296 maximumFractionDigits: 0 8297 }).formatToParts(0).find((o) => o.type === "currency"); 8298 return a ? a.value : t; 8299 } catch (r) { 8300 return t; 8301 } 8302 } 8303 }; 8304 var ye = "data-rnk-seo-static-hidden"; 8305 var Ne = "data-rnk-seo-static-display"; 8306 var Bs = "data-rnk-rendered"; 8307 var Be = "data-rnk-ssr-projection"; 8308 function yh(s) { 8309 s.setAttribute(Bs, ""); 8310 } 8311 function sa(s) { 8312 s.removeAttribute(Bs); 8313 } 8314 function ys(s) { 8315 s.querySelectorAll(`.rnk-SeoStaticData:not([${Be}])`).forEach((t) => { 8316 t instanceof HTMLElement && (t.hasAttribute(ye) || (t.setAttribute(Ne, t.style.getPropertyValue("display")), t.setAttribute(ye, "")), t.style.setProperty("display", "none", "important")); 8317 }); 8318 } 8319 function wh(s) { 8320 if (s.hasAttribute(Bs)) { 8321 sa(s); 8322 for (const t of Array.from(s.childNodes)) 8323 t.nodeType === Node.ELEMENT_NODE && xh(t) || s.removeChild(t); 8324 } 8325 } 8326 function xh(s) { 8327 var t, e; 8328 return (t = s.classList) != null && t.contains("rnk-SeoStaticData") && !s.hasAttribute(Be) ? true : ((e = s.querySelector) == null ? void 0 : e.call(s, `.rnk-SeoStaticData:not([${Be}])`)) != null; 8329 } 8330 var un = [ 8331 "aria-labelledby", 8332 "aria-describedby", 8333 "aria-controls", 8334 "aria-owns", 8335 "aria-flowto", 8336 "aria-activedescendant" 8337 ]; 8338 function kh(s, { activeKey: t, initialKey: e, idPrefix: i }) { 8339 var d, f, m; 8340 if (!t || e && t && t !== e) 8341 return null; 8342 const r = s.querySelector(".rnk-SeoStaticData"); 8343 if (!r) 8344 return null; 8345 const n = r.cloneNode(true); 8346 if (n.setAttribute(Be, ""), n.hasAttribute(ye)) { 8347 n.removeAttribute(ye); 8348 const p = n, v = p.getAttribute(Ne);
8349 p.removeAttribute(Ne), v && v !== "none" ? p.style.setProperty("display", v) : (d = p.style) == null || d.removeProperty("display"), p.getAttribute("style") === "" && p.removeAttribute("style"); 8350 } 8351 n.querySelectorAll("script, style, template").forEach((p) => p.remove()); 8352 const a = /* @__PURE__ */ new Map(); 8353 if (n.hasAttribute("id")) { 8354 const p = n.getAttribute("id"), v = i + p; 8355 a.set(p, v), n.setAttribute("id", v); 8356 } 8357 n.querySelectorAll("[id]").forEach((p) => { 8358 const v = p.getAttribute("id"), b = i + v; 8359 a.set(v, b), p.setAttribute("id", b); 8360 }); 8361 for (const p of un) 8362 if (n.hasAttribute(p)) { 8363 const b = n.getAttribute(p).split(/\s+/).map((y) => { 8364 var x; 8365 return (x = a.get(y)) != null ? x : y; 8366 }).join(" "); 8367 n.setAttribute(p, b); 8368 } 8369 const o = (p) => { 8370 n.querySelectorAll(`[${p}]`).forEach((v) => { 8371 const y = v.getAttribute(p).split(/\s+/).map((x) => { 8372 var S; 8373 return (S = a.get(x)) != null ? S : x; 8374 }).join(" "); 8375 v.setAttribute(p, y); 8376 }); 8377 }; 8378 un.forEach(o), n.querySelectorAll("label[for]").forEach((p) => { 8379 var b; 8380 const v = p.getAttribute("for"); 8381 p.setAttribute("for", (b = a.get(v)) != null ? b : v); 8382 }), n.querySelectorAll("[list]").forEach((p) => { 8383 var b; 8384 const v = p.getAttribute("list"); 8385 p.setAttribute("list", (b = a.get(v)) != null ? b : v); 8386 }), n.querySelectorAll('a[href^="#"]').forEach((p) => { 8387 const b = p.getAttribute("href").slice(1); 8388 b && a.has(b) && p.setAttribute("href", "#" + a.get(b)); 8389 }), n.querySelectorAll('use[href^="#"]').forEach((p) => { 8390 const v = p.getAttribute("href").slice(1); 8391 v && a.has(v) && p.setAttribute("href", "#" + a.get(v)); 8392 }), n.querySelectorAll('use[xlink\\:href^="#"]').forEach((p) => { 8393 const v = p.getAttribute("xlink:href").slice(1); 8394 v && a.has(v) && p.setAttribute("xlink:href", "#" + a.get(v)); 8395 }); 8396 const l = (p) => { 8397 var y; 8398 const b = ((y = p.getAttribute("style")) != null ? y : "").toLowerCase(); 8399 (b.includes("expression(") || b.includes("javascript:") || b.includes("behavior:")) && p.removeAttribute("style"); 8400 }; 8401 n.hasAttribute("style") && l(n), n.querySelectorAll("[style]").forEach(l), n.querySelectorAll("*").forEach((p) => { 8402 for (const v of Array.from(p.attributes)) { 8403 const b = v.name.toLowerCase(), y = v.value.trim().toLowerCase(); 8404 (b.startsWith("on") || y.startsWith("javascript:") || y.startsWith("vbscript:") || y.startsWith("data:text/html")) && p.removeAttribute(v.name); 8405 } 8406 }); 8407 const h = n.querySelector("*") !== null, c = ((m = (f = n.textContent) == null ? void 0 : f.trim().length) != null ? m : 0) > 0; 8408 return !h && !c ? null : n.outerHTML; 8409 } 8410 var Sh = Object.defineProperty; 8411 var Ch = Object.getOwnPropertyDescriptor; 8412 var je = (s, t, e, i) => { 8413 for (var r = i > 1 ? void 0 : i ? Ch(t, e) : t, n = s.length - 1, a; n >= 0; n--) 8414 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 8415 return i && r && Sh(t, e, r), r; 8416 }; 8417 var Os = class Yt { 8418 static get API_BASE_URL() { 8419 const t = globalThis.__STOCK_WC_API_BASE_URL; 8420 if (t === void 0) 8421 return this.DEFAULT_URL; 8422 if (typeof t != "string") 8423 return Yt.warnInvalid(`expected string, got ${typeof t}`), this.DEFAULT_URL; 8424 const e = t.trim(); 8425 if (!e.length) 8426 return Yt.warnInvalid("value is empty or whitespace-only"), this.DEFAULT_URL; 8427 const i = e.replace(/\/+$/, ""); 8428 return i.length ? i : (Yt.warnInvalid(`value collapses to empty after slash normalization (got ${JSON.stringify(t)})`), this.DEFAULT_URL); 8429 } 8430 static warnInvalid(t) { 8431 var i; 8432 if (Yt.warnedInvalid) 8433 return; 8434 Yt.warnedInvalid = true, typeof process != "undefined" && ((i = process.env) == null ? void 0 : i.NODE_ENV) === "production" || console.warn(`[stock-webcomponents] Ignored globalThis.__STOCK_WC_API_BASE_URL: ${t}. Falling back to ${Yt.DEFAULT_URL}.`); 8435 } 8436 }; 8437 Os.DEFAULT_URL = "https://api-myportfolio.rankia.com"; 8438 Os.warnedInvalid = false;
8439 var q = Os; 8440 var kt = class extends $t { 8441 constructor() { 8442 super(...arguments), this.locale = "", this.showHeader = true, this.loading = false, this.error = null, this.data = null; 8443 } 8444 /** 8445 * Se llama cuando el componente es añadido al DOM 8446 */ 8447 connectedCallback() { 8448 super.connectedCallback(), this.renderRoot === this && wh(this), this.shouldFetchData() && this.fetchData(); 8449 } 8450 /** 8451 * Se llama cuando el componente es retirado del DOM 8452 */ 8453 disconnectedCallback() { 8454 super.disconnectedCallback(), this.renderRoot === this && sa(this); 8455 } 8456 /** 8457 * Se llama cuando cambian las propiedades del componente 8458 * 8459 * MAINTENANCE: any light-DOM subclass that overrides `updated()` MUST call 8460 * `super.updated()`. Otherwise the `markLightDomRendered` stamp below never 8461 * runs, `clearStaleLightDomRender` loses the marker it gates on, and the Turbo 8462 * snapshot-restore duplication this path fixes silently returns. 8463 */ 8464 updated(t) { 8465 this.renderRoot === this && yh(this), this.hasKeyPropertyChanged(t) && this.shouldFetchData() && this.fetchData(), (t.has("locale") || t.has("showHeader")) && this.requestUpdate(); 8466 } 8467 /** 8468 * Formatea un valor decimal 8469 * Delegates to FormatUtils.formatDecimal for consistent formatting 8470 */ 8471 formatDecimal(t, e = 2) { 8472 return F.formatDecimal(t, this.locale || "en-US", e); 8473 } 8474 /** 8475 * Formatea un valor como porcentaje 8476 * Delegates to FormatUtils.formatPercentage for consistent formatting 8477 */ 8478 formatPercentage(t) { 8479 return F.formatPercentage(t, this.locale || "en-US"); 8480 } 8481 /** 8482 * Formatea un valor como moneda 8483 * Delegates to FormatUtils.formatCurrency for consistent formatting 8484 */ 8485 formatCurrency(t, e = 2, i = "EUR") { 8486 return F.formatCurrency(t, this.locale || "en-US", i, e); 8487 } 8488 /** 8489 * Formatea una fecha 8490 * Uses en-GB for English locales to get DD/MM/YYYY format (European style) 8491 * instead of MM/DD/YYYY (American style from en-US) 8492 */ 8493 formatDate(t) { 8494 if (!t) 8495 return "-"; 8496 try { 8497 const e = new Date(t); 8498 let i = this.locale || "en-GB"; 8499 return (i === "en-US" || i.startsWith("en-")) && (i = "en-GB"), e.toLocaleDateString(i, { 8500 day: "2-digit", 8501 month: "2-digit", 8502 year: "numeric" 8503 }); 8504 } catch (e) { 8505 return t; 8506 } 8507 } 8508 /** 8509 * Determina la clase CSS para un valor (positivo/negativo) 8510 */ 8511 getValueClass(t) { 8512 return t == null ? "" : t < 0 ? "negative" : t > 0 ? "positive" : ""; 8513 } 8514 /** 8515 * Renderiza el componente cuando está cargando 8516 */ 8517 renderLoading() { 8518 return g`<div class="loading">${u("Cargando datos...", { 8519 desc: "Loading message" 8520 })}</div>`; 8521 } 8522 /** 8523 * Renderiza el componente cuando hay un error 8524 */ 8525 renderError() { 8526 return g`<div class="error">${this.error}</div>`; 8527 } 8528 /** 8529 * Renderiza el componente cuando no hay datos 8530 */ 8531 renderNoData() { 8532 return g`<div>${this.getNoDataMessage()}</div>`; 8533 } 8534 /** 8535 * Renderiza el componente 8536 */ 8537 render() { 8538 return this.loading ? this.renderLoading() : this.error ? this.renderError() : this.data ? this.renderContent() : this.renderNoData(); 8539 } 8540 }; 8541 kt.styles = Ns; 8542 je([ 8543 $({ type: String }) 8544 ], kt.prototype, "locale", 2); 8545 je([ 8546 $({ 8547 type: Boolean, 8548 attribute: "show-header", 8549 converter: { 8550 fromAttribute: (s) => s === "false" ? false : s !== null 8551 }, 8552 reflect: true 8553 }) 8554 ], kt.prototype, "showHeader", 2); 8555 je([ 8556 C() 8557 ], kt.prototype, "loading", 2); 8558 je([ 8559 C() 8560 ], kt.prototype, "error", 2); 8561 je([ 8562 C() 8563 ], kt.prototype, "data", 2); 8564 var ra = /* @__PURE__ */ Symbol.for(""); 8565 var _h = (s) => { 8566 if ((s == null ? void 0 : s.r) === ra) 8567 return s == null ? void 0 : s._$litStatic$; 8568 }; 8569 var qs = (s) => ({ _$litStatic$: s, r: ra }); 8570 var fn = /* @__PURE__ */ new Map(); 8571 var $h = (s) => (t, ...e) => { 8572 const i = e.length; 8573 let r, n; 8574 const a = [], o = []; 8575 let l, h = 0, c = false;
8576 for (; h < i; ) { 8577 for (l = t[h]; h < i && (n = e[h], (r = _h(n)) !== void 0); ) 8578 l += r + t[++h], c = true; 8579 h !== i && o.push(n), a.push(l), h++; 8580 } 8581 if (h === i && a.push(t[i]), c) { 8582 const d = a.join("$$lit$$"); 8583 (t = fn.get(d)) === void 0 && (a.raw = a, fn.set(d, t = a)), e = o; 8584 } 8585 return s(t, ...e); 8586 }; 8587 var Us = $h(g); 8588 function Vs(s) { 8589 if (!s || s.trim() === "") 8590 return "p"; 8591 const t = parseInt(s, 10); 8592 return isNaN(t) || t < 1 || t > 6 ? "p" : `h${t}`; 8593 } 8594 function Dt(s, t, e) { 8595 const i = qs(Vs(s)); 8596 return Us`<${i} class="${t}">${e}</${i}>`; 8597 } 8598 var js = 6e5; 8599 var Dh = 200; 8600 var Mh = 5e4; 8601 var na = "swc_cache_"; 8602 var es = 2; 8603 var mn = [2e3, 5e3]; 8604 var Hs = "x-stock-source"; 8605 var Eh = "bd-fallback"; 8606 var Zt = /* @__PURE__ */ new Map(); 8607 var is = /* @__PURE__ */ new Map(); 8608 function ws(s) { 8609 return na + s; 8610 } 8611 function zh(s) { 8612 try { 8613 const t = localStorage.getItem(ws(s)); 8614 if (!t) 8615 return null; 8616 const e = JSON.parse(t); 8617 return Date.now() - e.timestamp > js ? (localStorage.removeItem(ws(s)), null) : e; 8618 } catch (t) { 8619 return null; 8620 } 8621 } 8622 function Fh(s, t) { 8623 try { 8624 const e = JSON.stringify(t); 8625 e.length <= Mh && localStorage.setItem(ws(s), e); 8626 } catch (e) { 8627 } 8628 } 8629 function Ph() { 8630 try { 8631 const s = []; 8632 for (let e = 0; e < localStorage.length; e++) { 8633 const i = localStorage.key(e); 8634 i != null && i.startsWith(na) && s.push(i); 8635 } 8636 const t = Date.now(); 8637 for (const e of s) 8638 try { 8639 const i = localStorage.getItem(e); 8640 if (!i) 8641 continue; 8642 const r = JSON.parse(i); 8643 t - r.timestamp > js && localStorage.removeItem(e); 8644 } catch (i) { 8645 localStorage.removeItem(e); 8646 } 8647 } catch (s) { 8648 } 8649 } 8650 function Ah() { 8651 for (; Zt.size >= Dh; ) { 8652 const s = Zt.keys().next().value; 8653 if (s !== void 0) 8654 Zt.delete(s); 8655 else 8656 break; 8657 } 8658 } 8659 function ri(s) { 8660 const t = { "Content-Type": "application/json" }; 8661 return s.stockSource && (t[Hs] = s.stockSource), new Response(JSON.stringify(s.data), { 8662 status: s.status, 8663 statusText: s.statusText, 8664 headers: t 8665 }); 8666 } 8667 function pn(s) { 8668 const t = s.status === 204 ? null : s.body, e = {}; 8669 return s.stockSource && (e[Hs] = s.stockSource), s.contentType && (e["Content-Type"] = s.contentType), new Response(t, { 8670 status: s.status, 8671 statusText: s.statusText, 8672 headers: e 8673 }); 8674 } 8675 function gn(s) { 8676 return L(this, null, function* () { 8677 try { 8678 return typeof s.text == "function" ? yield s.text() : ""; 8679 } catch (t) { 8680 return ""; 8681 } 8682 }); 8683 } 8684 function R(s, t) { 8685 return L(this, null, function* () { 8686 var c, d; 8687 const e = () => t !== void 0 ? fetch(s, t) : fetch(s), i = typeof s == "string" ? s : s instanceof URL ? s.href : s.url; 8688 if (((d = (c = t == null ? void 0 : t.method) != null ? c : typeof s != "string" && !(s instanceof URL) ? s.method : void 0) != null ? d : "GET").toUpperCase() !== "GET") 8689 return e(); 8690 const n = Zt.get(i); 8691 if (n && Date.now() - n.timestamp <= js) 8692 return ri(n); 8693 n && Zt.delete(i); 8694 const a = zh(i); 8695 if (a) 8696 return Zt.set(i, a), ri(a); 8697 const o = is.get(i); 8698 if (o) { 8699 const f = yield o; 8700 return "buffered" in f ? pn(f) : ri(f); 8701 } 8702 const l = (() => L(this, null, function* () { 8703 var f, m, p, v, b, y, x, S, w, _, D, z, P, E, H; 8704 try { 8705 let J = null, j = 0; 8706 for (let Q = 0; Q <= es; Q++) { 8707 if (Q > 0) { 8708 if ((f = t == null ? void 0 : t.signal) != null && f.aborted) 8709 throw new DOMException("The operation was aborted.", "AbortError"); 8710 const U = j || mn[Math.min(Q - 1, mn.length - 1)]; 8711 if (yield new Promise((Et) => setTimeout(Et, U)), j = 0, (m = t == null ? void 0 : t.signal) != null && m.aborted) 8712 throw new DOMException("The operation was aborted.", "AbortError"); 8713 } 8714 let N; 8715 try { 8716 N = yield e(); 8717 } catch (U) { 8718 if (U && U.name === "AbortError") 8719 throw U; 8720 if (Q < es) 8721 continue; 8722 throw U; 8723 } 8724 const W = (p = N.status) != null ? p : 200, at = (v = N.statusText) != null ? v : ""; 8725 if (N.ok) { 8726 const U = (x = (y = (b = N.headers) == null ? void 0 : b.get) == null ? void 0 : y.call(b, Hs)) != null ? x : null, Et = U == null ? void 0 : U.toLowerCase().trim().split(/[;,\s]+/)[0], rt = ((_ = (w = (S = N.headers) == null ? void 0 : S.get) == null ? void 0 : w.call(S, "cache-control")) != null ? _ : "").toLowerCase(), bt = (P = (z = (D = N.headers) == null ? void 0 : D.get) == null ? void 0 : z.call(D, "content-type")) != null ? P : null, da = Et === Eh || rt.includes("no-store"); 8727 if (W === 204) 8728 return { buffered: true, body: "", status: W, statusText: at, stockSource: U, contentType: bt }; 8729 if (bt && !bt.toLowerCase().includes("json")) 8730 return { buffered: true, body: yield gn(N), status: W, statusText: at, stockSource: U, contentType: bt }; 8731 let Mi; 8732 try { 8733 Mi = yield N.json(); 8734 } catch (ua) { 8735 return { buffered: true, body: "", status: W, statusText: at, stockSource: U, contentType: bt }; 8736 } 8737 if (da) 8738 return { 8739 buffered: true, 8740 body: JSON.stringify(Mi), 8741 status: W, 8742 statusText: at, 8743 stockSource: U, 8744 contentType: bt != null ? bt : "application/json" 8745 }; 8746 const Ei = { 8747 data: Mi, 8748 status: W, 8749 statusText: at, 8750 stockSource: U, 8751 timestamp: Date.now() 8752 }; 8753 return Ah(), Zt.set(i, Ei), Fh(i, Ei), Ei; 8754 } 8755 J = { buffered: true, body: yield gn(N), status: W, statusText: at }; 8756 const Lt = (H = (E = N.headers) == null ? void 0 : E.get) == null ? void 0 : H.call(E, "retry-after"); 8757 if (Lt) { 8758 const U = Number(Lt); 8759 j = isNaN(U) ? 0 : U * 1e3; 8760 } 8761 if (W < 500 && W !== 429 || Q >= es) 8762 return J; 8763 } 8764 return J; 8765 } finally { 8766 is.delete(i); 8767 } 8768 }))(); 8769 is.set(i, l); 8770 const h = yield l; 8771 return "buffered" in h ? pn(h) : ri(h); 8772 }); 8773 } 8774 Ph(); 8775 var Th = Object.defineProperty; 8776 var Ih = Object.getOwnPropertyDescriptor; 8777 var He = (s, t, e, i) => { 8778 for (var r = i > 1 ? void 0 : i ? Ih(t, e) : t, n = s.length - 1, a; n >= 0; n--) 8779 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 8780 return i && r && Th(t, e, r), r; 8781 }; 8782 var Se = class extends kt { 8783 constructor() { 8784 super(...arguments), this.symbol = "", this.locale = "", this.showHeader = true, this.empty = false, this.initialSymbol = null, this.ssrIdPrefix = null, this.seoSeedObserver = null, this.seoSeedParseCleanup = null; 8785 } 8786 getSsrIdPrefix() { 8787 return this.ssrIdPrefix === null && (this.ssrIdPrefix = `ssr-${Math.random().toString(36).slice(2, 8)}-`), this.ssrIdPrefix; 8788 } 8789 /** 8790 * Registramos el sÃmbolo emitido por el servidor en el primer attach. El SSR 8791 * fallback de `.rnk-SeoStaticData` SOLO aplica para ese sÃmbolo; si el host 8792 * lo swappea client-side, `getSeoStaticOuterHTML()` devolverá null aunque el 8793 * wrapper siga vivo en el light-DOM (Codex round 8). 8794 */ 8795 connectedCallback() { 8796 super.connectedCallback(), this.initialSymbol === null && (this.initialSymbol = this.symbol || null), ys(this), this.projectSeoSeedWhenParsed(); 8797 } 8798 disconnectedCallback() { 8799 super.disconnectedCallback(), this.cleanupSeoSeedWatch(); 8800 } 8801 projectSeoSeedWhenParsed() { 8802 if (this.hasSeoStaticContent()) 8803 return; 8804 const t = this.ownerDocument, e = t == null ? void 0 : t.defaultView; 8805 if (!e || typeof e.MutationObserver == "undefined" || t.readyState !== "loading") 8806 return; 8807 const i = new e.MutationObserver((n) => { 8808 n.some((a) => a.addedNodes.length > 0) && this.tryProjectParsedSeed(); 8809 }); 8810 i.observe(this, { childList: true, subtree: true }); 8811 const r = () => this.cleanupSeoSeedWatch(); 8812 t.addEventListener("DOMContentLoaded", r, { once: true }), this.seoSeedObserver = i, this.seoSeedParseCleanup = () => t.removeEventListener("DOMContentLoaded", r), this.tryProjectParsedSeed(); 8813 } 8814 tryProjectParsedSeed() { 8815 this.hasSeoStaticContent() && (this.cleanupSeoSeedWatch(), ys(this), this.requestUpdate()); 8816 } 8817 cleanupSeoSeedWatch() { 8818 this.seoSeedObserver && (this.seoSeedObserver.disconnect(), this.seoSeedObserver = null), this.seoSeedParseCleanup && (this.seoSeedParseCleanup(), this.seoSeedParseCleanup = null); 8819 } 8820 /** 8821 * Capturamos `initialSymbol` en el primer `symbol` no vacÃo detectado vÃa 8822 * `updated()` para cubrir el caso de late binding: si el host setea 8823 * `symbol` DESPUÃS del upgrade (común con frameworks que bindean atributos 8824 * post-mount), `connectedCallback()` ya corrió con `symbol=""` y el 8825 * stale-guard nunca se activarÃa (Codex round 9). 8826 */ 8827 updated(t) { 8828 super.updated(t), t.has("symbol") && this.initialSymbol === null && this.symbol && (this.initialSymbol = this.symbol); 8829 } 8830 /** 8831 * Datos de ratios financieros (alias para mantener compatibilidad) 8832 */ 8833 get ratioData() { 8834 return this.data; 8835 } 8836 set ratioData(t) { 8837 this.data = t; 8838 } 8839 /** 8840 * Verifica si se debe obtener los datos 8841 */ 8842 shouldFetchData() { 8843 return !!this.symbol; 8844 } 8845 /** 8846 * Verifica si una propiedad clave ha cambiado 8847 */ 8848 hasKeyPropertyChanged(t) { 8849 return t.has("symbol") && !!this.symbol; 8850 } 8851 /** 8852 * Obtiene los datos de la API 8853 */ 8854 fetchData() { 8855 return L(this, null, function* () { 8856 if (this.symbol) { 8857 this.loading = true, this.error = null; 8858 try { 8859 const t = yield R(`${q.API_BASE_URL}/asset-data/financial-ratios-ttm?symbol=${encodeURIComponent(this.symbol)}`); 8860 if (!t.ok) 8861 throw new Error(`${u("Error", { 8862 desc: "Error message prefix when API request fails" 8863 })}: ${t.statusText}`); 8864 const e = yield t.json(); 8865 this.processData(e); 8866 } catch (t) {
8867 this.error = t instanceof Error ? t.message : String(t), console.error(`Error fetching financial ratios: ${t}`), this.warnOnSeoFallback(t); 8868 } finally { 8869 this.loading = false; 8870 } 8871 } 8872 }); 8873 } 8874 /** 8875 * Helper compartido para que cualquier subclase que sobreescriba `fetchData()` 8876 * (stock-list-item, stock-briefing-ratios, etc.) emita el mismo warning de 8877 * observability cuando el fetch falla y existe SSR fallback en el light-DOM. 8878 * Centralizado para evitar drift entre overrides (Codex round 7). 8879 */ 8880 warnOnSeoFallback(t) { 8881 this.hasSeoStaticContent() && console.warn("[stock-element] Fetch errored; SSR fallback engaged:", t); 8882 } 8883 /** 8884 * Formatea un valor decimal 8885 * Delegates to FormatUtils.formatDecimal for consistent formatting 8886 */ 8887 formatDecimal(t, e = 2) { 8888 return F.formatDecimal(t, this.locale || "en-US", e); 8889 } 8890 /** 8891 * Formatea un valor como porcentaje 8892 * Delegates to FormatUtils.formatPercentage for consistent formatting 8893 */ 8894 formatPercentage(t) { 8895 return F.formatPercentage(t, this.locale || "en-US"); 8896 } 8897 /** 8898 * Formatea un valor como moneda 8899 * Delegates to FormatUtils.formatCurrency for consistent formatting 8900 */ 8901 formatCurrency(t, e = 2, i = "USD") { 8902 return F.formatCurrency(t, this.locale || "en-US", i, e); 8903 } 8904 /** 8905 * Determina la clase CSS para un valor (positivo/negativo) 8906 */ 8907 getValueClass(t) { 8908 return t == null ? "" : t < 0 ? "negative" : t > 0 ? "positive" : ""; 8909 } 8910 /** 8911 * Renderiza el componente cuando está cargando. 8912 * 8913 * Initial paint desde el valor persistido (TDT-RNK-3273, fase 1): si el host 8914 * trae SSR en `.rnk-SeoStaticData` (columnas `last_*` que emite la vista de 8915 * Rankia), lo proyectamos como PRIMER pintado en lugar del spinner «Cargando 8916 * datos...», y el fetch en vivo lo reemplaza al resolver (`renderContent()`). 8917 * En fichas poco visitadas el quote frÃo tarda ~0,5 s por el cache miss del 8918 * proxy; pintar el persistido elimina la latencia PERCIBIDA sin coste de 8919 * backend. Además evita el parpadeo SSRâspinnerâlive: antes, el primer render 8920 * (data=null, loading=false) mostraba el fallback vÃa `renderNoData()`, luego 8921 * `loading=true` tapaba con el spinner; ahora se mantiene el persistido hasta 8922 * que llega el dato en vivo. Mismo patrón que `renderError()`/`renderNoData()`. 8923 */ 8924 renderLoading() { 8925 if (this.ratioData && this.ratioData.symbol === this.symbol) 8926 return g`${this.renderContent()}`; 8927 const t = this.renderSeoStaticFallback(); 8928 return t !== null ? t : g`<div class="loading">${u("Cargando datos...", { 8929 desc: "Loading message" 8930 })}</div>`; 8931 } 8932 /** 8933 * Renderiza el componente cuando hay un error. 8934 * 8935 * Igual que `renderNoData()`, si el host trae SSR fallback en `.rnk-SeoStaticData` 8936 * (small-cap sin cobertura FMP, upstream caÃdo, etc.) lo proyectamos en lugar 8937 * de tapar con el mensaje de error â la promesa del patrón persistido también 8938 * debe sostenerse frente a fallos de red/5xx, no solo cuando la respuesta llega 8939 * vacÃa. El aviso a observability se emite en `fetchData()`, NO aquÃ, para 8940 * mantener `render()` libre de side effects (Codex round 6). 8941 */ 8942 renderError() { 8943 const t = this.renderSeoStaticFallback(); 8944 return t !== null ? t : g`<div class="error">${this.error}</div>`; 8945 } 8946 /** 8947 * Renderiza el componente cuando no hay datos. 8948 * 8949 * Si el host tiene contenido SSR pre-renderizado dentro de `.rnk-SeoStaticData` 8950 * (patrón de Rankia: la vista emite la tabla con datos persistidos en BD vÃa 8951 * `PoblarAccionFundamentalsJob` â TDT-RNK-117/118 â para fallback con caché 8952 * frÃa), lo renderizamos en el shadow vÃa `unsafeHTML` en lugar de tapar con 8953 * el mensaje de "No hay datos disponibles". Mantiene la promesa del patrón 8954 * SSR persistido cuando nuestro propio fetch falla (small-caps sin cobertura 8955 * FMP, throttle upstream, etc.). Reportado por Jamil 2026-05-19 sobre 8956 * `908-devices-inc-mass` (TDT-RNK-2015). 8957 */ 8958 renderNoData() { 8959 const t = this.renderSeoStaticFallback(); 8960 return t !== null ? t : g`<div>${u("No hay datos disponibles. Por favor, proporcione un s\xEDmbolo de acci\xF3n v\xE1lido.", { 8961 desc: "Message shown when no data is available" 8962 })}</div>`; 8963 } 8964 /** 8965 * Helper centralizado que proyecta el SSR fallback de `.rnk-SeoStaticData` si 8966 * existe contenido visible. Devuelve `null` cuando el host NO trae fallback 8967 * (o el wrapper está vacÃo / sólo trae script/style/template). 8968 * 8969 * Centralizado en la base para evitar drift entre los 7 overrides que lo 8970 * consumen (Codex round 6). Cada override que sobreescriba `renderNoData()` 8971 * con copy localizada debe pedir esto PRIMERO; si devuelve null, cae a su 8972 * propia UI custom. 8973 * 8974 * `unsafeHTML` está acotado a contenido emitido por nuestra view server-side 8975 * de Rankia (Rails SSR), nunca input de usuario/CMS. Trust boundary documentada. 8976 */ 8977 renderSeoStaticFallback() {
8978 const t = this.getSeoStaticOuterHTML(); 8979 return t === null ? null : g`<div class="ssr-fallback">${ia(t)}</div>`; 8980 } 8981 /** 8982 * Devuelve el `outerHTML` de `.rnk-SeoStaticData` cuando trae contenido visible, 8983 * pero CLONADO y con `<script>/<style>/<template>` removidos. 8984 * 8985 * Usamos `unsafeHTML` sobre este string en lugar de un `<slot>` abierto por dos 8986 * razones: (1) un `<slot>` sin nombre proyectarÃa TODO el light-DOM del host â 8987 * si algún dÃa se añade otro hijo (p.ej. fragmentos auxiliares), también 8988 * aparecerÃa en estados de error/sin-datos. (2) un slot nombrado obligarÃa a 8989 * coordinar el atributo `slot="seo-static"` en el HAML de Rankia. Inyectando 8990 * el `outerHTML` del nodo SSR mantenemos el alcance pegado a ese elemento y la 8991 * compatibilidad con el markup actual. El contenido es trusted (lo emite 8992 * nuestra view server-side, no input de usuario). 8993 * 8994 * Preservamos el wrapper `.rnk-SeoStaticData` (via `outerHTML`) porque CSS y 8995 * data-attributes existentes en Rankia se apoyan en esa clase. Pero antes 8996 * STRIPEAMOS `<script>/<style>/<template>` DEEP del clon: si la vista 8997 * server-side emite JSON-LD dentro del wrapper (o anidado en cualquier 8998 * descendiente), re-inyectarlo en el shadow lo duplicarÃa frente al crawler 8999 * (el original sigue vivo en el light-DOM). Estilos embebidos podrÃan además 9000 * aplicarse fuera de su scope original. 9001 * 9002 * Consideramos el nodo "útil" después del strip si tiene contenido estructural 9003 * (al menos un nodo elemento descendiente) O texto visible. Un check basado 9004 * sólo en `textContent.trim()` descartarÃa SSR icon-only (p.ej. un `<svg>` o 9005 * `<img>` sin texto) que sà es información válida (Codex round 8). 9006 * 9007 * Además stripeamos atributos `on*` y URLs `javascript:`/`vbscript:`/ 9008 * `data:text/html` como defensa en profundidad. El contenido viene de 9009 * nuestra view server-side y se considera trusted, pero la sanitización 9010 * client-side actúa como belt-and-suspenders frente a un futuro cambio que 9011 * incorpore HTML de CMS o input de usuario al wrapper SSR (Codex round 7). 9012 * 9013 * Stale-guard (Codex round 8): si el host swappea `symbol` client-side, el 9014 * SSR del light-DOM ya no aplica al sÃmbolo activo â devolvemos null para 9015 * que el fetch del nuevo sÃmbolo sea autoritativo. 9016 * 9017 * Sin cache: re-computamos en cada llamada porque (a) el light-DOM puede 9018 * mutar entre renders (frameworks que hidratan async, intersection observers 9019 * que inyectan contenido) y (b) clone+sanitize+outerHTML sobre el wrapper 9020 * SSR es barato â micro-opt no justifica el riesgo de staleness (Codex round 10). 9021 */ 9022 getSeoStaticOuterHTML() { 9023 var c, d, f; 9024 if (!this.symbol || this.initialSymbol && this.symbol && this.symbol !== this.initialSymbol) 9025 return null; 9026 const t = this.querySelector(".rnk-SeoStaticData"); 9027 if (!t) 9028 return null; 9029 const e = t.cloneNode(true); 9030 if (e.setAttribute(Be, ""), e.hasAttribute(ye)) { 9031 e.removeAttribute(ye); 9032 const m = e, p = m.getAttribute(Ne); 9033 m.removeAttribute(Ne), p && p !== "none" ? m.style.setProperty("display", p) : (c = m.style) == null || c.removeProperty("display"), m.getAttribute("style") === "" && m.removeAttribute("style"); 9034 } 9035 e.querySelectorAll("script, style, template").forEach((m) => m.remove()); 9036 const i = this.getSsrIdPrefix(), r = /* @__PURE__ */ new Map(); 9037 if (e.hasAttribute("id")) { 9038 const m = e.getAttribute("id"), p = i + m; 9039 r.set(m, p), e.setAttribute("id", p); 9040 } 9041 e.querySelectorAll("[id]").forEach((m) => { 9042 const p = m.getAttribute("id"), v = i + p; 9043 r.set(p, v), m.setAttribute("id", v); 9044 }); 9045 const n = [ 9046 "aria-labelledby", 9047 "aria-describedby", 9048 "aria-controls", 9049 "aria-owns", 9050 "aria-flowto", 9051 "aria-activedescendant" 9052 ]; 9053 for (const m of n) 9054 if (e.hasAttribute(m)) { 9055 const v = e.getAttribute(m).split(/\s+/).map((b) => { 9056 var y; 9057 return (y = r.get(b)) != null ? y : b; 9058 }).join(" "); 9059 e.setAttribute(m, v); 9060 } 9061 const a = (m) => { 9062 e.querySelectorAll(`[${m}]`).forEach((p) => { 9063 const b = p.getAttribute(m).split(/\s+/).map((y) => { 9064 var x; 9065 return (x = r.get(y)) != null ? x : y; 9066 }).join(" "); 9067 p.setAttribute(m, b); 9068 }); 9069 }; 9070 a("aria-labelledby"), a("aria-describedby"), a("aria-controls"), a("aria-owns"), a("aria-flowto"), a("aria-activedescendant"), e.querySelectorAll("label[for]").forEach((m) => { 9071 var v; 9072 const p = m.getAttribute("for"); 9073 m.setAttribute("for", (v = r.get(p)) != null ? v : p); 9074 }), e.querySelectorAll("[list]").forEach((m) => { 9075 var v; 9076 const p = m.getAttribute("list"); 9077 m.setAttribute("list", (v = r.get(p)) != null ? v : p); 9078 }), e.querySelectorAll('a[href^="#"]').forEach((m) => { 9079 const v = m.getAttribute("href").slice(1); 9080 v && r.has(v) && m.setAttribute("href", "#" + r.get(v)); 9081 }), e.querySelectorAll('use[href^="#"]').forEach((m) => { 9082 const p = m.getAttribute("href").slice(1); 9083 p && r.has(p) && m.setAttribute("href", "#" + r.get(p)); 9084 }), e.querySelectorAll('use[xlink\\:href^="#"]').forEach((m) => { 9085 const p = m.getAttribute("xlink:href").slice(1); 9086 p && r.has(p) && m.setAttribute("xlink:href", "#" + r.get(p)); 9087 }); 9088 const o = (m) => { 9089 var b; 9090 const v = ((b = m.getAttribute("style")) != null ? b : "").toLowerCase(); 9091 (v.includes("expression(") || v.includes("javascript:") || v.includes("behavior:")) && m.removeAttribute("style"); 9092 }; 9093 e.hasAttribute("style") && o(e), e.querySelectorAll("[style]").forEach(o), e.querySelectorAll("*").forEach((m) => { 9094 for (const p of Array.from(m.attributes)) { 9095 const v = p.name.toLowerCase(), b = p.value.trim().toLowerCase(); 9096 (v.startsWith("on") || b.startsWith("javascript:") || b.startsWith("vbscript:") || b.startsWith("data:text/html")) && m.removeAttribute(p.name); 9097 } 9098 }); 9099 const l = e.querySelector("*") !== null, h = ((f = (d = e.textContent) == null ? void 0 : d.trim().length) != null ? f : 0) > 0; 9100 return !l && !h ? null : e.outerHTML; 9101 } 9102 /** Backwards-compatible alias para clases hijas que ya invocan este método. */ 9103 hasSeoStaticContent() {
9104 return this.getSeoStaticOuterHTML() !== null; 9105 } 9106 /** 9107 * Marca la sección como "sin datos" â que `render()` colapsa vÃa 9108 * `:host([empty]) { display: none }` â PERO solo si el host NO trae un SSR 9109 * fallback persistido en `.rnk-SeoStaticData`. Cuando Sà lo trae, dejamos 9110 * `empty = false` para que `render()` caiga en `renderNoData()`, que proyecta 9111 * el seed persistido en lugar de hacer desaparecer la sección. 9112 * 9113 * Motivo (TDT): el caso FMP «200 con cuerpo nulo» para `search`/`quote` no debe 9114 * colapsar una ficha que sà tiene datos persistidos en BD (columnas `last_*`). 9115 * Antes, `this.empty = true` incondicional borraba el bloque entero âincluido el 9116 * precio del heroâ aunque el seed existiera. Mismo espÃritu que 9117 * `renderError()`/`renderNoData()`, que ya honran el fallback. Sin seed, el 9118 * comportamiento es idéntico al anterior: `empty = true` â sección oculta. 9119 * 9120 * Centralizado aquà para que los tres componentes que usan `empty` 9121 * (`stock-quote-card`, `stock-short-quote`, `stock-key-stats`) compartan la 9122 * misma regla y no vuelva a haber drift. 9123 */ 9124 markEmptyUnlessSeoFallback() { 9125 this.empty = !this.hasSeoStaticContent(); 9126 } 9127 /** 9128 * Un payload de cotización sólo es utilizable si trae `price`. 9129 * 9130 * Motivo (incidente 2026-08-26, Ãndices sin cobertura FMP): el proxy no siempre 9131 * responde «200 con cuerpo nulo». Rankia (Rails) devuelve **200 con un cuerpo de 9132 * error** â`{"error":"Quote not found"}`â cuando el upstream no cubre el sÃmbolo. 9133 * Eso es un objeto *truthy*, asà que una guarda de mera presencia 9134 * (`if (!this.quoteData)`) lo deja pasar: el componente sigue como si tuviera 9135 * datos, lee `price === undefined` y pinta **0** encima de un seed SSR que sà 9136 * traÃa el precio persistido bueno (`^AEX`: 0 en el hero, 1.108,34 en el seed). 9137 * 9138 * Exigir `price` alinea el componente con el helper de Rankia `cached_quote`, 9139 * que ya aplica exactamente este criterio (`return parsed if parsed && parsed['price']`). 9140 * 9141 * `price: 0` se considera dato válido: si el upstream afirma cero, es una 9142 * afirmación, no una ausencia. Lo que se rechaza es la ausencia y lo no numérico. 9143 */ 9144 static hasUsableQuote(t) { 9145 if (!t || typeof t != "object" || Array.isArray(t)) 9146 return false; 9147 const { price: e } = t; 9148 if (typeof e == "number") 9149 return Number.isFinite(e); 9150 if (typeof e != "string") 9151 return false; 9152 const i = e.trim(); 9153 return i !== "" && Number.isFinite(Number(i)); 9154 } 9155 /** 9156 * Renderiza el encabezado con información básica del stock 9157 * Este método es compartido por todos los componentes 9158 */ 9159 renderHeader() { 9160 if (!this.showHeader) 9161 return g``; 9162 if (!this.ratioData) 9163 return this.symbol ? g` 9164 <div class="info-header"> 9165 <div> 9166 ${Dt(this.headerLevel, "stock-name", this.symbol)} 9167 <p class="stock-symbol">${this.symbol}</p> 9168 </div> 9169 </div> 9170 ` : g``; 9171 const { symbol: t } = this.ratioData; 9172 let e, i; 9173 return "name" in this.ratioData && (e = this.ratioData.name), "image" in this.ratioData && (i = this.ratioData.image), g` 9174 <div class="info-header"> 9175 ${i ? g`<img class="stock-image" src="${i}" alt="${u(A`${e || t} logo`, { desc: "Alt text for company logo" })}" onerror="this.style.display='none'" />` : ""} 9176 <div> 9177 ${Dt(this.headerLevel, "stock-name", e || t)} 9178 <p class="stock-symbol">${t}</p> 9179 </div> 9180 </div> 9181 `; 9182 } 9183 /** 9184 * Renderiza el componente 9185 */ 9186 render() { 9187 return this.empty ? I : this.loading ? this.renderLoading() : this.error ? this.renderError() : this.ratioData ? this.renderContent() : this.renderNoData(); 9188 } 9189 }; 9190 He([ 9191 $({ type: String }) 9192 ], Se.prototype, "symbol", 2); 9193 He([ 9194 $({ type: String }) 9195 ], Se.prototype, "locale", 2); 9196 He([ 9197 $({ 9198 type: Boolean, 9199 attribute: "show-header", 9200 converter: { 9201 fromAttribute: (s) =>
9201 s === "false" || s === false ? false : s === "true" || s === true ? true : s !== null 9202 }, 9203 reflect: true 9204 }) 9205 ], Se.prototype, "showHeader", 2); 9206 He([ 9207 $({ type: String, attribute: "header-level" }) 9208 ], Se.prototype, "headerLevel", 2); 9209 He([ 9210 $({ type: Boolean, reflect: true }) 9211 ], Se.prototype, "empty", 2); 9212 var We = K` 9213 :host { 9214 display: block; 9215 font-family: var(--stock-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 9216 padding: var(--stock-padding, 0); 9217 max-width: var(--stock-max-width, 100%); 9218 margin: 0 auto; 9219 font-size: var(--stock-font-size-basis, 18px); 9220 color: var(--stock-text-color, #383d43); 9221 background-color: transparent; 9222 box-sizing: border-box; 9223 } 9224 9225 :host *, *:before, *:after { 9226 box-sizing: border-box; 9227 } 9228 9229 /* TÃtulos y encabezados */ 9230 h2, .section-title { 9231 font-size: var(--stock-title-font-size, 1.5rem); 9232 font-weight: var(--stock-title-weight, 700); 9233 margin-top: 0; 9234 margin-bottom: 1rem; 9235 } 9236 9237 .section-title { 9238 font-size: var(--stock-section-title-font-size, 1.1rem); 9239 padding-bottom: 0.5rem; 9240 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 9241 } 9242 9243 /* Estados de carga y error */ 9244 .loading { 9245 display: flex; 9246 align-items: center; 9247 justify-content: center; 9248 padding: 30px; 9249 font-size: var(--stock-text-size, 15px); 9250 color: var(--stock-muted-color, #64748b); 9251 font-weight: 500; 9252 position: relative; 9253 text-align: center; 9254 } 9255 9256 .loading::before { 9257 content: ''; 9258 display: block; 9259 width: 24px; 9260 height: 24px; 9261 margin-right: 12px; 9262 border: 3px solid var(--stock-primary-color, #1A5275); 9263 border-radius: 50%; 9264 border-top-color: transparent; 9265 animation: spinner 0.8s linear infinite; 9266 } 9267 9268 @keyframes spinner { 9269 to { transform: rotate(360deg); } 9270 } 9271 9272 .error { 9273 color: var(--stock-error-color, #E91101); 9274 padding: 16px; 9275 border: 1px solid var(--stock-error-border-color, rgba(233, 17, 1, 0.25)); 9276 border-radius: 12px; 9277 font-size: var(--stock-small-text-size, 14px); 9278 font-weight: 500; 9279 background-color: var(--stock-error-background, rgba(233, 17, 1, 0.15)); 9280 text-align: center; 9281 margin: 12px 0; 9282 display: flex; 9283 align-items: center; 9284 justify-content: center; 9285 } 9286 9287 .error::before { 9288 content: 'â ï¸'; 9289 margin-right: 8px; 9290 font-size: 18px; 9291 } 9292 9293 /* Contenedores de información */ 9294 .info-container { 9295 display: grid; 9296 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); 9297 gap: 20px; 9298 } 9299 9300 .info-header { 9301 grid-column: 1 / -1; 9302 display: flex; 9303 align-items: center; 9304 margin-bottom: 20px; 9305 padding-bottom: 16px; 9306 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 9307 } 9308 9309 /* Imágenes de acciones */ 9310 .stock-image { 9311 width: 64px; 9312 height: 64px; 9313 object-fit: contain; 9314 border-radius: 12px; 9315 background-color: var(--stock-image-bg, #f8fafc); 9316 padding: 8px; 9317 margin-right: 20px; 9318 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); 9319 transition: transform 0.3s ease; 9320 } 9321 9322 /* TÃtulos de acciones */ 9323 .stock-name { 9324 margin: 0; 9325 font-size: var(--stock-title-size, 22px); 9326 font-weight: var(--stock-title-weight, 700); 9327 color: var(--stock-title-color, #1e293b); 9328 letter-spacing: -0.01em; 9329 } 9330 9331 .stock-symbol { 9332 color: var(--stock-muted-color, #64748b); 9333 margin: 6px 0 0; 9334 font-size: var(--stock-small-text-size, 15px); 9335 font-weight: 500; 9336 padding: 4px 10px; 9337 background-color: var(--stock-symbol-bg, rgba(226, 232, 240, 0.5)); 9338 border-radius: 6px; 9339 display: inline-block; 9340 } 9341 9342 /* Elementos detallados */ 9343 .detail-item, .ratio-item { 9344 padding: 18px; 9345 background-color: var(--stock-item-background, #fff); 9346 border-radius: 8px; 9347 box-shadow: 0px 0px 30px 5px rgba(0, 0, 0, 0.07); 9348 } 9349 9350 .detail-label, .ratio-label { 9351 font-weight: var(--stock-label-weight, 600); 9352 color: var(--stock-label-color, #475569); 9353 margin-bottom: 10px; 9354 font-size: var(--stock-label-size, 14px); 9355 display: flex; 9356 align-items: center; 9357 text-transform: uppercase; 9358 letter-spacing: 0.5px; 9359 } 9360 9361 .detail-value, .ratio-value { 9362 font-size: var(--stock-value-size, 16px); 9363 line-height: 1.6; 9364 color: var(--stock-value-color, #334155);
9365 font-weight: var(--stock-value-weight, 600); 9366 } 9367 9368 /* Estilos especÃficos de ratios */ 9369 .ratios-grid { 9370 display: grid; 9371 grid-template-columns: repeat(var(--stock-ratios-columns, 2), 1fr); 9372 /* Por token, con el 2em de siempre por defecto: la unidad em se ata al 9373 tamano de letra del anfitrion, y con el cuerpo de la ficha a 18px la 9374 rejilla abria 36 donde la entrega pide 24. Quien no configure nada se 9375 queda exactamente como estaba. */ 9376 gap: var(--stock-ratios-gap, 2em); 9377 /* HU-03: expanding one card must not change the height of its row 9378 neighbours. The grid default (stretch) would grow every card in the row 9379 with the tallest one, so each card takes its natural height instead. */ 9380 align-items: start; 9381 } 9382 9383 /* El 32/42 de 1440 para arriba venia de antes del rediseno y abria la rejilla 9384 de mas. Tambien por token, con ese valor de siempre por defecto. */ 9385 @media (min-width: 1440px) { 9386 .ratios-grid { 9387 gap: var(--stock-ratios-gap, 32px 42px); 9388 } 9389 } 9390 9391 .ratio-item { 9392 display: flex; 9393 justify-content: space-between; 9394 align-items: center; 9395 padding: 24px 24px 16px; 9396 } 9397 9398 /* Hover del diseno: una ligera elevacion, sin tocar el fondo ni el borde. 9399 La sombra reutiliza el par que ya usa la tarjeta hermana stock-mini-chart, 9400 que parte EXACTAMENTE de esta misma sombra en reposo (0 0 30px 5px al 7%): 9401 sube el desenfoque y la opacidad, de modo que la tarjeta se despega del 9402 fondo. Cambiarla por una sombra de otra forma (con desplazamiento vertical) 9403 encogeria el halo y en pantalla se leeria como que la tarjeta BAJA. 9404 9405 Todo dentro de (hover: hover) porque en tactil el :hover se queda pegado 9406 tras el toque y la tarjeta se quedaria elevada hasta tocar en otro sitio. */ 9407 @media (hover: hover) { 9408 .ratio-item { 9409 transition: box-shadow 0.2s ease, transform 0.2s ease; 9410 } 9411 9412 .ratio-item:hover { 9413 box-shadow: var(--stock-ratio-card-shadow-hover, 0 0 35px 8px rgba(0, 0, 0, 0.1)); 9414 transform: translateY(var(--stock-ratio-card-lift-hover, -4px)); 9415 } 9416 9417 /* Quien pide menos movimiento conserva la sombra: la elevacion se sigue 9418 leyendo, pero la tarjeta no se desplaza bajo el puntero. */ 9419 @media (prefers-reduced-motion: reduce) { 9420 .ratio-item { 9421 transition: box-shadow 0.2s ease; 9422 } 9423 9424 .ratio-item:hover { 9425 transform: none; 9426 } 9427 } 9428 } 9429 9430 /* Valor + variación respecto al periodo anterior. 9431 Se alinea a la derecha para que el valor siga leyéndose como antes 9432 cuando la tarjeta no tiene comparación disponible. */ 9433 .ratio-value-group { 9434 display: flex; 9435 align-items: center; 9436 gap: 10px; 9437 flex-wrap: wrap; 9438 justify-content: flex-end; 9439 } 9440 9441 .ratio-change { 9442 display: flex; 9443 flex-direction: column; 9444 align-items: flex-end; 9445 gap: 2px; 9446 } 9447 9448 .ratio-change-badge { 9449 display: inline-flex; 9450 align-items: center; 9451 gap: 4px; 9452 font-size: var(--stock-ratio-badge-size, var(--stock-small-text-size, 15px)); 9453 line-height: var(--stock-ratio-badge-line, inherit); 9454 font-weight: 500; 9455 padding: 2px 8px; 9456 border-radius: 6px; 9457 white-space: nowrap; 9458 } 9459 9460 .ratio-change-badge.positive { 9461 color: var(--stock-success-color, #00856f); 9462 background-color: var(--stock-success-bg, rgba(0, 133, 111, 0.15)); 9463 } 9464 9465 .ratio-change-badge.negative { 9466 color: var(--stock-danger-color, #e91101); 9467 background-color: var(--stock-danger-bg, rgba(233, 17, 1, 0.15)); 9468 } 9469 9470 .ratio-change-badge.neutral { 9471 color: var(--stock-muted-color, #5a6773); 9472 background-color: var(--stock-symbol-bg, rgba(226, 232, 240, 0.5)); 9473 } 9474 9475 .ratio-change-baseline { 9476 font-size: var(--stock-ratio-baseline-size, var(--stock-tiny-text-size, 12px)); 9477 line-height: var(--stock-ratio-baseline-line, inherit); 9478 color: var(--stock-muted-color, #5a6773); 9479 white-space: nowrap; 9480 } 9481 9482 /* Tarjeta con panel educativo. Solo la pintan las tarjetas que tienen copy en 9483 la entrega de diseño: el resto conserva el markup y el layout de siempre, 9484 incluido el que stock-debt-ratios construye por su cuenta. */ 9485 .ratio-item.has-disclosure { 9486 display: block; 9487 /* Por token, con el relleno heredado por defecto: la entrega lo baja a 24 en 9488 los cuatro lados, pero quien no configure nada se queda con el 24/24/16 de 9489 siempre. */ 9490 padding: var(--stock-ratio-card-padding, 24px 24px 16px); 9491 } 9492 9493 /* La entrega baja el relleno de las tarjetas de metricas a 16px en los cuatro 9494 lados por debajo de 900px. Tambien por token. */ 9495 @media (max-width: 899.98px) { 9496 .ratio-item.has-disclosure { 9497 padding: var(--stock-ratio-card-padding-mobile, var(--stock-ratio-card-padding, 24px 24px 16px)); 9498 } 9499 } 9500 9501 .ratio-item-main { 9502 display: flex; 9503 justify-content: space-between; 9504 /* La entrega alinea arriba y separa 24; el reparto de siempre era centrado 9505 y sin hueco declarado. */ 9506 align-items: var(--stock-ratio-main-align, center); 9507 gap: var(--stock-ratio-main-gap, normal); 9508 } 9509 9510 .ratio-disclosure { 9511 margin-top: 12px; 9512 } 9513 9514 /* La Entrega 2 mide esta tarjeta en 117px: una fila de 40 con la etiqueta y el 9515 badge, 8 de separacion y una de 21 con "Mas informacion" a la izquierda y la 9516 referencia a la derecha. Antes la referencia se apilaba bajo el badge y la 9517 primera fila media 54. */ 9518 .has-disclosure .ratio-item-main { 9519 margin-bottom: var(--stock-ratio-main-gap-below, 0); 9520 } 9521 9522 .has-disclosure .ratio-value-group {
9523 align-items: var(--stock-ratio-value-group-align, center); 9524 gap: var(--stock-ratio-value-group-gap, 10px); 9525 } 9526 9527 /* La caja del badge de la entrega: 40 de alto, 8 a los lados y radio 4. Los 9528 valores de siempre (alto automatico, relleno 2/8 y radio 6) siguen siendo el 9529 defecto. */ 9530 .has-disclosure .ratio-change-badge { 9531 height: var(--stock-ratio-badge-height, auto); 9532 padding: var(--stock-ratio-badge-padding, 2px 8px); 9533 border-radius: var(--stock-ratio-badge-radius, 6px); 9534 gap: var(--stock-ratio-badge-gap, 4px); 9535 } 9536 9537 .has-disclosure .ratio-disclosure { 9538 margin-top: var(--stock-ratio-disclosure-gap, 12px); 9539 } 9540 9541 .ratio-disclosure-row { 9542 display: flex; 9543 justify-content: space-between; 9544 align-items: center; 9545 gap: 16px; 9546 } 9547 9548 .ratio-disclosure-toggle { 9549 /* inline-flex para poder separar el icono del texto con gap; el boton sigue 9550 midiendo lo que mide su contenido, como cuando era texto suelto. */ 9551 display: inline-flex; 9552 align-items: center; 9553 gap: var(--stock-ratio-toggle-icon-gap, 6px); 9554 padding: 0; 9555 border: 0; 9556 background: none; 9557 font: inherit; 9558 font-size: var(--stock-ratio-toggle-size, var(--stock-small-text-size, 15px)); 9559 line-height: var(--stock-ratio-toggle-line, inherit); 9560 font-weight: var(--stock-ratio-toggle-weight, 500); 9561 color: var(--stock-primary-color, #1a5275); 9562 cursor: pointer; 9563 text-align: left; 9564 } 9565 9566 .ratio-disclosure-toggle:hover { 9567 color: var(--stock-accent-color, #d4324b); 9568 } 9569 9570 /* El icono de info acompana a la etiqueta. Se dimensiona aqui y no con los 9571 atributos del SVG para que siga al cuerpo de letra del token, y hereda el 9572 color por currentColor, asi el hover del boton lo tine tambien a el. 9573 flex-shrink: 0 para que no se aplaste cuando la etiqueta crece al abrir. */ 9574 .ratio-disclosure-icon { 9575 width: var(--stock-ratio-toggle-icon-size, 16px); 9576 height: var(--stock-ratio-toggle-icon-size, 16px); 9577 flex-shrink: 0; 9578 } 9579 9580 .ratio-disclosure-toggle:focus-visible { 9581 outline: 2px solid var(--stock-accent-color, #d4324b); 9582 outline-offset: 2px; 9583 border-radius: 2px; 9584 } 9585 9586 .ratio-disclosure-panel { 9587 margin-top: 12px; 9588 padding-top: 12px; 9589 border-top: 1px solid var(--stock-border-color, #e6ecef); 9590 } 9591 9592 .ratio-disclosure-panel[hidden] { 9593 display: none; 9594 } 9595 9596 .ratio-disclosure-heading { 9597 margin: 0 0 4px; 9598 font-size: var(--stock-label-size, 14px); 9599 font-weight: 600; 9600 color: var(--stock-label-color, #475569); 9601 } 9602 9603 .ratio-disclosure-text { 9604 margin: 0 0 12px; 9605 font-size: var(--stock-small-text-size, 15px); 9606 line-height: 1.5; 9607 color: var(--stock-muted-color, #5a6773); 9608 } 9609 9610 .ratio-disclosure-text:last-child { 9611 margin-bottom: 0; 9612 } 9613 9614 @media (max-width: 600px) { 9615 .ratio-change-baseline { 9616 display: none; 9617 } 9618 } 9619 9620 /* Colores de valores */ 9621 .negative { 9622 color: var(--stock-negative-color, #d32f2f); 9623 } 9624 9625 .positive { 9626 color: var(--stock-positive-color, #388e3c); 9627 } 9628 9629 .high-debt, .warning { 9630 color: var(--stock-warning-color, #f57c00); 9631 } 9632 9633 /* Enlaces */ 9634 .website-link { 9635 color: var(--stock-link-color, #0d6efd); 9636 text-decoration: none; 9637 } 9638 9639 .website-link:hover { 9640 text-decoration: underline; 9641 } 9642 9643 /* Elemento horizontal con scroll */ 9644 .horizontal-scroll-element { 9645 width: 100%; 9646 display: block; 9647 position: relative; 9648 box-sizing: border-box; 9649 } 9650 9651 .horizontal-scroll-element.initiated { 9652 width: calc(100% + var(--stock-padding, 16px) * 2); 9653 margin-left: calc(-1 * var(--stock-padding, 16px)); 9654 margin-right: calc(-1 * var(--stock-padding, 16px)); 9655 overflow: hidden; 9656 } 9657 9658 .horizontal-scroll-element.initiated::before, 9659 .horizontal-scroll-element.initiated::after { 9660 content: ''; 9661 position: absolute; 9662 top: 0; 9663 bottom: 0; 9664 width: var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)); 9665 pointer-events: none; 9666 z-index: 1; 9667 } 9668 9669 .horizontal-scroll-element.initiated::before { 9670 left: 0; 9671 background: linear-gradient(to right, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); 9672 opacity: 0; 9673 transition: opacity 0.2s ease; 9674 } 9675 9676 .horizontal-scroll-element.initiated.scrolled-left::before { 9677 opacity: 1; 9678 } 9679 9680 .horizontal-scroll-element.initiated::after { 9681 right: 0; 9682 background: linear-gradient(to left, 9683 rgba(255, 255, 255, 1) 0px, 9684 rgba(255, 255, 255, 0.9) 10px, 9685 rgba(255, 255, 255, 0) 100% 9686 ); 9687 width: calc(var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)) * 1.6); 9688 opacity: 1; 9689 transition: opacity 0.2s ease; 9690 } 9691 9692 /* Hide right fade when scrolled to the end */ 9693 .horizontal-scroll-element.initiated.scrolled-right::after { 9694 opacity: 0; 9695 } 9696 9697 .horizontal-scroll-element-inner { 9698 display: flex; 9699 flex-direction: row; 9700 align-items: center; 9701 gap: 8px; 9702 width: 100%; 9703 overflow-x: auto; 9704 -webkit-overflow-scrolling: touch; 9705 scrollbar-width: none; 9706 padding-bottom: 5px; 9707 scroll-behavior: smooth; 9708 box-sizing: border-box; 9709 } 9710 9711 .horizontal-scroll-element-inner::-webkit-scrollbar {
9712 display: none; 9713 } 9714 9715 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner { 9716 padding-left: var(--stock-padding, 16px); 9717 padding-right: var(--stock-padding, 16px); 9718 cursor: grab; 9719 user-select: none; 9720 } 9721 9722 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner:active { 9723 cursor: grabbing; 9724 } 9725 9726 /* 9727 * Fallback SSR: cuando \`renderNoData()\`/\`renderError()\` proyectan el outerHTML 9728 * de \`.rnk-SeoStaticData\` dentro del shadow vÃa \`unsafeHTML\` (TDT-RNK-2015), 9729 * el CSS de Rankia que normalmente estiliza esa clase queda fuera del shadow. 9730 * Estos estilos minimos garantizan una rejilla legible (dl/dt/dd) aunque el 9731 * bundle externo no aplique aqui. Si el host inyecta CSS adicional via 9732 * \`::part\` o variables, sigue funcionando. 9733 */ 9734 .ssr-fallback { 9735 display: block; 9736 } 9737 9738 .ssr-fallback dl { 9739 display: grid; 9740 grid-template-columns: max-content 1fr; 9741 gap: 0.25rem 0.75rem; 9742 margin: 0; 9743 } 9744 9745 .ssr-fallback dt { 9746 font-weight: 600; 9747 } 9748 9749 .ssr-fallback dd { 9750 margin: 0; 9751 } 9752 9753 /* Responsive */ 9754 @media (max-width: 600px) { 9755 .info-header { 9756 flex-direction: column; 9757 align-items: center; 9758 } 9759 9760 .ratios-grid { 9761 grid-template-columns: 1fr; 9762 gap: var(--stock-ratios-gap-mobile, var(--stock-ratios-gap, 1em)); 9763 } 9764 } 9765`; 9766 var _i = K` 9767 .tab-button { 9768 display: flex; 9769 height: 45px; 9770 padding: 12px 16px; 9771 justify-content: center; 9772 align-items: center; 9773 gap: 10px; 9774 border: none; 9775 border-radius: 4px; 9776 background: var(--Neutral-colors-color-neutral-3, #F0F0F0); 9777 cursor: pointer; 9778 transition: all 0.2s ease; 9779 white-space: nowrap; 9780 flex-shrink: 0; 9781 9782 /* Text styles - unselected state */ 9783 color: var(--Neutral-colors-color-neutral-1, #383D43); 9784 font-family: Poppins, sans-serif; 9785 font-size: 18px; 9786 font-style: normal; 9787 font-weight: 500; 9788 line-height: 27px; /* 150% */ 9789 } 9790 9791 .tab-button.active { 9792 background: var(--Primary-colors-color-primary, #1A5275); 9793 9794 /* Text styles - selected state */ 9795 color: var(--Neutral-colors-color-neutral-0, #FFF); 9796 } 9797 9798 .tab-button:hover:not(.active) { 9799 background-color: var(--stock-info-color, rgba(88, 168, 218, 0.15)); 9800 } 9801 9802 .tab-button:focus-visible { 9803 outline: 2px solid var(--Primary-colors-color-primary, #1A5275); 9804 outline-offset: 2px; 9805 } 9806 9807 @media (max-width: 768px) { 9808 .tab-button { 9809 font-size: var(--stock-font-size-small-mobile, 14px); 9810 padding: 6px 12px; 9811 } 9812 } 9813`; 9814 function ss(s, t) { 9815 t.scrollLeft > 0 ? s.classList.add("scrolled-left") : s.classList.remove("scrolled-left"), t.scrollLeft + t.clientWidth >= t.scrollWidth - 1 ? s.classList.add("scrolled-right") : s.classList.remove("scrolled-right"); 9816 } 9817 function aa(s) { 9818 if (s.classList.contains("initiated")) 9819 return; 9820 const t = s.querySelector(".horizontal-scroll-element-inner"); 9821 if (!t) 9822 return; 9823 if (t.offsetWidth === 0 || t.offsetHeight === 0) { 9824 setTimeout(() => aa(s), 50); 9825 return; 9826 } 9827 if (t.scrollWidth > t.clientWidth) { 9828 s.classList.add("initiated"); 9829 const i = { 9830 isDown: false, 9831 startX: 0, 9832 scrollLeft: 0 9833 }, r = (h) => { 9834 i.isDown = true, t.style.cursor = "grabbing", i.startX = h.pageX - t.offsetLeft, i.scrollLeft = t.scrollLeft; 9835 }, n = () => { 9836 i.isDown = false, t.style.cursor = "grab"; 9837 }, a = () => { 9838 i.isDown = false, t.style.cursor = "grab"; 9839 }, o = (h) => { 9840 if (!i.isDown) 9841 return; 9842 h.preventDefault(); 9843 const d = (h.pageX - t.offsetLeft - i.startX) * 2; 9844 t.scrollLeft = i.scrollLeft - d, ss(s, t); 9845 }, l = () => { 9846 ss(s, t); 9847 }; 9848 t.style.cursor = "grab", t.addEventListener("mousedown", r), t.addEventListener("mouseleave", n), t.addEventListener("mouseup", a), t.addEventListener("mousemove", o), t.addEventListener("scroll", l), requestAnimationFrame(() => { 9849 ss(s, t); 9850 }); 9851 } 9852 } 9853 function yt(s) { 9854 (s.renderRoot || s.shadowRoot || s).querySelectorAll(".horizontal-scroll-element").forEach((i) => { 9855 aa(i); 9856 }); 9857 } 9858 var Qe = K` 9859 .no-data-block { 9860 border: 1px solid var(--stock-border-color, #e0e0e0); 9861 border-radius: 8px; 9862 padding: 40px 20px; 9863 display: flex; 9864 align-items: center; 9865 gap: 16px; 9866 background-color: var(--stock-white-color, #ffffff); 9867 } 9868 9869 .no-data-icon-container { 9870 display: flex; 9871 align-items: center; 9872 justify-content: center; 9873 flex-shrink: 0; 9874 position: relative; 9875 width: 85px; 9876 height: 63.969px;
9877 aspect-ratio: 85.00 / 63.97; 9878 } 9879 9880 .no-data-icon { 9881 width: 85px; 9882 height: 63.969px; 9883 aspect-ratio: 85.00 / 63.97; 9884 color: var(--stock-muted-color, #64748b); 9885 opacity: 0.6; 9886 } 9887 9888 .no-data-content { 9889 flex: 1; 9890 display: flex; 9891 flex-direction: column; 9892 gap: 8px; 9893 } 9894 9895 .no-data-title { 9896 font-size: var(--stock-text-size, 14px); 9897 color: var(--stock-muted-color, #64748b); 9898 font-weight: var(--stock-value-weight, 500); 9899 margin: 0; 9900 } 9901 9902 .no-data-description { 9903 font-size: var(--stock-text-size, 14px); 9904 color: var(--stock-muted-color, #64748b); 9905 margin: 0; 9906 line-height: 1.5; 9907 } 9908 9909 @media (max-width: 768px) { 9910 .no-data-block { 9911 padding: 30px 16px; 9912 flex-direction: column; 9913 align-items: flex-start; 9914 gap: 12px; 9915 } 9916 9917 .no-data-icon-container { 9918 width: 70px; 9919 height: 52.68px; 9920 aspect-ratio: 70.00 / 52.68; 9921 align-self: center; 9922 } 9923 9924 .no-data-icon { 9925 width: 70px; 9926 height: 52.68px; 9927 aspect-ratio: 70.00 / 52.68; 9928 } 9929 9930 .no-data-title, 9931 .no-data-description { 9932 font-size: 12px; 9933 } 9934 } 9935`; 9936 function Ye() { 9937 return g` 9938 <div class="no-data-block"> 9939 <div class="no-data-icon-container"> 9940 <svg width="70" height="53" viewBox="0 0 70 53" fill="none" xmlns="http://www.w3.org/2000/svg"> 9941 <path d="M20.857 15.9238C21.1989 15.9238 27.9285 15.8927 29.1096 15.8927C29.9178 15.8927 30.182 16.5297 30.182 16.9491C30.182 17.3686 30.182 51.4376 30.182 51.4376C30.2131 52.0124 29.8867 52.4785 29.3428 52.6338H20.7793C20.2198 52.5717 19.9556 52.2144 19.8623 51.6862C19.8623 51.6862 19.9245 17.555 19.94 16.8559C19.94 16.2345 20.2975 15.8927 20.857 15.9238ZM27.8352 18.223H22.1469V50.3501H27.8352V18.223Z" fill="#5A6773"/> 9942 <path d="M34.2228 24.3594C36.9893 24.3594 39.8023 24.2818 42.3356 24.3284C42.833 24.3284 43.206 24.6546 43.3614 25.3537L43.4391 51.4531C43.4702 51.9813 43.206 52.4163 42.7086 52.6183L34.1762 52.6804C33.71 52.6804 33.3214 52.3852 33.1505 51.9658L33.0728 25.711C33.0728 25.1362 33.2282 24.3128 34.2228 24.3594ZM41.0923 26.6587H35.404V50.3501H41.0923V26.6587Z" fill="#5A6773"/> 9943 <path d="M10.8947 27.1248C11.9827 26.7985 12.7442 28.088 13.4902 28.6472C14.5781 28.1967 16.1945 26.8141 16.8783 28.5074L16.9094 51.593C16.9094 52.0901 16.5519 52.5095 16.0701 52.6494H7.50664C6.94714 52.5872 6.68293 52.2299 6.58968 51.7017L6.55859 29.0667C7.07147 27.3733 8.39252 28.1035 9.54261 28.6783C9.68248 28.6783 10.3663 27.2801 10.8792 27.1248H10.8947ZM14.5781 30.729C13.0706 31.7388 12.6199 31.1329 11.4542 30.1542C10.8015 31.2416 10.0555 31.5834 8.9054 30.8843V50.3657H14.5937V30.7445L14.5781 30.729Z" fill="#5A6773"/> 9944 <path d="M11.2366 24.6235C11.2055 25.1673 10.3507 26.2392 9.72907 26.3635C8.90536 26.5188 7.19576 26.2703 6.44976 25.4003L0.0154812 5.62378C-0.0777692 5.0645 0.201982 4.55184 0.699318 4.28774C3.32587 3.49543 6.10784 2.39242 8.15935 1.75547C8.99861 1.49137 9.62028 1.7244 9.93111 2.57885L16.1789 21.9359C16.2255 22.402 16.1478 22.5729 15.8991 22.9302C15.6816 23.2409 13.7699 24.9964 13.4591 25.1517C12.5577 25.6023 12.0914 24.7478 11.2366 24.608V24.6235ZM7.83298 4.42756L2.65758 6.21412L8.39248 23.738C9.35607 24.3594 9.26282 22.868 9.60473 22.3243C10.3197 21.1281 11.8894 22.2621 12.7442 22.7127L13.6611 21.7806L7.83298 4.42756Z" fill="#5A6773"/> 9945 <path d="M47.1692 33.9448C49.9667 33.9448 52.8419 33.9758 55.5928 33.9137C56.3854 33.8981 56.6963 34.3953 56.6963 35.141C56.6963 40.3919 56.6963 46.0002 56.6963 51.5774C56.603 52.3542 56.2145 52.6804 55.4685 52.6649C53.5413 52.6493 49.3295 52.6493 47.4489 52.6649C46.734 52.6649 46.3455 52.1522 46.3455 51.4376C46.3455 46.14 46.4076 40.4696 46.3455 35.2963C46.3455 34.6749 46.5009 34.1312 47.1847 33.9448H47.1692ZM54.365 36.244H48.6767V50.3501H54.365V36.244Z" fill="#5A6773"/> 9946 <path d="M60.7526 40.9356C63.5656 40.9356 65.8347 40.9045 68.5079 40.9045C69.285 40.9045 69.9533 41.3706 69.9533 42.1318C69.9844 44.6486 70.031 49.216 69.9533 51.453C69.9222 52.1987 69.6425 52.6803 68.8498 52.6803C66.9537 52.6803 62.8818 52.6803 60.8303 52.6803C59.96 52.6803 59.618 52.323 59.587 51.4375C59.5093 49.1227 59.5714 44.3534 59.587 42.1318C59.587 41.557 60.1309 40.9045 60.7371 40.9201L60.7526 40.9356ZM67.622 43.2193H61.9338V50.3345H67.622V43.2193Z" fill="#5A6773"/> 9947 <path d="M54.909 4.87966e-06C55.8104 -0.0621366 56.7429 0.372854 57.2092 1.14962L65.3997 16.5607C66.0524 18.2385 64.98 19.761 63.286 19.761H46.8117C45.3974 19.761 44.1075 18.1764 44.667 16.9646C44.667 16.9646 52.2824 2.57887 52.9196 1.38265C53.5569 0.186429 54.1474 0.046611 54.909 4.87966e-06ZM63.0995 17.4307L55.111 2.33031C54.9245 2.31477 46.9672 17.4307 46.9672 17.4307H63.115H63.0995Z" fill="#5A6773"/>
9948 <path d="M54.9711 6.97533C54.4893 7.02194 54.0697 7.34818 53.9609 7.81424C54.0231 9.08814 53.8366 10.5329 53.9609 11.7758C54.0852 13.0186 55.9658 13.1429 56.2455 11.9311C56.1834 10.6572 56.3699 9.21242 56.2455 7.96959C56.1834 7.31711 55.6239 6.92872 54.9711 6.97533ZM55.0177 13.9507C53.4636 14.0439 53.6501 16.4364 55.2198 16.281C56.6496 16.1412 56.5097 13.873 55.0177 13.9507Z" fill="white"/> 9949 <path d="M54.9712 6.97534C55.6084 6.92873 56.2456 7.30158 56.2456 7.9696C56.2456 9.1969 56.2456 10.564 56.2456 11.9311C56.2456 13.1429 53.961 13.0807 53.961 11.7758C53.961 10.4708 53.9299 9.01047 53.961 7.81425C54.0698 7.33265 54.4894 7.00641 54.9712 6.97534Z" fill="#5A6773"/> 9950 <path d="M55.0178 13.9508C56.5098 13.8731 56.6497 16.1413 55.2199 16.2811C53.6502 16.4365 53.4637 14.0285 55.0178 13.9508Z" fill="#5A6773"/> 9951 </svg> 9952 </div> 9953 <div class="no-data-content"> 9954 <p class="no-data-title"> 9955 ${u("No hay datos disponibles en este momento.", { 9956 desc: "No data available at this moment message" 9957 })} 9958 </p> 9959 <p class="no-data-description"> 9960 ${u("Puede que la informaci\xF3n a\xFAn no est\xE9 actualizada o no est\xE9 disponible temporalmente.", { 9961 desc: "Information may not be updated yet or temporarily unavailable message" 9962 })} 9963 </p> 9964 </div> 9965 </div> 9966 `; 9967 } 9968 var _t = { 9969 upColor: "#16a34a", 9970 downColor: "#dc2626", 9971 baselineColor: "#6b7280", 9972 positiveLine: "#16a34a", 9973 negativeLine: "#dc2626", 9974 positiveAreaTop: "rgba(22, 163, 74, 0.32)", 9975 positiveAreaBottom: "rgba(22, 163, 74, 0.02)", 9976 negativeAreaTop: "rgba(220, 38, 38, 0.32)", 9977 negativeAreaBottom: "rgba(220, 38, 38, 0.02)", 9978 gridColor: "rgba(0, 0, 0, 0.06)", 9979 textColor: "rgba(0, 0, 0, 0.6)", 9980 crosshairColor: "rgba(0, 0, 0, 0.3)",
9981 crosshairLabelBg: "rgba(30, 41, 59, 0.95)", 9982 volumeBar: "rgba(120, 120, 120, 0.5)", 9983 fontFamily: "Inter, -apple-system, BlinkMacSystemFont, sans-serif" 9984 }; 9985 var oa = "es-ES"; 9986 var xs = 2; 9987 var Rh = 4; 9988 function Lh(s, t = xs) { 9989 const e = s || oa, i = new Intl.NumberFormat(e, { 9990 minimumFractionDigits: t, 9991 maximumFractionDigits: t 9992 }); 9993 return (r) => i.format(r); 9994 } 9995 function Nh(s) { 9996 let t = 1 / 0; 9997 for (const e of s) { 9998 if (!Number.isFinite(e) || e === 0) 9999 continue; 10000 const i = Math.abs(e); 10001 i < t && (t = i); 10002 } 10003 return t === 1 / 0 ? xs : t < 1 ? Rh : xs; 10004 } 10005 function Bh(s, t) { 10006 return { 10007 type: "custom", 10008 formatter: Lh(s, t), 10009 minMove: Js(10, -t) 10010 }; 10011 } 10012 function Oh(s, t, e) { 10013 return { 10014 localization: { locale: e || oa }, 10015 layout: { 10016 background: { color: "transparent" }, 10017 textColor: _t.textColor, 10018 fontFamily: _t.fontFamily, 10019 // lightweight-charts paints a clickable TradingView logo in the bottom 10020 // corner of every chart by default (`attributionLogo: true`), which links 10021 // out to tradingview.com from our quote pages. We don't want any external 10022 // link on Rankia's charts, so we disable it here â a single central 10023 // toggle that covers every component that routes through `createSwcChart`. 10024 // Apache-2.0 attribution is still satisfied via the repo NOTICE/licenses. 10025 attributionLogo: false 10026 }, 10027 grid: { 10028 vertLines: { color: _t.gridColor }, 10029 horzLines: { color: _t.gridColor } 10030 }, 10031 rightPriceScale: { borderColor: _t.gridColor }, 10032 timeScale: { 10033 borderColor: _t.gridColor, 10034 timeVisible: false, 10035 secondsVisible: false, 10036 // Clamp the visible range to the loaded dataset. The period buttons 10037 // (1D/1W/1M/1Y/5Y/Max) refetch a fresh series and are the only way to 10038 // navigate through time, so there is never off-screen data to reveal. 10039 // Without these, dragging past the first/last bar scrolled into empty 10040 // canvas and the chart went blank (reported on /acciones/nvidia-nvda). 10041 // Mirrors MyPortfolio's ChartContainer.tsx. 10042 fixLeftEdge: true, 10043 fixRightEdge: true 10044 }, 10045 crosshair: { 10046 mode: hs.Normal, 10047 vertLine: { 10048 color: _t.crosshairColor, 10049 width: 1, 10050 style: Re.Dashed, 10051 labelVisible: true, 10052 labelBackgroundColor: _t.crosshairLabelBg 10053 }, 10054 horzLine: { 10055 color: _t.crosshairColor, 10056 width: 1, 10057 style: Re.Dashed, 10058 labelBackgroundColor: _t.crosshairLabelBg 10059 } 10060 }, 10061 // Interaction model: the chart is embedded in a long, scrollable content 10062 // page (Rankia quote pages, Jamon articles). Leaving lightweight-charts' 10063 // default gestures on made the canvas hijack the page â the mouse wheel / 10064 // trackpad zoomed the chart out ("se aleja") instead of scrolling the 10065 // page, and drag-to-pan let users scroll past the data into a blank 10066 // canvas. We disable all pan/zoom gestures and rely on the period buttons 10067 // for time navigation and the crosshair for reading values, matching the 10068 // period-button-driven UX of the MyPortfolio reference. On touch this also 10069 // lets a vertical swipe over the chart scroll the page as expected, while 10070 // a press-and-hold still raises the crosshair. 10071 handleScroll: false, 10072 handleScale: false, 10073 autoSize: false, 10074 width: s, 10075 height: t 10076 }; 10077 } 10078 function qh(s, t, e = {}) { 10079 var c, d, f, m, p, v; 10080 const i = Math.max(s.clientWidth, 1), r = Math.max(s.clientHeight, 1), n = Oh(i, r, t), a = G(M(M({}, n), e), { 10081 localization: M(M({}, n.localization), (c = e.localization) != null ? c : {}), 10082 // `attributionLogo: false` is re-asserted *after* the caller's `options.layout` 10083 // so a caller can never accidentally re-enable the TradingView logo / external 10084 // link by passing their own `layout`. No external link on the charts, ever. 10085 layout: G(M(M({}, n.layout), (d = e.layout) != null ? d : {}), { attributionLogo: false }), 10086 grid: M(M({}, n.grid), (f = e.grid) != null ? f : {}), 10087 rightPriceScale: M(M({}, n.rightPriceScale), (m = e.rightPriceScale) != null ? m : {}), 10088 timeScale: M(M({}, n.timeScale), (p = e.timeScale) != null ? p : {}), 10089 crosshair: M(M({}, n.crosshair), (v = e.crosshair) != null ? v : {}) 10090 }), o = sh(s, a), l = new ResizeObserver((b) => { 10091 for (const y of b) { 10092 const { width: x, height: S } = y.contentRect; 10093 x > 0 && S > 0 && o.applyOptions({ width: x, height: S }); 10094 } 10095 }); 10096 return l.observe(s), { chart: o, dispose: () => { 10097 l.disconnect(), o.remove(); 10098 } }; 10099 } 10100 function ni(s) { 10101 if (!s) 10102 return 0; 10103 if (s.includes("T") || s.includes(" ")) { 10104 const r = Date.parse(s.replace(" ", "T")); 10105 if (!Number.isNaN(r)) 10106 return Math.floor(r / 1e3); 10107 } 10108 const [t, e, i] = s.split("-").map(Number); 10109 return Math.floor(Date.UTC(t, (e != null ? e : 1) - 1, i != null ? i : 1, 12, 0, 0) / 1e3); 10110 } 10111 var ae = class { 10112 /** 10113 * Constructor 10114 * @param baseUrl Base URL for API requests 10115 */ 10116 constructor(t) { 10117 this.baseUrl = t; 10118 } 10119 /** 10120 * Transforms fund API data to component-expected format 10121 * @param apiResponse API response 10122 * @returns Transformed data for the component 10123 */ 10124 transformFundData(t) { 10125 if (!t.historic || t.historic.length === 0) 10126 return []; 10127 const e = t.historic.filter( 10128 (r) => r.date && r.value !== null && r.value !== void 0 10129 ); 10130 return e.length === 0 ? [] : (e.sort((r, n) => new Date(r.date).getTime() - new Date(n.date).getTime()), e.map((r, n) => { 10131 const a = r.value, o = n > 0 ? e[n - 1].value : a, l = a - o, h = o !== 0 ? l / o * 100 : 0; 10132 return { 10133 symbol: t.isin, 10134 date: r.date, 10135 nav: a, 10136 aum: r.aum, 10137 change: l, 10138 changePercent: h 10139 }; 10140 })); 10141 } 10142 /** 10143 * Fetches product information to get currency and other details 10144 * @param isin Product ISIN 10145 * @returns Product information 10146 * @throws Error with status property if response is not ok 10147 */ 10148 fetchProductInfo(t) { 10149 return L(this, null, function* () { 10150 const e = `${this.baseUrl}/funds/product/${encodeURIComponent(t)}`, i = yield R(e); 10151 if (!i.ok) { 10152 const n = new Error(u(A`Error al obtener información del producto: ${i.statusText}`, { 10153 id: "fund.data.service.product.info.error", 10154 desc: "Error message when product info API request fails" 10155 })); 10156 throw n.status = i.status, n; 10157 } 10158 return yield i.json(); 10159 }); 10160 } 10161 /** 10162 * Fetches historical fund data from the API 10163 * @param options Request options 10164 * @returns Fetched fund data 10165 */ 10166 fetchFundData(t) { 10167 return L(this, null, function* () { 10168 var r, n; 10169 const { isin: e, showHeader: i } = t; 10170 try { 10171 const a = yield this.fetchProductInfo(e), o = `${this.baseUrl}/funds/product/${encodeURIComponent(e)}/historic/nav?currency=${encodeURIComponent(a.currency)}`, l = yield R(o); 10172 if (!l.ok) { 10173 if (l.status === 404) 10174 return { 10175 fundData: [], 10176 fundInfo: null 10177 }; 10178 throw new Error(u(A`Error al obtener datos históricos del fondo: ${l.statusText}`, { 10179 desc: "Error message when fund historic API request fails" 10180 })); 10181 } 10182 const h = yield l.json(), c = this.transformFundData(h); 10183 if (c.length === 0) 10184 return { 10185 fundData: [], 10186 fundInfo: null 10187 }; 10188 let d = null; 10189 return i ? d = { 10190 isin: a.isin, 10191 name: a.name, 10192 description: ((r = a.fund) == null ? void 0 : r.investmentObjective) || "Fondo de inversi\xF3n", 10193 category: (n = a.mainCategory) == null ? void 0 : n.name, 10194 currency: a.currency, 10195 launchDate: a.launchDate, 10196 aum: a.aum, 10197 company: a.company, 10198 fees: a.fees 10199 } : d = { 10200 isin: a.isin, 10201 name: a.name, 10202 currency: a.currency 10203 }, { 10204 fundData: c, 10205 fundInfo: d 10206 }; 10207 } catch (a) { 10208 if (a.status === 404) 10209 return { 10210 fundData: [], 10211 fundInfo: null 10212 }; 10213 throw console.error("Error al obtener datos del fondo:", a), a; 10214 } 10215 }); 10216 } 10217 /** 10218 * Fetches detailed information about a fund 10219 * @param isin Fund ISIN 10220 * @returns Fund information or null if not available 10221 */ 10222 fetchFundInfo(t) { 10223 return L(this, null, function* () { 10224 var e, i; 10225 try { 10226 const r = yield this.fetchProductInfo(t); 10227 return { 10228 isin: r.isin, 10229 name: r.name, 10230 description: ((e = r.fund) == null ? void 0 : e.investmentObjective) || "Fondo de inversi\xF3n", 10231 category: (i = r.mainCategory) == null ? void 0 : i.name, 10232 currency: r.currency, 10233 launchDate: r.launchDate, 10234 aum: r.aum, 10235 company: r.company, 10236 fees: r.fees 10237 }; 10238 } catch (r) { 10239 return console.warn("No se pudo obtener informaci\xF3n detallada del fondo:", r), null; 10240 } 10241 }); 10242 } 10243 }; 10244 var mt = class { 10245 /** 10246 * Calculates the date range for a given timeframe 10247 * @param timeframe The timeframe to calculate (e.g., '1d', '5d', '1m', '6m', 'ytd', '1y', '5y', 'max') 10248 * @param data The data array to calculate from (uses the last date as reference) 10249 * @returns DateRange object with startDate and endDate 10250 */ 10251 static calculateDateRange(t, e) { 10252 if (!e || e.length === 0) 10253 return null; 10254 const i = /* @__PURE__ */ new Date(), r = new Date(Math.min( 10255 i.getTime(), 10256 Math.max(...e.map((a) => new Date(a.date).getTime())) 10257 )); 10258 let n = new Date(r); 10259 switch (t) { 10260 case "1d": 10261 n.setDate(r.getDate() - 1); 10262 break; 10263 case "5d": 10264 n.setDate(r.getDate() - 5); 10265 break; 10266 case "1w": 10267 n.setDate(r.getDate() - 7), n.setDate(n.getDate() + 1); 10268 break; 10269 case "1m": 10270 n.setMonth(r.getMonth() - 1), n.setDate(n.getDate() + 1); 10271 break; 10272 case "3m": 10273 n.setMonth(r.getMonth() - 3), n.setDate(n.getDate() + 1); 10274 break; 10275 case "6m": 10276 n.setMonth(r.getMonth() - 6), n.setDate(n.getDate() + 1); 10277 break; 10278 case "ytd": 10279 n = new Date(r.getFullYear(), 0, 1); 10280 break; 10281 case "1y": 10282 n.setFullYear(r.getFullYear() - 1), n.setDate(n.getDate() + 1); 10283 break; 10284 case "3y": 10285 n.setFullYear(r.getFullYear() - 3), n.setDate(n.getDate() + 1); 10286 break; 10287 case "5y": 10288 n.setFullYear(r.getFullYear() - 5), n.setDate(n.getDate() + 1); 10289 break; 10290 case "10y": 10291 n.setFullYear(r.getFullYear() - 10), n.setDate(n.getDate() + 1); 10292 break; 10293 case "max": 10294 n = new Date(Math.min(...e.map((a) => new Date(a.date).getTime()))); 10295 break; 10296 default: 10297 n.setMonth(r.getMonth() - 1), n.setDate(n.getDate() + 1); 10298 } 10299 return { 10300 startDate: n, 10301 endDate: r 10302 }; 10303 } 10304 /** 10305 * Filters data by timeframe 10306 * @param data Array of time-series data points 10307 * @param timeframe The timeframe to filter by 10308 * @param customMode If true, returns all data without filtering 10309 * @returns FilterResult with filtered data and optional error 10310 */ 10311 static filterDataByTimeframe(t, e, i = false) { 10312 if (!t || t.length === 0) 10313 return { 10314 filteredData: [], 10315 error: void 0 10316 }; 10317 if (i) 10318 return { 10319 filteredData: [...t], 10320 error: void 0 10321 }; 10322 if (e === "max") 10323 return { 10324 filteredData: [...t], 10325 error: void 0 10326 }; 10327 const r = this.calculateDateRange(e, t); 10328 if (!r) 10329 return { 10330 filteredData: [], 10331 error: u("No se pudo calcular el rango de fechas", { 10332 desc: "Error message when date range calculation fails" 10333 }) 10334 }; 10335 const n = t.filter((a) => { 10336 const o = new Date(a.date); 10337 return o >= r.startDate && o <= r.endDate; 10338 }); 10339 return n.length === 0 ? { 10340 filteredData: [], 10341 error: u("No hay datos disponibles para el per\xEDodo seleccionado", { 10342 desc: "Error message when no data is available for the selected timeframe" 10343 }) 10344 } : this.hasInsufficientDataSpan(n, e) ? { 10345 filteredData: [], 10346 error: u("Datos insuficientes para el per\xEDodo solicitado", { 10347 desc: "Error message when data does not span the requested timeframe", 10348 id: "timeframe-filter.insufficient-span" 10349 }) 10350 } : { 10351 filteredData: n, 10352 error: void 0 10353 }; 10354 } 10355 /** 10356 * Gets the last valid date from data (capped at today) 10357 * @param data Array of time-series data points 10358 * @returns The last valid date or null 10359 */ 10360 static getLastValidDate(t) { 10361 if (!t || t.length === 0) 10362 return null; 10363 const e = /* @__PURE__ */ new Date(); 10364 return new Date(Math.min( 10365 e.getTime(), 10366 Math.max(...t.map((i) => new Date(i.date).getTime())) 10367 )); 10368 } 10369 /** 10370 * Calculates the minimum required days for a timeframe (exact match) 10371 * Uses full period requirement with small buffer for weekends/holidays 10372 * @param timeframe The timeframe to check 10373 * @returns Minimum required days or null if no validation needed 10374 */ 10375 static getMinimumRequiredDays(t) { 10376 switch (t) { 10377 case "3y": 10378 return 365 * 3 - 30; 10379 case "5y": 10380 return 365 * 5 - 30; 10381 case "10y": 10382 return 365 * 10 - 30; 10383 default: 10384 return null; 10385 } 10386 } 10387 /** 10388 * Validates if filtered data spans enough of the requested timeframe 10389 * @param filteredData The filtered data array 10390 * @param timeframe The requested timeframe 10391 * @returns true if data span is insufficient, false otherwise 10392 */ 10393 static hasInsufficientDataSpan(t, e) { 10394 const i = this.getMinimumRequiredDays(e); 10395 if (i === null || t.length < 2) 10396 return false;
10397 const r = t.map((a) => new Date(a.date).getTime()).sort((a, o) => a - o); 10398 return (r[r.length - 1] - r[0]) / (1e3 * 60 * 60 * 24) < i; 10399 } 10400 /** 10401 * Calculates days to request based on timeframe 10402 * Useful for API calls that need to know how much historical data to fetch 10403 * @param timeframe The timeframe 10404 * @returns Number of days to request 10405 */ 10406 static calculateDaysToRequest(t) { 10407 switch (t) { 10408 case "1d": 10409 return 2; 10410 case "5d": 10411 return 7; 10412 case "1w": 10413 return 10; 10414 case "1m": 10415 return 35; 10416 case "3m": 10417 return 100; 10418 case "6m": 10419 return 190; 10420 case "ytd": 10421 return 366; 10422 case "1y": 10423 return 380; 10424 case "5y": 10425 return 1830; 10426 case "max": 10427 return 7300; 10428 default: 10429 return 35; 10430 } 10431 } 10432 }; 10433 var ht = class { 10434 /** 10435 * Calculates absolute and percentage change from data array 10436 * @param data Array of time-series data points 10437 * @param valueAccessor Function to extract the value from each data point 10438 * @returns ChangeResult with absolute and percentage change, or null if calculation fails 10439 * @example 10440 * // For stocks 10441 * const result = ChangeCalculator.calculateChange(stockData, (item) => item.close); 10442 * 10443 * // For funds 10444 * const result = ChangeCalculator.calculateChange(fundData, (item) => item.nav); 10445 */ 10446 static calculateChange(t, e) { 10447 if (!t || t.length === 0) 10448 return null; 10449 if (t.length === 1) 10450 return { 10451 absoluteChange: 0, 10452 percentageChange: 0 10453 }; 10454 try { 10455 const i = e(t[0]), r = e(t[t.length - 1]); 10456 if (i == null || r === null || r === void 0) 10457 return null; 10458 if (i === 0) 10459 return { 10460 absoluteChange: r - i, 10461 percentageChange: 0 10462 // Cannot calculate percentage from zero 10463 }; 10464 const n = r - i, a = n / i * 100; 10465 return { 10466 absoluteChange: n, 10467 percentageChange: a 10468 }; 10469 } catch (i) { 10470 return console.error("Error calculating change:", i), null; 10471 } 10472 } 10473 /** 10474 * Calculates only absolute change 10475 * @param data Array of time-series data points 10476 * @param valueAccessor Function to extract the value from each data point 10477 * @returns Absolute change or null if calculation fails 10478 */ 10479 static calculateAbsoluteChange(t, e) { 10480 const i = this.calculateChange(t, e); 10481 return i ? i.absoluteChange : null; 10482 } 10483 /** 10484 * Calculates only percentage change 10485 * @param data Array of time-series data points 10486 * @param valueAccessor Function to extract the value from each data point 10487 * @returns Percentage change or null if calculation fails 10488 */ 10489 static calculatePercentageChange(t, e) { 10490 const i = this.calculateChange(t, e); 10491 return i ? i.percentageChange : null; 10492 } 10493 /** 10494 * Calculates change between two specific values 10495 * @param firstValue Starting value 10496 * @param lastValue Ending value 10497 * @returns ChangeResult with absolute and percentage change, or null if calculation fails 10498 */ 10499 static calculateChangeFromValues(t, e) { 10500 if (t == null || e === null || e === void 0) 10501 return null; 10502 if (t === 0) 10503 return { 10504 absoluteChange: e - t, 10505 percentageChange: 0 10506 // Cannot calculate percentage from zero 10507 }; 10508 const i = e - t, r = i / t * 100; 10509 return { 10510 absoluteChange: i, 10511 percentageChange: r 10512 }; 10513 } 10514 }; 10515 function Uh(s, t) { 10516 var a; 10517 if (!s || s.length === 0) 10518 return []; 10519 if (!t || t.length === 0) 10520 return []; 10521 const e = [...t].sort( 10522 (o, l) => new Date(o.date).getTime() - new Date(l.date).getTime() 10523 ), i = /* @__PURE__ */ new Map(); 10524 e.forEach((o) => { 10525 const l = o.date.split("T")[0]; 10526 i.set(l, o.price); 10527 }); 10528 const r = []; 10529 let n = null; 10530 for (const o of s) { 10531 const l = o.split("T")[0]; 10532 if (i.has(l)) { 10533 const h = i.get(l); 10534 r.push(h), n = h; 10535 } else if (n !== null) 10536 r.push(n); 10537 else { 10538 const h = (a = e[0]) == null ? void 0 : a.price; 10539 h !== void 0 ? (r.push(h), n = h) : r.push(0); 10540 } 10541 } 10542 return r; 10543 } 10544 var Vh = Object.defineProperty; 10545 var jh = Object.getOwnPropertyDescriptor; 10546 var V = (s, t, e, i) => { 10547 for (var r = i > 1 ? void 0 : i ? jh(t, e) : t, n = s.length - 1, a; n >= 0; n--) 10548 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 10549 return i && r && Vh(t, e, r), r; 10550 }; 10551 var O = class extends Se { 10552 constructor() { 10553 super(), this.isin = "", this.timeframe = "5y", this.displayInterval = "1day", this.benchmark = "", this.showHeader = true, this.fundData = [], this.filteredFundData = [], this.fundInfo = null, this.currentNav = null, this.navChange = null, this.navChangePercent = null, this.currentAum = null, this.showCustomPeriodModal = false, this.customStartDate = "", this.customEndDate = "", this.isCu
10553stomPeriod = false, this.lastUpdatedDate = null, this.benchmarkData = [], this.benchmarkLoading = false, this.benchmarkError = null, this.benchmarkName = null, this.alignedBenchmarkPrices = [], this.benchmarkQuoteFetchInProgress = false, this.lastFetchedBenchmarkSymbol = null, this.priceChart = null, this.chartDispose = null, this.fundSeries = null, this.benchmarkSeries = null, this.crosshairHandler = null, this.fundDataByTime = /* @__PURE__ */ new Map(), this.benchmarkByTime = /* @__PURE__ */ new Map(), this.fullFundData = [], this.isInitializing = true, this.fetchInProgress = false, this.initialFetchCompleted = false, this.benchmarkFetchInProgress = false, this.fundDataService = new ae(q.API_BASE_URL); 10554 } 10555 connectedCallback() { 10556 super.connectedCallback(), this.isInitializing = true, this.isin && !this.initialFetchCompleted && this.fetchData().then(() => { 10557 this.isInitializing = false, this.initialFetchCompleted = true; 10558 }); 10559 } 10560 disconnectedCallback() { 10561 super.disconnectedCallback(), this.destroyChart(); 10562 } 10563 firstUpdated(s) { 10564 super.firstUpdated(s), setTimeout(() => { 10565 yt(this); 10566 }, 0); 10567 } 10568 updated(s) { 10569 if (super.updated(s), s.has("timeframe") && this.fullFundData.length > 0 && !this.isCustomPeriod && this.filterDataByTimeframe(), s.has("benchmark")) { 10570 const t = s.get("benchmark"); 10571 this.benchmark && this.benchmark !== t && this.fundData.length > 0 ? (this.benchmarkName = null, this.lastFetchedBenchmarkSymbol = null, this.fetchBenchmarkQuote().then(() => { 10572 this.fetchBenchmarkData(); 10573 })) : this.benchmark || (this.benchmarkData = [], this.benchmarkError = null, this.benchmarkLoading = false, this.benchmarkName = null, this.alignedBenchmarkPrices = [], this.lastFetchedBenchmarkSymbol = null, this.createChart()); 10574 } 10575 setTimeout(() => { 10576 yt(this); 10577 }, 0); 10578 } 10579 setIntervalByTimeframe() { 10580 const s = { 10581 ytd: "1week", 10582 "1m": "1week", 10583 "3m": "1week", 10584 "6m": "1week", 10585 "1y": "1week", 10586 "5y": "1month", 10587 max: "1month" 10588 }; 10589 this.displayInterval = s[this.timeframe] || "1day"; 10590 } 10591 setIntervalForCustomPeriod(s, t) { 10592 (t.getTime() - s.getTime()) / 864e5 / 365 >= 5 ? this.displayInterval = "1month" : this.displayInterval = "1week"; 10593 } 10594 destroyChart() { 10595 if (this.priceChart && this.crosshairHandler) 10596 try { 10597 this.priceChart.unsubscribeCrosshairMove(this.crosshairHandler); 10598 } catch (s) { 10599 } 10600 this.crosshairHandler = null, this.chartDispose && this.chartDispose(), this.chartDispose = null, this.priceChart = null, this.fundSeries = null, this.benchmarkSeries = null, this.fundDataByTime = /* @__PURE__ */ new Map(), this.benchmarkByTime = /* @__PURE__ */ new Map(), this.hideTooltip(); 10601 } 10602 hideTooltip() { 10603 var t; 10604 const s = (t = this.shadowRoot) == null ? void 0 : t.querySelector(".chart-tooltip"); 10605 s && (s.dataset.visible = "false"); 10606 } 10607 filterDataByTimeframe() { 10608 return L(this, null, function* () { 10609 if (!this.fullFundData.length) 10610 return; 10611 this.setIntervalByTimeframe(); 10612 const { filteredData: s, error: t } = mt.filterDataByTimeframe( 10613 this.fullFundData, 10614 this.timeframe 10615 ); 10616 if (t) { 10617 this.error = t; 10618 return; 10619 } 10620 if (this.fundData = s, this.filteredFundData = s, this.fundData.length > 0) { 10621 const e = this.fundData[this.fundData.length - 1]; 10622 this.currentNav = e.nav, this.currentAum = e.aum || null; 10623 const i = ht.calculateChange( 10624 this.fundData, 10625 (r) => r.nav 10626 ); 10627 i ? (this.navChange = i.absoluteChange, this.navChangePercent = i.percentageChange) : (this.navChange = null, this.navChangePercent = null); 10628 } 10629 this.error = null, this.createChart(), this.benchmark && (this.lastFetchedBenchmarkSymbol !== this.benchmark && (yield this.fetchBenchmarkQuote()), this.fetchBenchmarkData()); 10630 }); 10631 } 10632 /** 10633 * Fetches benchmark quote data (name) from /asset-data/quote 10634 */ 10635 fetchBenchmarkQuote() { 10636 return L(this, null, function* () { 10637 if (!this.benchmark) { 10638 this.benchmarkName = null; 10639 return; 10640 } 10641 if (!(this.benchmarkQuoteFetchInProgress || this.lastFetchedBenc
10641hmarkSymbol === this.benchmark)) { 10642 this.benchmarkQuoteFetchInProgress = true, this.lastFetchedBenchmarkSymbol = this.benchmark; 10643 try { 10644 const s = q.API_BASE_URL, t = encodeURIComponent(this.benchmark), e = yield R(`${s}/asset-data/quote?symbol=${t}`); 10645 if (!e.ok) { 10646 this.benchmarkName = null; 10647 return; 10648 } 10649 const i = yield e.json(); 10650 this.benchmarkName = (i == null ? void 0 : i.name) || null, this.benchmarkName && this.fundData.length > 0 && this.createChart(); 10651 } catch (s) { 10652 this.benchmarkName = null; 10653 } finally { 10654 this.benchmarkQuoteFetchInProgress = false; 10655 } 10656 } 10657 }); 10658 } 10659 /** 10660 * Fetches benchmark historical data from API 10661 * Based on BENCHMARK_COMPARISON_GUIDE.md 10662 */ 10663 fetchBenchmarkData() { 10664 return L(this, null, function* () { 10665 if (!(!this.benchmark || this.benchmarkFetchInProgress) && this.fundData.length !== 0) { 10666 this.benchmarkLoading = true, this.benchmarkError = null, this.benchmarkFetchInProgress = true; 10667 try { 10668 const s = this.fundData[0].date, t = this.fundData[this.fundData.length - 1].date, e = q.API_BASE_URL, i = encodeURIComponent(this.benchmark), r = yield R( 10669 `${e}/asset-data/basic-stock-chart?symbol=${i}&from_date=${s}&to_date=${t}` 10670 ); 10671 if (!r.ok) 10672 throw new Error(u(A`Error ${r.status}: ${r.statusText}`, { 10673 desc: "Error message when benchmark API request fails" 10674 })); 10675 const a = (yield r.json()).sort( 10676 (o, l) => new Date(o.date).getTime() - new Date(l.date).getTime() 10677 ); 10678 this.benchmarkData = a, this.benchmarkError = null; 10679 } catch (s) { 10680 this.benchmarkError = s instanceof Error ? s.message : String(s), console.error("Error al cargar datos del benchmark:", s), this.benchmarkData = []; 10681 } finally { 10682 this.benchmarkLoading = false, this.benchmarkFetchInProgress = false, this.createChart(); 10683 } 10684 } 10685 }); 10686 } 10687 createChart() { 10688 var S; 10689 if (!this.fundData.length) 10690 return; 10691 const s = (S = this.shadowRoot) == null ? void 0 : S.querySelector("#fund-chart-container"); 10692 if (!s) { 10693 queueMicrotask(() => this.createChart()); 10694 return; 10695 } 10696 this.destroyChart(), this.fundData.sort((w, _) => new Date(w.date).getTime() - new Date(_.date).getTime()); 10697 const t = this.fundData.map((w) => w.nav), e = this.benchmark && this.benchmarkData.length > 0 && !this.benchmarkError && !this.benchmarkLoading; 10698 let i = t, r = [], n = false; 10699 if (e) { 10700 const w = this.fundData.map((E) => E.date); 10701 this.alignedBenchmarkPrices = Uh(w, this.benchmarkData); 10702 const _ = this.alignedBenchmarkPrices, D = t[0], z = _[0]; 10703 Number.isFinite(D) && D !== 0 && Number.isFinite(z) && z !== 0 ? (i = t.map( 10704 (E) => Number.isFinite(E) ? E / D * 100 : 100 10705 ), r = _.map( 10706 (E) => Number.isFinite(E) ? E / z * 100 : 100 10707 ), n = true) : (i = t.slice(), r = _.slice()); 10708 } 10709 const a = i[0], l = i[i.length - 1] >= a, h = l ? "#00856F" : "#E91101", c = l ? "rgba(0, 133, 111, 0.15)" : "rgba(233, 17, 1, 0.15)", d = l ? "rgba(0, 133, 111, 0)" : "rgba(233, 17, 1, 0)", f = this.locale || "en-US", m = n ? 1 : Nh([...i, ...r]), p = Bh(f, m), { chart: v, dispose: b } = qh(s, f, { 10710 rightPriceScale: { 10711 scaleMargins: { top: 0.1, bottom: 0.05 } 10712 }, 10713 timeScale: { 10714 timeVisible: false, 10715 secondsVisible: false 10716 } 10717 }); 10718 this.priceChart = v, this.chartDispose = b; 10719 const y = this.fundData.map((w, _) => ({ 10720 time: ni(w.date), 10721 value: i[_] 10722 })); 10723 if (e) { 10724 const w = v.addSeries(dn, { 10725 color: h, 10726 lineWidth: 2, 10727 priceLineVisible: false, 10728 lastValueVisible: false, 10729 priceFormat: p 10730 }); 10731 w.setData(y), this.fundSeries = w; 10732 const _ = v.addSeries(dn, { 10733 color: "#5A6773", 10734 lineWidth: 2, 10735 lineStyle: Re.Dashed, 10736 priceLineVisible: false,
10737 lastValueVisible: false, 10738 priceFormat: p 10739 }), D = this.fundData.map((z, P) => ({ 10740 time: ni(z.date), 10741 value: r[P] 10742 })); 10743 _.setData(D), this.benchmarkSeries = _; 10744 } else { 10745 const w = v.addSeries(ph, { 10746 lineColor: h, 10747 topColor: c, 10748 bottomColor: d, 10749 lineWidth: 2, 10750 priceLineVisible: false, 10751 lastValueVisible: false, 10752 priceFormat: p 10753 }); 10754 w.setData(y), this.fundSeries = w; 10755 } 10756 this.fundDataByTime = /* @__PURE__ */ new Map(), this.fundData.forEach((w) => { 10757 this.fundDataByTime.set(ni(w.date), w); 10758 }), e && (this.benchmarkByTime = /* @__PURE__ */ new Map(), this.fundData.forEach((w, _) => { 10759 const D = ni(w.date); 10760 this.benchmarkByTime.set(D, this.alignedBenchmarkPrices[_]); 10761 })); 10762 const x = (w) => this.renderCrosshairTooltip(w, n); 10763 this.crosshairHandler = x, v.subscribeCrosshairMove(x), v.timeScale().fitContent(), v.timeScale().applyOptions({ fixLeftEdge: true, fixRightEdge: true }); 10764 } 10765 /** 10766 * Renders the floating tooltip on top of the chart canvas in response to 10767 * crosshair movement. Mirrors the multi-line title/label/afterLabel 10768 * structure of the previous Chart.js tooltip so consumers see the same 10769 * fields (date, fund label, optional benchmark, AUM, change). 10770 */ 10771 renderCrosshairTooltip(s, t) { 10772 var _, D, z, P; 10773 const e = (_ = this.shadowRoot) == null ? void 0 : _.querySelector(".chart-tooltip"), i = (D = this.shadowRoot) == null ? void 0 : D.querySelector("#fund-chart-container"); 10774 if (!e || !i) 10775 return; 10776 if (!s.time || !s.point || s.point.x < 0 || s.point.y < 0 || s.point.x > i.clientWidth || s.point.y > i.clientHeight) { 10777 e.dataset.visible = "false"; 10778 return; 10779 } 10780 const r = s.time, n = this.fundDataByTime.get(r); 10781 if (!n) { 10782 e.dataset.visible = "false"; 10783 return; 10784 } 10785 const a = this.locale || "en-US", o = this.fundInfo, l = this.benchmarkName || this.benchmark, h = !!this.benchmark && this.benchmarkSeries !== null && this.benchmarkByTime.size > 0, c = new Date(r * 1e3); 10786 let d = a; 10787 (d === "en-US" || d.startsWith("en-")) && (d = "en-GB"); 10788 const f = new Intl.DateTimeFormat(d, { 10789 day: "2-digit", 10790 month: "2-digit", 10791 year: "numeric", 10792 timeZone: "UTC" 10793 }).format(c), m = []; 10794 m.push(`<div class="chart-tooltip-title">${this.escape(f)}</div>`); 10795 const p = h ? (o == null ? void 0 : o.name) || u("Fondo", { desc: "Fund label in tooltip", id: "fund-price-chart.tooltip.fund" }) : (o == null ? void 0 : o.name) || u("Valor liquidativo", { desc: "Net asset value label in tooltip" }); 10796 if (h && t) { 10797 const E = this.fundSeries ? (z = s.seriesData.get(this.fundSeries)) == null ? void 0 : z.value : void 0, H = (E != null ? E : 100) - 100, J = H >= 0 ? "+" : ""; 10798 m.push(`<div class="chart-tooltip-row">${this.escape(p)}: ${F.formatDecimal(n.nav, a, 2)} (${J}${F.formatDecimal(H, a, 2)}%)</div>`); 10799 const j = this.benchmarkByTime.get(r), Q = this.benchmarkSeries ? (P = s.seriesData.get(this.benchmarkSeries)) == null ? void 0 : P.value : void 0; 10800 if (j !== void 0 && Number.isFinite(j)) { 10801 const N = (Q != null ? Q : 100) - 100, W = N >= 0 ? "+" : ""; 10802 m.push(`<div class="chart-tooltip-row">${this.escape(l)}: ${F.formatDecimal(j, a, 2)} (${W}${F.formatDecimal(N, a, 2)}%)</div>`); 10803 } 10804 } else 10805 m.push(`<div class="chart-tooltip-row">${this.escape(p)}: ${F.formatDecimal(n.nav, a, 2)}</div>`); 10806 if (!h) { 10807 if (n.aum !== void 0) { 10808 const E = u("Patrimonio", { desc: "AUM label" }); 10809 m.push(`<div class="chart-tooltip-row">${this.escape(E)}: ${this.escape(F.formatNumber(n.aum, a))}</div>`); 10810 } 10811 if (n.change !== void 0 && n.changePercent !== void 0) { 10812 const E = u("Cambio", { desc: "Change label in tooltip" }), H = n.change > 0 ? "+" : ""; 10813 m.push(`<div class="chart-tooltip-row">${this.escape(E)}: ${H}${F.formatDecimal(n.change, a, 2)} (${F.formatDecimal(n.changePercent, a, 2)}%)</div>`); 10814 } 10815 } 10816 e.innerHTML = m.join(""), e.dataset.visible = "true"; 10817 const v = e.offsetWidth || 180, b = e.offsetHeight || 60, y = i.clientWidth, x = i.clientHeight; 10818 let S = s.point.x + 16; 10819 S + v > y && (S = s.point.x - v - 16), S < 0 && (S = 0); 10820 let w = s.point.y + 16; 10821 w + b > x && (w = s.point.y - b - 16), w < 0 && (w = 0), e.style.left = `${S}px`, e.style.top = `${w}px`; 10822 } 10823 escape(s) { 10824 return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); 10825 } 10826 fetchData() { 10827 return L(this, null, function* () { 10828 if (!(!this.isin || this.fetchInProgress)) { 10829 this.fetchInProgress = true, this.loading = true, this.error = null; 10830 try { 10831 const s = yield this.fundDataService.fetchFundData({ 10832 isin: this.isin, 10833 timeframe: this.timeframe, 10834 showHeader: this.showHeader 10835 }); 10836 if (this.fullFundData = s.fundData, s.fundInfo && (this.fundInfo = s.fundInfo), this.fullFundData.length > 0) { 10837 const t = this.fullFundData[this.fullFundData.length - 1], e = new Date(t.date); 10838 let i = this.locale || "en-GB"; 10839 (i === "en-US" || i.startsWith("en-")) && (i = "en-GB"), this.lastUpdatedDate = e.toLocaleDateString(i, { 10840 day: "2-digit", 10841 month: "2-digit", 10842 year: "2-digit", 10843 timeZoneName: "short" 10844 }); 10845 } 10846 this.processData({ 10847 isin: this.isin, 10848 fundData: this.fullFundData, 10849 symbol: this.isin 10850 // Usar ISIN como symbol para compatibilidad 10851 }), setTimeout(() => { 10852 this.filterDataByTimeframe(), this.benchmark && setTimeout(() => { 10853 this.fetchBenchmarkData(); 10854 }, 100); 10855 }, 0); 10856 } catch (s) { 10857 this.error = u("No se pudo cargar el hist\xF3rico. Por favor, reint\xE9ntalo m\xE1s tarde.", { 10858 desc: "Error after intraday + daily fallback both failed" 10859 }), console.error("Error al cargar datos del fondo:", s); 10860 } finally { 10861 this.loading = false, this.fetchInProgress = false;
10862 } 10863 } 10864 }); 10865 } 10866 handleTimeframeChange(s) { 10867 this.timeframe === s || this.isInitializing || this.fetchInProgress || (this.timeframe = s, this.isCustomPeriod = false, this.setIntervalByTimeframe(), this.fullFundData.length > 0 ? this.filterDataByTimeframe() : setTimeout(() => { 10868 this.fetchData(); 10869 }, 0)); 10870 } 10871 openCustomPeriodModal() { 10872 const s = /* @__PURE__ */ new Date(), t = /* @__PURE__ */ new Date(); 10873 t.setFullYear(t.getFullYear() - 1), this.customStartDate = t.toISOString().split("T")[0], this.customEndDate = s.toISOString().split("T")[0], this.showCustomPeriodModal = true; 10874 } 10875 closeCustomPeriodModal() { 10876 this.showCustomPeriodModal = false; 10877 } 10878 applyCustomPeriod() { 10879 if (!this.customStartDate || !this.customEndDate) 10880 return; 10881 const s = new Date(this.customStartDate), t = new Date(this.customEndDate); 10882 s >= t || (this.isCustomPeriod = true, this.timeframe = "custom", this.setIntervalForCustomPeriod(s, t), this.closeCustomPeriodModal(), this.filterDataByCustomPeriod(s, t)); 10883 } 10884 filterDataByCustomPeriod(s, t) { 10885 if (!this.fullFundData.length) 10886 return; 10887 const e = this.fullFundData.filter((i) => { 10888 const r = new Date(i.date); 10889 return r >= s && r <= t; 10890 }); 10891 if (e.length === 0) { 10892 this.error = "No hay datos disponibles para el per\xEDodo seleccionado"; 10893 return; 10894 } 10895 if (this.fundData = e, this.filteredFundData = e, this.fundData.length > 0) { 10896 const i = this.fundData[this.fundData.length - 1]; 10897 this.currentNav = i.nav, this.currentAum = i.aum || null; 10898 const r = ht.calculateChange( 10899 this.fundData, 10900 (n) => n.nav 10901 ); 10902 r ? (this.navChange = r.absoluteChange, this.navChangePercent = r.percentageChange) : (this.navChange = null, this.navChangePercent = null); 10903 } 10904 this.error = null, this.createChart(); 10905 } 10906 processData(s) { 10907 this.ratioData = s; 10908 } 10909 /** 10910 * Implementación del método abstracto getNoDataMessage 10911 * Nota: Este método no se usa directamente ya que usamos renderNoDataBlock() 10912 */ 10913 getNoDataMessage() { 10914 return u("No hay datos de fondo disponibles. Por favor, proporcione un ISIN v\xE1lido.", { 10915 desc: "Message shown when no fund data is available" 10916 }); 10917 } 10918 getPeriodText(s) { 10919 if (this.isCustomPeriod) 10920 return u("per\xEDodo seleccionado", { desc: "Selected period text" }); 10921 switch (s) { 10922 case "ytd": 10923 return u("a\xF1o en curso", { desc: "Year to date period text" }); 10924 case "1m": 10925 return u("\xFAltimo mes", { desc: "Last month period text" }); 10926 case "3m": 10927 return u("\xFAltimos 3 meses", { desc: "Last 3 months period text" }); 10928 case "6m": 10929 return u("\xFAltimos 6 meses", { desc: "Last 6 months period text" }); 10930 case "1y": 10931 return u("\xFAltimo a\xF1o", { desc: "Last year period text" }); 10932 case "5y": 10933 return u("\xFAltimos 5 a\xF1os", { desc: "Last 5 years period text" }); 10934 case "max": 10935 return u("m\xE1ximo hist\xF3rico", { desc: "Maximum historical period text" }); 10936 default: 10937 return u("per\xEDodo seleccionado", { desc: "Selected period text" }); 10938 } 10939 } 10940 hasEnoughDataForTimeframe(s) { 10941 if (!this.fullFundData.length) 10942 return false; 10943 if (s === "5y") { 10944 const t = /* @__PURE__ */ new Date(), e = new Date(Math.min( 10945 t.getTime(), 10946 Math.max(...this.fullFundData.map((n) => new Date(n.date).getTime())) 10947 )), i = new Date(e); 10948 return i.setFullYear(e.getFullYear() - 5), new Date(Math.min(...this.fullFundData.map((n) => new Date(n.date).getTime()))) <= i; 10949 } 10950 return true; 10951 } 10952 formatDateForDisplay(s) { 10953 if (!s) 10954 return ""; 10955 const t = new Date(s); 10956 let e = this.locale || "en-GB"; 10957 return (e === "en-US" || e.startsWith("en-")) && (e = "en-GB"), t.toLocaleDateString(e, { 10958 day: "2-digit", 10959 month: "2-digit", 10960 year: "numeric" 10961 }); 10962 } 10963 renderContent() { 10964 var i, r, n, a; 10965 if (this.loading) 10966 return g`<div class="loading">${u("Cargando datos del fondo...", {
10967 desc: "Loading message when fetching fund data" 10968 })}</div>`; 10969 if (this.error) 10970 return g`<div class="error">${this.error}</div>`; 10971 if (this.fullFundData.length === 0) 10972 return Ye(); 10973 const t = [ 10974 { value: "ytd", label: u("YTD", { desc: "Year to date timeframe abbreviation" }) }, 10975 { value: "1m", label: u("1M", { desc: "One month timeframe abbreviation" }) }, 10976 { value: "3m", label: u("3M", { desc: "Three months timeframe abbreviation" }) }, 10977 { value: "6m", label: u("6M", { desc: "Six months timeframe abbreviation" }) }, 10978 { value: "1y", label: u("1A", { desc: "One year timeframe abbreviation" }) }, 10979 { value: "5y", label: u("5A", { desc: "Five years timeframe abbreviation" }) }, 10980 { value: "max", label: u("M\xC1X", { desc: "Maximum timeframe abbreviation" }) } 10981 ].filter((o) => this.hasEnoughDataForTimeframe(o.value)); 10982 if (t.length > 0 && !this.hasEnoughDataForTimeframe(this.timeframe)) { 10983 const l = t.find((h) => h.value === "max") || t[t.length - 1]; 10984 this.timeframe = l.value; 10985 } 10986 const e = this.benchmark && this.benchmarkData.length > 0 && !this.benchmarkError && !this.benchmarkLoading; 10987 return g` 10988 <div> 10989 ${this.showHeader && this.fundInfo ? g` 10990 <div class="info-header"> 10991 <div> 10992 ${Dt(this.headerLevel, "stock-name", this.fundInfo.name)} 10993 <p class="stock-symbol">${this.isin}</p> 10994 ${this.fundInfo.category ? g` 10995 <p class="stock-description">${this.fundInfo.category}</p> 10996 ` : ""} 10997 </div> 10998 </div> 10999 ` : ""} 11000 11001 <div class="chart-header"> 11002 <div class="price-info"> 11003 ${this.currentNav !== null ? g` 11004 <div class="current-price-container"> 11005 <span class="current-price">${F.formatDecimal(this.currentNav, this.locale || "en-US", 2)}</span> <span class="current-price-currency">${(i = this.fundInfo) == null ? void 0 : i.currency}</span> 11006 </div> 11007 ${this.navChange !== null && this.navChangePercent !== null ? g` 11008 <span class="price-change ${this.navChange >= 0 ? "positive" : "negative"}"> 11009 <span class="price-change-percent"> 11010 <svg width="13" height="14" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 11011 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 11012 </svg> 11013 ${this.navChange >= 0 ? "+" : ""}${F.formatDecimal(this.navChangePercent, this.locale || "en-US", 2)}% 11014 </span> 11015 <span class="price-change-number">${this.navChange >= 0 ? "+" : ""}${F.formatDecimal(this.navChange, this.locale || "en-US", 2)} ${F.getCurrencySymbol(((r = this.fundInfo) == null ? void 0 : r.currency) || "", this.locale)} ${this.getPeriodText(this.timeframe)}</span> 11016 </span> 11017 ` : ""} 11018 ` : ""} 11019 11020 ${this.currentAum !== null ? g` 11021 <div class="liquidity-info"> 11022 <div class="liquidity-label">${u("Patrimonio", { desc: "AUM label" })}</div> 11023 <div class="liquidity-value">${F.formatNumber(this.currentAum, this.locale)} ${F.getCurrencySymbol(((n = this.fundInfo) == null ? void 0 : n.currency) || "", this.locale)}</div> 11024 </div> 11025 ` : ""} 11026 </div> 11027 </div> 11028 11029 <div class="chart-body"> 11030 <div class="timeframe-selector horizontal-scroll-element"> 11031 <div class="horizontal-scroll-element-inner"> 11032 ${t.map((o) => g` 11033 <button 11034 class="tab-button ${this.timeframe === o.value && !this.isCustomPeriod ? "active" : ""}" 11035 @click=${() => this.handleTimeframeChange(o.value)} 11036 > 11037 ${o.label} 11038 </button> 11039 `)} 11040 <button 11041 class="tab-button custom-period-button ${this.isCu
11041stomPeriod ? "active" : ""}" 11042 @click=${() => this.openCustomPeriodModal()} 11043 > 11044 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 11045 <path d="M8 2V5M16 2V5M3.5 9.09H20.5M21 8.5V17C21 20 19.5 22 16 22H8C4.5 22 3 20 3 17V8.5C3 5.5 4.5 3.5 8 3.5H16C19.5 3.5 21 5.5 21 8.5Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> 11046 <path d="M15.6947 13.7H15.7037M15.6947 16.7H15.7037M11.9955 13.7H12.0045M11.9955 16.7H12.0045M8.29431 13.7H8.30329M8.29431 16.7H8.30329" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 11047 </svg> 11048 ${u("Editar per\xEDodo", { desc: "Edit period button text" })} 11049 </button> 11050 </div> 11051 </div> 11052 11053 ${this.isCustomPeriod ? g` 11054 <div class="custom-period-info"> 11055 <span class="period-label">${u("Per\xEDodo seleccionado", { desc: "Selected period label" })}:</span> 11056 <span class="period-dates">${this.formatDateForDisplay(this.customStartDate)} - ${this.formatDateForDisplay(this.customEndDate)}</span> 11057 </div> 11058 ` : ""} 11059 11060 ${e ? g` 11061 <div class="chart-legend"> 11062 <div class="legend-item"> 11063 <div class="legend-line legend-line-fund"></div> 11064 <span>${((a = this.fundInfo) == null ? void 0 : a.name) || u("Fondo", { desc: "Fund label in legend", id: "fund-price-chart.legend.fund" })}</span> 11065 </div> 11066 <div class="legend-item"> 11067 <div class="legend-line legend-line-benchmark"></div> 11068 <span>${this.benchmarkName || this.benchmark} ${u("(Benchmark)", { desc: "Benchmark label in legend" })}</span> 11069 </div> 11070 </div> 11071 ` : ""} 11072 11073 <div class="chart-container"> 11074 <div id="fund-chart-container" class="chart-canvas"></div> 11075 <div class="chart-tooltip" data-visible="false"></div> 11076 </div> 11077 </div> 11078 11079 ${this.lastUpdatedDate ? g` 11080 <div class="actualization-info"> 11081 <svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg"> 11082 <path d="M10.5 15.4172C10.7833 15.4172 11.021 15.3212 11.213 15.1292C11.405 14.9372 11.5007 14.6999 11.5 14.4172V10.4172C11.5 10.1339 11.404 9.89657 11.212 9.70524C11.02 9.5139 10.7827 9.4179 10.5 9.41724C10.2173 9.41657 9.98 9.51257 9.788 9.70524C9.596 9.8979 9.5 10.1352 9.5 10.4172V14.4172C9.5 14.7006 9.596 14.9382 9.788 15.1302C9.98 15.3222 10.2173 15.4179 10.5 15.4172ZM10.5 7.41724C10.7833 7.41724 11.021 7.32124 11.213 7.12924C11.405 6.93724 11.5007 6.6999 11.5 6.41724C11.4993 6.13457 11.4033 5.89724 11.212 5.70524C11.0207 5.51324 10.7833 5.41724 10.5 5.41724C10.2167 5.41724 9.97933 5.51324 9.788 5.70524C9.59667 5.89724 9.50067 6.13457 9.5 6.41724C9.49933 6.6999 9.59533 6.93757 9.788 7.13024C9.98067 7.3229 10.218 7.41857 10.5 7.41724ZM10.5 20.4172C9.11667 20.4172 7.81667 20.1546 6.6 19.6292C5.38334 19.1039 4.325 18.3916 3.425 17.4922C2.525 16.5929 1.81267 15.5346 1.288 14.3172C0.763335 13.0999 0.500668 11.7999 0.500001 10.4172C0.499335 9.03457 0.762001 7.73457 1.288 6.51724C1.814 5.2999 2.52633 4.24157 3.425 3.34224C4.32367 2.4429 5.382 1.73057 6.6 1.20524C7.818 0.679903 9.118 0.417236 10.5 0.417236C11.882 0.417236 13.182 0.679903 14.4 1.20524C15.618 1.73057 16.6763 2.4429 17.575 3.34224C18.4737 4.24157 19.1863 5.2999 19.713 6.51724C20.2397 7.73457 20.502 9.03457 20.5 10.4172C20.498 11.7999 20.2353 13.0999 19.712 14.3172C19.1887 15.5346 18.4763 16.5929 17.575 17.4922C16.6737 18.3916 15.6153 19.1042 14.4 19.6302C13.1847 20.1562 11.8847 20.4186 10.5 20.4172ZM10.5 18.4172C12.7333 18.4172 14.625 17.6422 16.175 16.0922C17.725 14.5422 18.5 12.6506 18.5 10.4172C18.5 8.1839 17.725 6.29224 16.175 4.74224C14.625 3.19224 12.7333 2.41724 10.5 2.41724C8.26667 2.41724 6.375 3.19224 4.825 4.74224C3.275 6.29224 2.5 8.1839 2.5 10.4172C2.5 12.6506 3.275 14.5422 4.825 16.0922C6.375 17.6422 8.26667 18.4172 10.5 18.4172Z" fill="#58A8DA"/> 11083 </svg>
11084 <span class="actualization-text">${u("Datos actualizados a", { desc: "Data updated to text" })}</span> 11085 <span class="actualization-date">${this.lastUpdatedDate}</span> 11086 </div> 11087 ` : ""} 11088 11089 11090 ${this.showCustomPeriodModal ? g` 11091 <div class="modal-overlay" @click=${(o) => { 11092 o.target === o.currentTarget && this.closeCustomPeriodModal(); 11093 }}> 11094 <div class="modal-content"> 11095 <div class="modal-header"> 11096 <h3 class="modal-title">${u("Seleccionar per\xEDodo", { desc: "Select period modal title" })}</h3> 11097 <button class="modal-close" @click=${() => this.closeCustomPeriodModal()}>Ã</button> 11098 </div> 11099 11100 <div class="date-input-group"> 11101 <label class="date-label">${u("Fecha de inicio", { desc: "Start date label" })}</label> 11102 <input 11103 type="date" 11104 class="date-input" 11105 .value=${this.customStartDate} 11106 @input=${(o) => { 11107 this.customStartDate = o.target.value; 11108 }} 11109 /> 11110 </div> 11111 11112 <div class="date-input-group"> 11113 <label class="date-label">${u("Fecha de fin", { desc: "End date label" })}</label> 11114 <input 11115 type="date" 11116 class="date-input" 11117 .value=${this.customEndDate} 11118 @input=${(o) => { 11119 this.customEndDate = o.target.value; 11120 }} 11121 /> 11122 </div> 11123 11124 <div class="selected-period-display"> 11125 ${u("Per\xEDodo seleccionado", { desc: "Selected period label" })}: ${this.formatDateForDisplay(this.customStartDate)} - ${this.formatDateForDisplay(this.customEndDate)} 11126 </div> 11127 11128 <div class="modal-actions"> 11129 <button class="modal-button modal-button-cancel" @click=${() => this.closeCustomPeriodModal()}> 11130 ${u("Cancelar", { desc: "Cancel button text" })} 11131 </button> 11132 <button class="modal-button modal-button-apply" @click=${() => this.applyCustomPeriod()}> 11133 ${u("Aplicar", { desc: "Apply button text" })} 11134 </button> 11135 </div> 11136 </div> 11137 </div> 11138 ` : ""} 11139 </div> 11140 `; 11141 } 11142 }; 11143 O.styles = K` 11144 ${nt(Qe)} 11145 ${We} 11146 ${_i} 11147 11148 :host { 11149 display: block; 11150 width: 100%; 11151 font-family: var(--stock-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 11152 box-sizing: border-box; 11153 --button-text-color: var(--stock-text-color, #383d43); 11154 --button-active-color: var(--stock-white-color, #FFFFFF); 11155 --button-bg: var(--stock-light-gray-bg, #f0f0f0); 11156 --button-bg-active: var(--stock-primary-color, #1A5275); 11157 --button-bg-hover: var(--stock-info-color, rgba(88, 168, 218, 0.15)); 11158 --button-font-size-basis: var(--stock-font-size-basis, 18px); 11159 --button-font-size-basis-mobile: var(--stock-font-size-small-mobile, 14px); 11160 --button-padding: var(--stock-button-padding, 8px 16px); 11161 --button-border-radius: var(--stock-button-border-radius, 4px); 11162 --chart-buttons-gap: var(--stock-gap, 16px); 11163 --chart-positive-color: var(--stock-success-color, #00856F); 11164 --chart-positive-bg: var(--stock-success-bg, rgba(0, 133, 111, 0.15)); 11165 --chart-negative-color: var(--stock-danger-color, #E91101); 11166 --chart-negative-bg: var(--stock-danger-bg, rgba(233, 17, 1, 0.15)); 11167 } 11168 11169 :host *, :host *::before, :host *::after { 11170 box-sizing: border-box; 11171 } 11172 11173 .chart-container { 11174 grid-area: chart; 11175 position: relative; 11176 height: 388px; 11177 width: 100%; 11178 } 11179 11180 .chart-canvas { 11181 position: absolute; 11182 inset: 0; 11183 width: 100%; 11184 height: 100%; 11185 } 11186 11187 .chart-tooltip { 11188 position: absolute; 11189 pointer-events: none; 11190 background: #ffffff; 11191 color: #383d43; 11192 border: 1px solid #e0e0e0; 11193 border-radius: 4px; 11194 padding: 8px 10px; 11195 font-size: 12px; 11196 line-height: 1.4; 11197 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 11198 z-index: 2; 11199 white-space: nowrap; 11200 display: none; 11201 } 11202
11203 .chart-tooltip[data-visible="true"] { 11204 display: block; 11205 } 11206 11207 .chart-tooltip-title { 11208 font-weight: 600; 11209 margin-bottom: 4px; 11210 } 11211 11212 .chart-tooltip-row { 11213 display: block; 11214 } 11215 11216 .chart-header { 11217 display: flex; 11218 justify-content: space-between; 11219 align-items: center; 11220 margin-bottom: 20px; 11221 flex-wrap: wrap; 11222 gap: 15px; 11223 } 11224 11225 .price-info { 11226 display: flex; 11227 flex-direction: column; 11228 gap: 4px; 11229 } 11230 11231 .current-price { 11232 font-size: 29px; 11233 font-weight: 500; 11234 line-height: 1.29; 11235 color: var(--stock-text-color, #383d43); 11236 } 11237 11238 .current-price-currency { 11239 color: var(--stock-text-color, #383d43); 11240 font-size: 23px; 11241 font-weight: 500; 11242 line-height: 36px; 11243 } 11244 11245 .price-change { 11246 display: flex; 11247 align-items: center; 11248 gap: 8px; 11249 font-weight: 500; 11250 } 11251 11252 .price-change.positive { 11253 color: var(--chart-positive-color); 11254 } 11255 11256 .price-change.negative { 11257 color: var(--chart-negative-color); 11258 } 11259 11260 .price-change-percent { 11261 display: inline-flex; 11262 align-items: center; 11263 gap: 4px; 11264 padding: 8px 12px; 11265 border-radius: 4px; 11266 } 11267 11268 .positive > .price-change-percent { 11269 background-color: var(--chart-positive-bg); 11270 } 11271 11272 .negative > .price-change-percent { 11273 background-color: var(--chart-negative-bg); 11274 } 11275 11276 .negative > .price-change-percent > svg { 11277 transform: rotate(180deg); 11278 } 11279 11280 .liquidity-info { 11281 display: flex; 11282 flex-direction: column; 11283 gap: 4px; 11284 margin-top: 8px; 11285 } 11286 11287 .liquidity-label { 11288 font-size: 0.9rem; 11289 color: var(--stock-muted-color, #64748b); 11290 font-weight: 500; 11291 } 11292 11293 .liquidity-value { 11294 font-size: 1.1rem; 11295 font-weight: 600; 11296 color: var(--stock-text-color, #383d43); 11297 } 11298 11299 .chart-body { 11300 display: flex; 11301 flex-direction: column; 11302 gap: 16px; 11303 } 11304 11305 .timeframe-selector { 11306 grid-area: timeframe; 11307 } 11308 11309 .selector-title { 11310 font-size: 0.9rem; 11311 font-weight: 600; 11312 color: var(--stock-muted-color, #64748b); 11313 margin-right: 8px; 11314 } 11315 11316 .fund-notice { 11317 background-color: var(--stock-notice-bg, #fff3cd); 11318 color: var(--stock-notice-color, #856404); 11319 padding: 10px 15px; 11320 border-radius: 4px; 11321 margin-bottom: 15px; 11322 font-size: 0.9rem; 11323 display: flex; 11324 align-items: center; 11325 justify-content: center; 11326 text-align: center; 11327 } 11328 11329 .custom-period-button { 11330 display: flex; 11331 align-items: center; 11332 gap: 6px; 11333 } 11334 11335 11336 .modal-overlay { 11337 position: fixed; 11338 top: 0; 11339 left: 0; 11340 right: 0; 11341 bottom: 0; 11342 background-color: rgba(0, 0, 0, 0.5); 11343 display: flex; 11344 align-items: center; 11345 justify-content: center; 11346 z-index: 9000; 11347 } 11348 11349 .modal-content { 11350 background-color: var(--stock-background-color, #ffffff); 11351 border-radius: 8px; 11352 padding: 24px; 11353 width: 90%; 11354 max-width: 400px; 11355 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); 11356 position: relative; 11357 } 11358 11359 .modal-header { 11360 display: flex; 11361 justify-content: space-between; 11362 align-items: center; 11363 margin-bottom: 20px; 11364 } 11365 11366 .modal-title { 11367 font-size: 1.2rem; 11368 font-weight: 600; 11369 color: var(--stock-text-color, #383d43); 11370 margin: 0; 11371 } 11372 11373 .modal-close { 11374 background: none; 11375 border: none; 11376 font-size: 1.5rem; 11377 cursor: pointer; 11378 color: var(--stock-muted-color, #64748b); 11379 padding: 0; 11380 width: 24px; 11381 height: 24px; 11382 display: flex; 11383 align-items: center; 11384 justify-content: center; 11385 } 11386
11387 .modal-close:hover { 11388 color: var(--stock-text-color, #383d43); 11389 } 11390 11391 .date-input-group { 11392 margin-bottom: 16px; 11393 } 11394 11395 .date-label { 11396 display: block; 11397 font-size: 0.9rem; 11398 font-weight: 500; 11399 color: var(--stock-text-color, #383d43); 11400 margin-bottom: 6px; 11401 } 11402 11403 .date-input { 11404 /* Reset all browser default styles */ 11405 -webkit-appearance: none; 11406 -moz-appearance: none; 11407 appearance: none; 11408 11409 /* Standard styles */ 11410 width: 100%; 11411 max-width: 100%; 11412 display: block; 11413 padding: 10px 12px; 11414 border: 1px solid var(--stock-border-color, #e0e0e0); 11415 border-radius: 4px; 11416 font-size: 0.9rem; 11417 color: var(--stock-text-color, #383d43); 11418 background-color: var(--stock-background-color, #ffffff); 11419 } 11420 11421 .date-input:focus { 11422 outline: none; 11423 border-color: var(--button-bg-active); 11424 box-shadow: 0 0 0 2px rgba(26, 82, 117, 0.1); 11425 } 11426 11427 .selected-period-display { 11428 background-color: var(--button-bg-hover); 11429 color: var(--button-bg-active); 11430 padding: 12px; 11431 border-radius: 4px; 11432 margin-bottom: 20px; 11433 font-size: 0.9rem; 11434 font-weight: 500; 11435 } 11436 11437 .modal-actions { 11438 display: flex; 11439 gap: 12px; 11440 justify-content: flex-end; 11441 } 11442 11443 .modal-button { 11444 padding: 10px 20px; 11445 border-radius: 4px; 11446 font-size: 0.9rem; 11447 font-weight: 500; 11448 cursor: pointer; 11449 transition: all 0.2s ease; 11450 border: none; 11451 } 11452 11453 .modal-button-cancel { 11454 background-color: var(--button-bg); 11455 color: var(--button-text-color); 11456 } 11457 11458 .modal-button-cancel:hover { 11459 background-color: var(--button-bg-hover); 11460 } 11461 11462 .modal-button-apply { 11463 background-color: var(--button-bg-active); 11464 color: var(--button-active-color); 11465 } 11466 11467 .modal-button-apply:hover { 11468 background-color: var(--button-bg-active); 11469 opacity: 0.9; 11470 } 11471 11472 @media (min-width: 992px) { 11473 .chart-body { 11474 display: flex; 11475 flex-direction: column; 11476 gap: 24px; 11477 } 11478 11479 .price-info { 11480 flex-direction: row; 11481 align-items: center; 11482 gap: 24px; 11483 } 11484 11485 .current-price { 11486 font-size: 44px; 11487 } 11488 11489 .current-price-currency { 11490 font-size: 28px; 11491 } 11492 } 11493 11494 /* Estilos responsivos para móviles */ 11495 @media (max-width: 768px) { 11496 .chart-header { 11497 flex-direction: column; 11498 align-items: flex-start; 11499 gap: 15px; 11500 margin-bottom: 15px; 11501 } 11502 11503 .price-info { 11504 flex-direction: column; 11505 gap: 8px; 11506 width: 100%; 11507 } 11508 11509 .current-price { 11510 font-size: 24px; 11511 } 11512 11513 .current-price-currency { 11514 font-size: 18px; 11515 } 11516 11517 .liquidity-info { 11518 margin-top: 12px; 11519 } 11520 11521 .timeframe-selector { 11522 margin-top: 5px; 11523 flex-wrap: nowrap; 11524 justify-content: flex-start; 11525 } 11526 11527 .tab-button { 11528 flex-shrink: 0; 11529 text-align: center; 11530 white-space: nowrap; 11531 } 11532 11533 .chart-container { 11534 height: 166px; 11535 width: 100%; 11536 padding: 0; 11537 margin: 0; 11538 } 11539 11540 .selector-title { 11541 font-size: 0.8rem; 11542 margin-right: 5px; 11543 } 11544 11545 .modal-content { 11546 width: 100%; 11547 height: 100%; 11548 max-width: none; 11549 border-radius: 0; 11550 padding: 20px; 11551 display: flex; 11552 flex-direction: column; 11553 } 11554 11555 .modal-header { 11556 margin-bottom: 16px; 11557 } 11558 11559 .modal-title { 11560 font-size: 1.1rem; 11561 } 11562 11563 .date-input-group { 11564 margin-bottom: 12px; 11565 } 11566 11567 .selected-period-display { 11568 margin-bottom: 16px; 11569 padding: 10px; 11570 font-size: 0.85rem; 11571 } 11572 11573 .modal-actions { 11574 margin-top: auto; 11575 gap: 10px; 11576 } 11577 11578 .modal-button { 11579 padding: 12px 16px; 11580 font-size: 0.9rem; 11581 } 11582 11583 .modal-close { 11584 width: 36px; 11585 height: 36px; 11586 font-size: 2rem; 11587 font-weight: 300; 11588 } 11589 } 11590 11591 .actualization-info { 11592 line-height: 23px; 11593 margin-top: 16px; 11594 font-size: 14px; 11595 } 11596 11597 .actualization-info svg { 11598 flex-shrink: 0; 11599 vertical-align: bottom; 11600 } 11601 11602 .actualization-text { 11603 vertical-align: bottom; 11604 } 11605 11606 .actualization-date { 11607 vertical-align: bottom; 11608 } 11609 11610 .custom-period-info { 11611 color: var(--stock-muted-color, #64748b); 11612 padding: 8px 0; 11613 font-size: 14px; 11614 font-weight: 500; 11615 } 11616
11617 .chart-legend { 11618 display: flex; 11619 align-items: center; 11620 justify-content: flex-start; 11621 gap: 24px; 11622 margin-top: 0; 11623 margin-bottom: 16px; 11624 flex-wrap: wrap; 11625 } 11626 11627 .legend-item { 11628 display: flex; 11629 align-items: center; 11630 gap: 8px; 11631 font-size: 14px; 11632 color: var(--stock-text-color, #383d43); 11633 } 11634 11635 .legend-line { 11636 width: 20px; 11637 height: 0; 11638 flex-shrink: 0; 11639 border-top-width: 2px; 11640 border-top-style: solid; 11641 } 11642 11643 .legend-line-fund { 11644 border-top-color: var(--chart-positive-color, #00856F); 11645 } 11646 11647 .legend-line-benchmark { 11648 border-top-color: #5A6773; 11649 border-top-style: dashed; 11650 border-top-width: 2px; 11651 } 11652 11653 @media (max-width: 768px) { 11654 .chart-legend { 11655 gap: 16px; 11656 margin-top: 0; 11657 margin-bottom: 12px; 11658 } 11659 11660 .legend-item { 11661 font-size: 12px; 11662 } 11663 11664 .legend-line { 11665 width: 20px; 11666 } 11667 } 11668 `; 11669 V([ 11670 $({ type: String }) 11671 ], O.prototype, "isin", 2); 11672 V([ 11673 $({ type: String }) 11674 ], O.prototype, "timeframe", 2); 11675 V([ 11676 $({ type: String }) 11677 ], O.prototype, "displayInterval", 2); 11678 V([ 11679 $({ type: String }) 11680 ], O.prototype, "benchmark", 2); 11681 V([ 11682 $({ 11683 type: Boolean, 11684 attribute: "show-header", 11685 converter: { 11686 fromAttribute: (s) => s === "false" || s === false ? false : s === "true" || s === true ? true : s !== null 11687 } 11688 }) 11689 ], O.prototype, "showHeader", 2); 11690 V([ 11691 $({ type: String, attribute: "header-level" }) 11692 ], O.prototype, "headerLevel", 2); 11693 V([ 11694 C() 11695 ], O.prototype, "fundData", 2); 11696 V([ 11697 C() 11698 ], O.prototype, "filteredFundData", 2); 11699 V([ 11700 C() 11701 ], O.prototype, "fundInfo", 2); 11702 V([ 11703 C() 11704 ], O.prototype, "currentNav", 2); 11705 V([ 11706 C() 11707 ], O.prototype, "navChange", 2); 11708 V([ 11709 C() 11710 ], O.prototype, "navChangePercent", 2); 11711 V([ 11712 C() 11713 ], O.prototype, "currentAum", 2); 11714 V([ 11715 C() 11716 ], O.prototype, "showCustomPeriodModal", 2); 11717 V([ 11718 C() 11719 ], O.prototype, "customStartDate", 2); 11720 V([ 11721 C() 11722 ], O.prototype, "customEndDate", 2); 11723 V([ 11724 C() 11725 ], O.prototype, "isCustomPeriod", 2); 11726 V([ 11727 C() 11728 ], O.prototype, "lastUpdatedDate", 2); 11729 V([ 11730 C() 11731 ], O.prototype, "benchmarkData", 2); 11732 V([ 11733 C() 11734 ], O.prototype, "benchmarkLoading", 2); 11735 V([ 11736 C() 11737 ], O.prototype, "benchmarkError", 2); 11738 V([ 11739 C() 11740 ], O.prototype, "benchmarkName", 2); 11741 V([ 11742 C() 11743 ], O.prototype, "isInitializing", 2); 11744 O = V([ 11745 lt(), 11746 it("fund-price-chart") 11747 ], O); 11748 function vn(s) { 11749 return typeof s == "number" && Number.isFinite(s); 11750 } 11751 function bn(s) { 11752 return typeof s == "string" && s.trim().length > 0 && !Number.isNaN(Date.parse(s)); 11753 } 11754 function Ws(s, t) { 11755 const e = vn(s == null ? void 0 : s.value) ? s == null ? void 0 : s.value : void 0, i = bn(s == null ? void 0 : s.date) ? s == null ? void 0 : s.date : void 0; 11756 if (e !== void 0 && i !== void 0) 11757 return { value: e, date: i }; 11758 const r = vn(t == null ? void 0 : t.nav) ? t == null ? void 0 : t.nav : void 0, n = bn(t == null ? void 0 : t.date) ? t == null ? void 0 : t.date : void 0; 11759 return r !== void 0 ? { value: r, date: n } : e !== void 0 ? { value: e, date: void 0 } : { value: void 0, date: n }; 11760 } 11761 var ai = 252; 11762 var T = class { 11763 /** 11764 * Calculates total return for a period 11765 * @param data Array of time-series data points 11766 * @param valueAccessor Function to extract the value (price/NAV) from each data point 11767 * @returns Return as decimal (0.10 = 10%), or undefined if calculation fails 11768 * @example 11769 * // For stocks 11770 * const result = StatisticsCalculator.calculateReturn(stockData, (item) => item.close); 11771 * // For funds 11772 * const result = StatisticsCalculator.calculateReturn(fundData, (item) => item.nav); 11773 */ 11774 static calculateReturn(t, e) { 11775 if (!t || t.length < 2) 11776 return; 11777 const i = e(t[0]), r = e(t[t.length - 1]); 11778 if (!(i === 0 || !Number.isFinite(i) || !Number.isFinite(r))) 11779 return r / i - 1; 11780 } 11781 /** 11782 * Calculates volatility (annualized standard deviation of returns) 11783 * @param data Array of time-series data points 11784 * @param valueAccessor Function to extract the value from each data point 11785 * @param tradingDaysPerYear Number of trading days per year (default: 252) 11786 * @returns Annualized volatility as decimal, or undefined if calculation fails 11787 */ 11788 static calculateVolatility(t, e, i = ai) { 11789 if (!t || t.length < 2) 11790 return; 11791 const r = this.calculateDailyReturns(t, e); 11792 if (r.length === 0) 11793 return; 11794 const n = r.reduce((h, c) => h + c, 0) / r.length, a = r.reduce((h, c) => h + Math.pow(c - n, 2), 0) / r.length, l = Math.sqrt(a) * Math.sqrt(i); 11795 return Number.isFinite(l) ? l : void 0; 11796 } 11797 /** 11798 * Calculates maximum drawdown 11799 * @param data Array of time-series data points 11800 * @param valueAccessor Function to extract the value from each data point 11801 * @param dateAccessor Function to extract the date from each data point 11802 * @returns MaxDrawdownResult with date and value, or undefined if calculation fails 11803 */ 11804 static calculateMaxDrawdown(t, e, i) { 11805 if (!t || t.length < 2) 11806 return; 11807 const r = e(t[0]); 11808 if (!Number.isFinite(r) || r <= 0) 11809 return; 11810 let n = r, a = 0, o = i(t[0]); 11811 for (let l = 1; l < t.length; l++) { 11812 const h = e(t[l]); 11813 if (!Number.isFinite(h) || h <= 0) 11814 continue; 11815 h > n && (n = h); 11816 const c = h / n - 1; 11817 c < a && (a = c, o = i(t[l])); 11818 } 11819 return { 11820 date: o, 11821 value: a 11822 }; 11823 } 11824 /** 11825 * Calculates Sharpe ratio 11826 * Uses risk-free rate of 0% (industry standard for mutual fund anal
11826ysis) 11827 * @param annualizedReturn Annualized return as decimal 11828 * @param volatility Annualized volatility as decimal 11829 * @returns Sharpe ratio, or undefined if calculation fails 11830 */ 11831 static calculateSharpeRatio(t, e) { 11832 if (!(t === void 0 || e === void 0 || e === 0)) 11833 return t / e; 11834 } 11835 /** 11836 * Annualizes a return based on the number of data points 11837 * @param totalReturn Total return as decimal 11838 * @param dataPoints Number of data points 11839 * @param tradingDaysPerYear Number of trading days per year (default: 252) 11840 * @returns Annualized return as decimal, or undefined if invalid 11841 */ 11842 static annualizeReturn(t, e, i = ai) { 11843 if (e <= 1) 11844 return; 11845 const r = Math.pow(1 + t, i / e) - 1; 11846 return Number.isFinite(r) ? r : void 0; 11847 } 11848 /** 11849 * Calculates daily returns from price series 11850 * @param data Array of time-series data points 11851 * @param valueAccessor Function to extract the value from each data point 11852 * @returns Array of daily returns as decimals 11853 */ 11854 static calculateDailyReturns(t, e) { 11855 if (!t || t.length < 2) 11856 return []; 11857 const i = []; 11858 for (let r = 1; r < t.length; r++) { 11859 const n = e(t[r - 1]), a = e(t[r]); 11860 n > 0 && Number.isFinite(n) && Number.isFinite(a) && a > 0 && i.push(a / n - 1); 11861 } 11862 return i; 11863 } 11864 /** 11865 * Performs linear regression: Fund Return = Alpha + Beta * Benchmark Return 11866 * @param fundReturns Array of fund daily returns 11867 * @param benchmarkReturns Array of benchmark daily returns (same length as fundReturns) 11868 * @returns RegressionResult with alpha (annualized), beta, and r2, or undefined if calculation fails 11869 */ 11870 static performRegression(t, e) { 11871 if (!t || !e || t.length < 2 || t.length !== e.length) 11872 return; 11873 const i = t.length, r = e.reduce((S, w) => S + w, 0), n = t.reduce((S, w) => S + w, 0), a = e.reduce((S, w, _) => S + w * t[_], 0), o = e.reduce((S, w) => S + w * w, 0), l = t.reduce((S, w) => S + w * w, 0), h = r / i, c = n / i, d = a / i - h * c, f = o / i - h * h; 11874 if (f === 0 || !Number.isFinite(f)) 11875 return; 11876 const m = d / f, p = c - m * h, v = l / i - c * c; 11877 if (v === 0 || !Number.isFinite(v)) 11878 return; 11879 const b = d / Math.sqrt(f * v), y = b * b, x = p * ai; 11880 if (!(!Number.isFinite(x) || !Number.isFinite(m) || !Number.isFinite(y))) 11881 return { 11882 alpha: x, 11883 beta: m, 11884 r2: y 11885 }; 11886 } 11887 /** 11888 * Calculates tracking error (annualized standard deviation of return differences) 11889 * @param returnDifferences Array of (fund return - benchmark return) for each period 11890 * @param tradingDaysPerYear Number of trading days per year (default: 252) 11891 * @returns Annualized tracking error as decimal, or undefined if calculation fails 11892 */ 11893 static calculateTrackingError(t, e = ai) { 11894 if (!t || t.length < 2) 11895 return; 11896 const i = t.reduce((o, l) => o + l, 0) / t.length, r = t.reduce((o, l) => o + Math.pow(l - i, 2), 0) / t.length, a = Math.sqrt(r) * Math.sqrt(e); 11897 return Number.isFinite(a) ? a : void 0; 11898 } 11899 }; 11900 var la = { 11901 "1y": 1, 11902 "3y": 3, 11903 "5y": 5, 11904 "10y": 10 11905 }; 11906 function ha(s, t) { 11907 return t <= 0 || !Number.isFinite(s) || s <= -1 ? s : Math.pow(1 + s, 1 / t) - 1; 11908 } 11909 function qt(s, t) { 11910 if (s == null) 11911 return; 11912 const e = la[t.toLowerCase()]; 11913 return e !== void 0 && e > 1 ? ha(s, e) : s; 11914 } 11915 function ks(s, t) { 11916 if (s == null) 11917 return; 11918 const e = la[t.toLowerCase()]; 11919 if (e !== void 0 && e > 1) { 11920 const i = s / 100; 11921 return ha(i, e) * 100; 11922 } 11923 return s; 11924 } 11925 var Hh = Object.defineProperty; 11926 var Wh = Object.getOwnPropertyDescriptor; 11927 var At = (s, t, e, i) => { 11928 for (var r = i > 1 ? void 0 : i ? Wh(t, e) : t, n = s.length - 1, a; n >= 0; n--) 11929 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 11930 return i && r && Hh(t, e, r), r; 11931 }; 11932 var wt = class extends kt { 11933 constructor() { 11934 super(), this.isin = "", this.locale = "", this.lastFetchedIsin = null, this.fetchInProgress = false, this.fullFundData = [], this.ytdReturn = null, this.longTermReturn = null, this.longTermPeriod = null, this.fundDataService = new ae(q.API_BASE_URL); 11935 } 11936 /** 11937 * Computed getter for the long-term return label 11938 * This ensures the label is re-translated when locale changes 11939 */ 11940 get longTermLabel() { 11941 switch (this.longTermPeriod) { 11942 case "5y": 11943 return u("Rentab. 5 a\xF1os", { 11944 desc: "5-year return label", 11945 id: "fund-basic-info.5y-label" 11946 }); 11947 case "3y": 11948 return u("Rentab. 3 a\xF1os", { 11949 desc: "3-year return label", 11950 id: "fund-basic-info.3y-label" 11951 }); 11952 default: 11953 return u("Rentab. 3 a\xF1os", { 11954 desc: "3-year return label (no data fallback)", 11955 id: "fund-basic-info.3y-label-fallback" 11956 }); 11957 } 11958 } 11959 /** 11960 * Datos del fondo (alias para mantener compatibilidad) 11961 */ 11962 get fundData() { 11963 return this.data; 11964 } 11965 set fundData(s) { 11966 this.data = s; 11967 } 11968 /** 11969 * Verifica si se debe obtener los datos 11970 */ 11971 shouldFetchData() { 11972 return !!this.isin; 11973 } 11974 /** 11975 * Verifica si una propiedad clave ha cambiado 11976 */ 11977 hasKeyPropertyChanged(s) { 11978 return s.has("isin") && !!this.isin; 11979 } 11980 /** 11981 * Este componente no usa header 11982 */ 11983 renderHeader() { 11984 return g``; 11985 } 11986 fetchData() { 11987 return L(this, null, function* () { 11988 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 11989 this.loading = true, this.error = null, this.fetchInProgress = true; 11990 try { 11991 const s = yield this.fundDataService.fetchFundData({ 11992 isin: this.isin, 11993 timeframe: "max", 11994 // Get all available data 11995 showHeader: false 11996 // We don't need header info 11997 }); 11998 if (this.fullFundData = s.fundData, this.fullFundData.length === 0) { 11999 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 12000 return; 12001 } 12002 const t = q.API_BASE_URL, e = yield R(`${t}/funds/product/${encodeURIComponent(this.isin)}`); 12003 if (e.status === 404) { 12004 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 12005 return; 12006 } 12007 if (!e.ok) 12008 throw new Error(u(A`Error al obtener datos del fondo: ${e.statusText}`, { 12009 desc: "Error message when fund API request fails", 12010 id: "fund-basic-info.api-error" 12011 })); 12012 const i = yield e.json(); 12013 this.processData(i), this.filterAndCalculateReturns(), this.lastFetchedIsin = this.isin; 12014 } catch (s) { 12015 this.error = s instanceof Error ? s.message : u("Error desconocido", { 12016 desc: "Generic error message", 12017 id: "fund-basic-info.error.unknown" 12018 }), console.error(u("Error al obtener datos del fondo:", { 12019 desc: "Console error message prefix", 12020 id: "fund-basic-info.error.console" 12021 }), s); 12022 } finally { 12023 this.loading = false, this.fetchInProgress = false;
12024 } 12025 } 12026 }); 12027 } 12028 // Sobrescribir el método updated para controlar cuando se debe volver a cargar 12029 updated(s) { 12030 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 12031 } 12032 processData(s) { 12033 this.fundData = s; 12034 } 12035 /** 12036 * Filter historic data and calculate returns for different timeframes 12037 * Logic: Try 5-year first, fallback to 3-year, then show dash 12038 */ 12039 filterAndCalculateReturns() { 12040 var i, r; 12041 if (this.fullFundData.length === 0) 12042 return; 12043 const s = mt.filterDataByTimeframe(this.fullFundData, "ytd"); 12044 if (!s.error && s.filteredData.length > 0) { 12045 const n = ht.calculateChange( 12046 s.filteredData, 12047 (a) => a.nav 12048 ); 12049 this.ytdReturn = n ? n.percentageChange : null; 12050 } 12051 const t = mt.filterDataByTimeframe(this.fullFundData, "5y"); 12052 if (!t.error && t.filteredData.length > 0) { 12053 const n = ht.calculateChange( 12054 t.filteredData, 12055 (a) => a.nav 12056 ); 12057 if (n) { 12058 this.longTermReturn = (i = ks(n.percentageChange, "5y")) != null ? i : null, this.longTermPeriod = "5y"; 12059 return; 12060 } 12061 } 12062 const e = mt.filterDataByTimeframe(this.fullFundData, "3y"); 12063 if (!e.error && e.filteredData.length > 0) { 12064 const n = ht.calculateChange( 12065 e.filteredData, 12066 (a) => a.nav 12067 ); 12068 if (n) { 12069 this.longTermReturn = (r = ks(n.percentageChange, "3y")) != null ? r : null, this.longTermPeriod = "3y"; 12070 return; 12071 } 12072 } 12073 this.longTermReturn = null, this.longTermPeriod = null; 12074 } 12075 renderLoading() { 12076 return g`<div class="loading">${u("Cargando informaci\xF3n del fondo...", { 12077 desc: "Loading message when fetching fund data", 12078 id: "fund-basic-info.loading" 12079 })}</div>`; 12080 } 12081 getNoDataMessage() { 12082 return u("No hay datos del fondo disponibles. Por favor, proporcione un ISIN v\xE1lido.", { 12083 desc: "Message shown when no fund data is available", 12084 id: "fund-basic-info.no-data" 12085 }); 12086 } 12087 /** 12088 * Renderiza el componente cuando no hay datos 12089 * Usa renderNoDataBlock para mostrar un estado vacÃo consistente 12090 */ 12091 renderNoData() { 12092 return g` 12093 ${Ye()} 12094 `; 12095 } 12096 /** 12097 * Helper method to determine CSS classes for performance values 12098 */ 12099 getValueClass(s) { 12100 return s === null ? "" : s > 0 ? "positive" : s < 0 ? "negative" : "zero"; 12101 } 12102 /** 12103 * Render the arrow icon SVG 12104 */ 12105 renderArrowIcon() { 12106 return g` 12107 <svg class="return-icon" width="12" height="12" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 12108 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 12109 </svg> 12110 `; 12111 } 12112 renderContent() { 12113 if (!this.fundData) 12114 return null; 12115 const { company: s, mainCategory: t } = this.fundData, e = this.fullFundData.length > 0 ? this.fullFundData[this.fullFundData.length - 1].date : (/* @__PURE__ */ new Date()).toISOString(); 12116 return g` 12117 <div class="basic-info-card"> 12118 <!-- Left Section: Fund Info --> 12119 <div class="info-section"> 12120 <span class="isin-text">${this.isin}</span> 12121 ${s != null && s.name ? g` 12122 <span class="company-text">${s.name}</span> 12123 ` : ""} 12124 ${t != null && t.name ? g` 12125 <div class="category-badge"> 12126 <span class="category-text">${t.name}</span> 12127 </div> 12128 ` : ""} 12129 </div> 12130 12131 <!-- Right Section: Returns --> 12132 <div class="returns-section"> 12133 <!-- YTD Return --> 12134 <div class="return-badge ${this.getValueClass(this.ytdReturn)}"> 12135 <span class="return-label return-label-ytd">${u("YTD", { desc: "Year-to-date label", id: "fund-basic-info.ytd-label" })}</span> 12136 <div class="return-value-row"> 12137 ${this.ytdReturn !== null ? g` 12138 ${this.renderArrowIcon()}
12139 <span class="return-value">${F.formatPercentage(this.ytdReturn / 100, this.locale || "en-US")}</span> 12140 ` : g` 12141 <span class="return-value">-</span> 12142 `} 12143 </div> 12144 </div> 12145 12146 <!-- Long-term Return (5y or 3y) --> 12147 <div class="return-badge ${this.longTermReturn !== null ? this.getValueClass(this.longTermReturn) : "neutral"}"> 12148 <span class="return-label return-label-longterm">${this.longTermLabel}</span> 12149 <div class="return-value-row"> 12150 ${this.longTermReturn !== null ? g` 12151 ${this.renderArrowIcon()} 12152 <span class="return-value">${F.formatPercentage(this.longTermReturn / 100, this.locale || "en-US")}</span> 12153 ` : g` 12154 <span class="return-value">-</span> 12155 `} 12156 </div> 12157 </div> 12158 </div> 12159 </div> 12160 <div class="info-disclaimer"> 12161 <div class="info-icon">i</div> 12162 <div> 12163 <div class="disclaimer-text"> 12164 ${u("Rentabilidades pasadas no garantizan resultados futuros. Rentabilidades anualizadas para periodos superiores a 1 a\xF1o.", { 12165 id: "disclaimer.past-returns", 12166 desc: "Past returns disclaimer text" 12167 })} 12168 </div> 12169 <div class="update-date"> 12170 ${u("Datos actualizados a", { id: "disclaimer.data-updated", desc: "Data updated to text" })} ${this.formatDate(e)} 12171 </div> 12172 </div> 12173 </div> 12174 `; 12175 } 12176 }; 12177 wt.styles = K` 12178 ${nt(Qe)} 12179 12180 :host { 12181 display: block; 12182 font-family: var(--fund-font-family, 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 12183 width: 100%; 12184 box-sizing: border-box; 12185 } 12186 12187 .loading { 12188 padding: 24px; 12189 text-align: center; 12190 color: var(--Neutral-colors-color-neutral-1, #4F5862); 12191 } 12192 12193 .basic-info-card { 12194 display: flex; 12195 padding: 24px; 12196 align-items: center; 12197 gap: 24px; 12198 align-self: stretch; 12199 border-radius: 8px; 12200 background: var(--Neutral-colors-color-neutral-3, #EBF4F9); 12201 box-sizing: border-box; 12202 } 12203 12204 .info-section { 12205 display: flex; 12206 flex-direction: column; 12207 justify-content: center; 12208 align-items: flex-start; 12209 gap: 16px; 12210 flex: 1 0 0; 12211 } 12212 12213 .isin-text { 12214 color: var(--Primary-colors-color-primary, #0C3852); 12215 font-family: Poppins, sans-serif; 12216 font-size: 28px; 12217 font-style: normal; 12218 font-weight: 500; 12219 line-height: 36px; 12220 } 12221 12222 .company-text { 12223 color: var(--Neutral-colors-color-neutral-1, #4F5862); 12224 font-family: Poppins, sans-serif; 12225 font-size: 18px; 12226 font-style: normal; 12227 font-weight: 500; 12228 line-height: 23px; 12229 letter-spacing: 2.7px; 12230 text-transform: uppercase; 12231 } 12232 12233 .category-badge { 12234 display: flex; 12235 padding: 4px 12px; 12236 justify-content: center; 12237 align-items: center; 12238 gap: 10px; 12239 border-radius: 4px; 12240 background: var(--Neutral-colors-color-neutral-2, #6B7F90); 12241 } 12242 12243 .category-text { 12244 color: var(--Neutral-colors-color-neutral-0, #FFF); 12245 font-family: Poppins, sans-serif; 12246 font-size: 18px; 12247 font-style: normal; 12248 font-weight: 500; 12249 line-height: 27px; 12250 } 12251 12252 .returns-section { 12253 display: flex; 12254 flex-direction: column; 12255 justify-content: center; 12256 align-items: flex-start; 12257 gap: 16px; 12258 } 12259 12260 .return-badge { 12261 display: flex; 12262 padding: 8px; 12263 flex-direction: column; 12264 justify-content: center; 12265 align-items: center; 12266 flex: 1 0 0; 12267 border-radius: 4px; 12268 min-width: 120px; 12269 } 12270 12271 .return-badge.positive { 12272 background: rgba(7, 125, 68, 0.15); 12273 color: var(--Semantic-colors-color-success, #077D44); 12274 } 12275 12276 .return-badge.negative { 12277 background: rgba(233, 17, 1, 0.15); 12278 color: var(--Semantic-colors-color-danger, #E91101); 12279 } 12280 12281 .return-badge.negative .return-icon { 12282 transform: rotate(180deg); 12283 } 12284 12285 .return-badge.zero { 12286 background: none; 12287 color: var(--Neutral-colors-color-neutral-1, #383D43); 12288 } 12289 12290 .return-badge.neutral {
12291 background-color: var(--fund-light-gray-bg, #f0f0f0); 12292 color: var(--fund-muted-color, #5A6773); 12293 } 12294 12295 .return-label { 12296 font-family: Poppins, sans-serif; 12297 font-style: normal; 12298 font-weight: 500; 12299 } 12300 12301 .return-label-ytd { 12302 font-size: 18px; 12303 line-height: 27px; 12304 } 12305 12306 .return-label-longterm { 12307 font-size: 14px; 12308 line-height: 21px; 12309 } 12310 12311 .return-value-row { 12312 display: flex; 12313 align-items: center; 12314 gap: 10px; 12315 } 12316 12317 .return-icon { 12318 width: 13px; 12319 height: 14px; 12320 } 12321 12322 .return-value { 12323 font-family: Poppins, sans-serif; 12324 font-size: 18px; 12325 font-style: normal; 12326 font-weight: 500; 12327 line-height: 27px; 12328 } 12329 12330 .info-disclaimer { 12331 display: flex; 12332 align-items: flex-start; 12333 gap: 8px; 12334 margin-top: 20px; 12335 } 12336 12337 .info-icon { 12338 width: 16px; 12339 height: 16px; 12340 color: var(--stock-accent-color, #58A8DA); 12341 border-radius: 50%; 12342 display: flex; 12343 align-items: center; 12344 justify-content: center; 12345 font-size: 12px; 12346 font-weight: bold; 12347 flex-shrink: 0; 12348 margin-top: 2px; 12349 border: 1px solid var(--stock-accent-color, #58A8DA); 12350 } 12351 12352 .disclaimer-text { 12353 font-size: var(--stock-small-text-size, 14px); 12354 color: var(--stock-muted-color, #383D43); 12355 line-height: 1.4; 12356 } 12357 12358 .update-date { 12359 font-size: var(--stock-small-text-size, 14px); 12360 color: var(--stock-muted-color, #383D43); 12361 margin-top: 4px; 12362 } 12363 12364 /* Mobile styles */ 12365 @media (max-width: 768px) { 12366 .basic-info-card { 12367 padding: 24px 16px 16px 16px; 12368 flex-direction: column; 12369 justify-content: center; 12370 align-items: flex-start; 12371 } 12372 12373 .info-section { 12374 display: flex; 12375 flex-direction: column; 12376 justify-content: center; 12377 align-items: flex-start; 12378 gap: 16px; 12379 flex: 1 0 0; 12380 } 12381 12382 .returns-section { 12383 display: flex; 12384 flex-direction: row; 12385 align-items: stretch; 12386 gap: 8px; 12387 align-self: stretch; 12388 } 12389 12390 .return-badge { 12391 display: flex; 12392 padding: 8px; 12393 flex-direction: column; 12394 justify-content: center; 12395 align-items: center; 12396 flex: 1 1 0; 12397 border-radius: 4px; 12398 min-width: 0; 12399 } 12400 12401 .return-badge.positive { 12402 background: rgba(7, 125, 68, 0.15); 12403 } 12404 12405 .return-badge.negative { 12406 background: rgba(233, 17, 1, 0.15); 12407 } 12408 12409 .return-badge.neutral { 12410 background-color: var(--fund-light-gray-bg, #f0f0f0); 12411 } 12412 12413 .return-label { 12414 font-weight: 400; 12415 } 12416 12417 .return-label-longterm { 12418 text-align: center; 12419 font-family: Poppins, sans-serif; 12420 font-size: 14px; 12421 font-style: normal; 12422 font-weight: 400; 12423 line-height: 21px; 12424 } 12425 12426 .return-value { 12427 font-weight: 500; 12428 } 12429 } 12430 `; 12431 At([ 12432 $({ type: String }) 12433 ], wt.prototype, "isin", 2); 12434 At([ 12435 $({ type: String }) 12436 ], wt.prototype, "locale", 2); 12437 At([ 12438 C() 12439 ], wt.prototype, "lastFetchedIsin", 2); 12440 At([ 12441 C() 12442 ], wt.prototype, "fetchInProgress", 2); 12443 At([ 12444 C() 12445 ], wt.prototype, "fullFundData", 2); 12446 At([ 12447 C() 12448 ], wt.prototype, "ytdReturn", 2); 12449 At([ 12450 C() 12451 ], wt.prototype, "longTermReturn", 2); 12452 At([ 12453 C() 12454 ], wt.prototype, "longTermPeriod", 2); 12455 wt = At([ 12456 lt(), 12457 it("fund-basic-info") 12458 ], wt); 12459 var Qh = Object.defineProperty; 12460 var Yh = Object.getOwnPropertyDescriptor; 12461 var Qs = (s, t, e, i) => { 12462 for (var r = i > 1 ? void 0 : i ? Yh(t, e) : t, n = s.length - 1, a; n >= 0; n--) 12463 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 12464 return i && r && Qh(t, e, r), r; 12465 }; 12466 var st = class extends kt { 12467 constructor() { 12468 super(...arguments), this.isin = "", this.locale = "", this.showHeader = true, this.initialIsin = null, this.ssrIdPrefix = null; 12469 } 12470 getSsrIdPrefix() { 12471 return this.ssrIdPrefix === null && (this.ssrIdPrefix = `ssr-${Math.random().toString(36).slice(2, 8)}-`), this.ssrIdPrefix; 12472 } 12473 /** 12474 * Registramos el ISIN emitido por el servidor en el primer attach. 12475 */ 12476 connectedCallback() { 12477 super.connectedCallback(), this.initialIsin === null && (this.initialIsin = this.isin || null), ys(this); 12478 } 12479 /** 12480 * Cubrimos late binding: si el host setea `isin` DESPUÃS del upgrade, 12481 * `connectedCallback()` ya corrió con `isin=""` y el stale-guard nunca se 12482 * activarÃa. Capturamos el primer `isin` no vacÃo vÃa `updated()`. 12483 */ 12484 updated(t) { 12485 super.updated(t), t.has("isin") && this.initialIsin === null && this.isin && (this.initialIsin = this.isin); 12486 } 12487 /** 12488 * Datos del fondo (alias para mantener compatibilidad) 12489 */ 12490 get fundData() { 12491 return this.data; 12492 } 12493 set fundData(t) { 12494 this.data = t; 12495 } 12496 /** 12497 * Verifica si se debe obtener los datos 12498 */ 12499 shouldFetchData() { 12500 return !!this.isin; 12501 } 12502 /** 12503 * Verifica si una propiedad clave ha cambiado 12504 */ 12505 hasKeyPropertyChanged(t) { 12506 return t.has("isin") && !!this.isin; 12507 } 12508 /** 12509 * Obtiene el mensaje de "no hay datos" 12510 */ 12511 getNoDataMessage() { 12512 return u("No hay datos disponibles. Por favor, proporcione un c\xF3digo ISIN v\xE1lido.", { 12513 desc: "Message shown when no fund data is available" 12514 }); 12515 } 12516 /**
12517 * Renderiza el componente cuando no hay datos. 12518 * 12519 * Si el host trae SSR pre-renderizado en `.rnk-SeoStaticData` (la vista de 12520 * Rankia emite NAV/rentabilidad/ratios persistidos en columnas `last_*` vÃa 12521 * `PoblarFondoDeInversionFundamentalsJob` para fallback con caché frÃa), lo 12522 * proyectamos en el shadow vÃa `unsafeHTML` en lugar de tapar con el bloque 12523 * "sin datos". Mantiene la promesa del patrón SSR persistido cuando el fetch 12524 * a la Funds API falla o devuelve vacÃo. 12525 */ 12526 renderNoData() { 12527 const t = this.renderSeoStaticFallback(); 12528 return t !== null ? t : g` 12529 ${Ye()} 12530 `; 12531 } 12532 /** 12533 * Renderiza el componente cuando hay un error. Igual que `renderNoData()`, 12534 * si el host trae SSR fallback lo proyectamos en lugar del mensaje de error â 12535 * la promesa del patrón persistido también debe sostenerse frente a fallos de 12536 * red/5xx, no solo cuando la respuesta llega vacÃa. 12537 */ 12538 renderError() { 12539 const t = this.renderSeoStaticFallback(); 12540 return t !== null ? t : super.renderError(); 12541 } 12542 /** 12543 * Proyecta el SSR fallback de `.rnk-SeoStaticData` si existe contenido 12544 * visible. Devuelve `null` cuando el host NO trae fallback (o el wrapper está 12545 * vacÃo). Cada componente que sobreescriba `renderNoData()` con copy propia 12546 * debe pedir esto PRIMERO; si devuelve null, cae a su UI custom. 12547 * 12548 * `unsafeHTML` está acotado a contenido emitido por la view server-side de 12549 * Rankia (Rails SSR), nunca input de usuario/CMS. Trust boundary documentada. 12550 */ 12551 renderSeoStaticFallback() { 12552 const t = this.getSeoStaticOuterHTML(); 12553 return t === null ? null : g`<div class="ssr-fallback">${ia(t)}</div>`; 12554 } 12555 /** 12556 * Devuelve el `outerHTML` saneado de `.rnk-SeoStaticData` (keyed en ISIN), o 12557 * `null`. Delega en el helper compartido `extractSeoStaticOuterHTML`. 12558 */ 12559 getSeoStaticOuterHTML() { 12560 return kh(this, { 12561 activeKey: this.isin, 12562 initialKey: this.initialIsin, 12563 idPrefix: this.getSsrIdPrefix() 12564 }); 12565 } 12566 /** True si el host trae SSR fallback proyectable. */ 12567 hasSeoStaticContent() { 12568 return this.getSeoStaticOuterHTML() !== null; 12569 } 12570 /** 12571 * Helper de observability para que las subclases emitan el mismo warning 12572 * cuando su fetch falla y existe SSR fallback en el light-DOM. Se llama desde 12573 * el `catch` de `fetchData()`, NO desde `render()`, para mantener render libre 12574 * de side effects. 12575 */ 12576 warnOnSeoFallback(t) { 12577 this.hasSeoStaticContent() && console.warn("[fund-element] Fetch errored; SSR fallback engaged:", t); 12578 } 12579 /** 12580 * Renderiza el encabezado con información básica del fondo 12581 * Este método es compartido por todos los componentes 12582 */ 12583 renderHeader() { 12584 if (!this.showHeader) 12585 return g``; 12586 if (!this.fundData) 12587 return this.isin ? g` 12588 <div class="info-header"> 12589 <div> 12590 <h3 class="stock-name">${this.isin}</h3> 12591 <p class="stock-symbol">${u(A`ISIN: ${this.isin}`, { desc: "ISIN label" })}</p> 12592 </div> 12593 </div> 12594 ` : g``; 12595 const { isin: t } = this.fundData; 12596 let e; 12597 return "name" in this.fundData && (e = this.fundData.name), g` 12598 <div class="info-header"> 12599 <div> 12600 <h3 class="stock-name">${e || t}</h3> 12601 <p class="stock-symbol">${u(A`ISIN: ${t}`, { desc: "ISIN label" })}</p> 12602 </div> 12603 </div> 12604 `; 12605 } 12606 /** 12607 * Renderiza el componente 12608 */ 12609 render() { 12610 return this.loading ? this.renderLoading() : this.error ? this.renderError() : this.fundData ? this.renderContent() : this.renderNoData(); 12611 } 12612 }; 12613 st.styles = K` 12614 ${nt(Qe)} 12615 `; 12616 Qs([ 12617 $({ type: String }) 12618 ], st.prototype, "isin", 2); 12619 Qs([ 12620 $({ type: String }) 12621 ], st.prototype, "locale", 2); 12622 Qs([ 12623 $({ 12624 type: Boolean, 12625 attribute: "show-header", 12626 converter: { 12627 fromAttribute: (s) => s === "false" || s === false ? false : s === "true" || s === true ? true : s !== null 12628 }, 12629 reflect: true 12630 }) 12631 ], st.prototype, "showHeader", 2); 12632 var Kh = Object.defineProperty; 12633 var Zh = Object.getOwnPropertyDescriptor; 12634 var Ys = (s, t, e, i) => { 12635 for (var r = i > 1 ? void 0 : i ? Zh(t, e) : t, n = s.length - 1, a; n >= 0; n--) 12636 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 12637 return i && r && Kh(t, e, r), r; 12638 }; 12639 var Oe = class extends st { 12640 constructor() { 12641 super(...arguments), this.lastFetchedIsin = null, this.fetchInProgress = false;
12642 } 12643 fetchData() { 12644 return L(this, null, function* () { 12645 var s; 12646 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 12647 this.loading = true, this.error = null, this.fetchInProgress = true; 12648 try { 12649 const t = q.API_BASE_URL, i = (this.locale || "es").startsWith("es") ? "es" : "en", r = `${t}/funds/product/${encodeURIComponent(this.isin)}/breakdown?language=${i}`, n = this.showHeader ? [ 12650 R(r), 12651 R(`${t}/funds/product/${encodeURIComponent(this.isin)}`) 12652 ] : [R(r)], a = yield Promise.all(n); 12653 if (!a[0].ok) 12654 throw new Error(u(A`Error al obtener desglose del fondo: ${a[0].statusText}`, { 12655 desc: "Error message when breakdown API request fails" 12656 })); 12657 const o = yield a[0].json(); 12658 if (this.showHeader && ((s = a[1]) != null && s.ok)) { 12659 const l = yield a[1].json(); 12660 this.processData(G(M({}, o), { 12661 name: l == null ? void 0 : l.name 12662 })); 12663 } else 12664 this.processData(o); 12665 this.lastFetchedIsin = this.isin; 12666 } catch (t) { 12667 this.error = t instanceof Error ? t.message : u("Error desconocido", { 12668 desc: "Generic error message", 12669 id: "fund-breakdown.error.unknown" 12670 }), console.error(u("Error al obtener desglose del fondo:", { desc: "Console error message prefix" }), t); 12671 } finally { 12672 this.loading = false, this.fetchInProgress = false; 12673 } 12674 } 12675 }); 12676 } 12677 updated(s) { 12678 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 12679 } 12680 processData(s) { 12681 this.fundData = s; 12682 } 12683 renderLoading() { 12684 return g`<div class="loading">${u("Cargando desglose del fondo...", { 12685 desc: "Loading message when fetching fund breakdown" 12686 })}</div>`; 12687 } 12688 renderBreakdownSection(s, t, e) { 12689 if (!t || !t.breakdown || t.breakdown.length === 0) 12690 return g` 12691 <div class="breakdown-section"> 12692 <div class="section-title"> 12693 ${s} 12694 </div> 12695 <div class="no-data">${u("No hay datos disponibles", { desc: "No data available message" })}</div> 12696 </div> 12697 `; 12698 const i = Math.max(...t.breakdown.map((n) => n.value)), r = [...t.breakdown].sort((n, a) => a.value - n.value); 12699 return g` 12700 <div class="breakdown-section"> 12701 <div class="section-title"> 12702 ${s} 12703 ${t.date ? g`<span class="section-date">${this.formatDate(t.date)}</span>` : ""} 12704 </div> 12705 <div class="chart-container"> 12706 ${r.map((n) => e(n, i))} 12707 </div> 12708 </div> 12709 `; 12710 } 12711 renderStandardBreakdownItem(s, t) { 12712 const e = t > 0 ? s.value / t * 100 : 0; 12713 return g` 12714 <div class="breakdown-item"> 12715 <div class="breakdown-name">${s.name}</div> 12716 <div class="breakdown-value">${this.formatPercentage(s.value)}</div> 12717 <div class="breakdown-bar"> 12718 <div class="breakdown-progress" style="width: ${e}%"></div> 12719 </div> 12720 </div> 12721 `; 12722 } 12723 renderCountryBreakdownItem(s, t) { 12724 const e = t > 0 ? s.value / t * 100 : 0; 12725 return g` 12726 <div class="breakdown-item"> 12727 <div class="breakdown-name">${s.name} (${s.code})</div> 12728 <div class="breakdown-value">${this.formatPercentage(s.value)}</div> 12729 <div class="breakdown-bar"> 12730 <div class="breakdown-progress" style="width: ${e}%"></div> 12731 </div> 12732 </div> 12733 `; 12734 } 12735 renderTop10Item(s) { 12736 return g` 12737 <div class="holding-item"> 12738 <div class="holding-info"> 12739 <div class="holding-name">${s.name}</div> 12740 ${s.code ? g`<div class="holding-code">${s.code}</div>` : ""} 12741 </div> 12742 <div class="holding-value">${this.formatPercentage(s.value)}</div> 12743 </div> 12744 `; 12745 } 12746 renderContent() { 12747 if (!this.fundData) 12748 return null; 12749 const s = this.fundData; 12750 return g` 12751 <div class="info-container"> 12752 ${this.renderHeader()} 12753 12754 <div class="breakdown-grid"> 12755 ${s.assetBreakdown ? this.renderBreakdownSection( 12756 u("Desglose por Tipo de Activo", { desc: "Asset breakdown section title" }), 12757 s.assetBreakdown, 12758 (t, e) => this.renderStandardBreakdownItem(t, e) 12759 ) : ""} 12760 12761 ${s.sectorBreakdown ? this.renderBreakdownSection( 12762 u("Desglose por Sector", { desc: "Sector breakdown section title" }), 12763 s.sectorBreakdown, 12764 (t, e) => this.renderStandardBreakdownItem(t, e) 12765 ) : ""} 12766 12767 ${s.countryBreakdown ? this.renderBreakdownSection( 12768 u("Desglose por Pa\xEDs", { desc: "Country breakdown section title" }), 12769 s.countryBreakdown, 12770 (t, e) => this.renderCountryBreakdownItem(t, e) 12771 ) : ""} 12772 12773 ${s.regionBreakdown ? this.renderBreakdownSection( 12774 u("Desglose por Regi\xF3n", { desc: "Region breakdown section title" }), 12775 s.regionBreakdown, 12776 (t, e) => this.renderCountryBreakdownItem(t, e) 12777 ) : ""} 12778 12779 ${s.currencyBreakdown ? this.renderBreakdownSection( 12780 u("Desglose por Moneda", { desc: "Currency breakdown section title" }), 12781 s.currencyBreakdown, 12782 (t, e) => this.renderCountryBreakdownItem(t, e) 12783 ) : ""} 12784 12785 ${s.creditRatingBreakdown ? this.renderBreakdownSection( 12786 u("Desglose por Calificaci\xF3n Crediticia", { desc: "Credit rating breakdown section title" }), 12787 s.creditRatingBreakdown, 12788 (t, e) => this.renderStandardBreakdownItem(t, e) 12789 ) : ""} 12790 </div> 12791 12792 ${s.top10 && s.top10.breakdown && s.top10.breakdown.length > 0 ? g` 12793 <div class="top-holdings"> 12794 <div class="section-title"> 12795 ${u("Top 10 Posiciones", { desc: "Top 10 holdings section title" })} 12796 ${s.top10.date ? g`<span class="section-date">${this.formatDate(s.top10.date)}</span>` : ""} 12797 </div> 12798 <div class="breakdown-section"> 12799 ${[...s.top10.breakdown].sort((t, e) => e.value - t.value).map((t) => this.renderTop10Item(t))} 12800 </div> 12801 </div> 12802 ` : ""} 12803 </div> 12804 `; 12805 } 12806 }; 12807 Oe.styles = K` 12808 ${nt(Ns)} 12809 12810 .info-container { 12811 width: 100%; 12812 display: block; 12813 } 12814 12815 .section-title { 12816 font-size: var(--stock-section-title-font-size, 1.1rem); 12817 font-weight: var(--stock-title-weight, 700); 12818 color: var(--stock-title-color, #1e293b); 12819 margin: 25px 0 15px 0; 12820 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 12821 padding-bottom: 5px; 12822 display: flex; 12823 justify-content: space-between; 12824 align-items: center; 12825 } 12826 12827 .section-title:first-of-type { 12828 margin-top: 15px; 12829 } 12830 12831 .section-date { 12832 font-size: var(--stock-small-text-size, 12px); 12833 color: var(--stock-muted-color, #64748b); 12834 font-weight: normal; 12835 } 12836 12837 .breakdown-grid { 12838 display: grid; 12839 grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); 12840 gap: 20px; 12841 margin-top: 20px; 12842 } 12843 12844 .breakdown-section { 12845 background: var(--stock-detail-background, #f8fafc); 12846 border: 1px solid var(--stock-detail-border, rgba(226, 232, 240, 0.6)); 12847 border-radius: 12px; 12848 padding: 20px; 12849 transition: box-shadow 0.2s ease; 12850 } 12851 12852 .breakdown-section:hover { 12853 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 12854 } 12855 12856 .breakdown-item { 12857 display: flex; 12858 justify-content: space-between; 12859 align-items: center; 12860 padding: 8px 0; 12861 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 12862 } 12863 12864 .breakdown-item:last-child { 12865 border-bottom: none; 12866 } 12867 12868 .breakdown-name { 12869 font-size: var(--stock-text-size, 14px); 12870 color: var(--stock-value-color, #334155); 12871 flex: 1; 12872 margin-right: 16px; 12873 } 12874 12875 .breakdown-value { 12876 font-size: var(--stock-text-size, 14px);
12877 font-weight: var(--stock-value-weight, 600); 12878 color: var(--stock-value-color, #334155); 12879 min-width: 60px; 12880 text-align: right; 12881 } 12882 12883 .breakdown-bar { 12884 width: 100%; 12885 height: 4px; 12886 background-color: var(--stock-border-color, #e0e0e0); 12887 border-radius: 2px; 12888 margin-top: 4px; 12889 overflow: hidden; 12890 } 12891 12892 .breakdown-progress { 12893 height: 100%; 12894 background: linear-gradient(45deg, var(--stock-accent-color, #3b82f6), var(--stock-positive-color, #388e3c)); 12895 border-radius: 2px; 12896 transition: width 0.3s ease; 12897 } 12898 12899 .top-holdings { 12900 grid-column: 1 / -1; 12901 } 12902 12903 .top-holdings .breakdown-grid { 12904 grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); 12905 } 12906 12907 .holding-item { 12908 display: flex; 12909 justify-content: space-between; 12910 align-items: flex-start; 12911 padding: 12px 0; 12912 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 12913 } 12914 12915 .holding-item:last-child { 12916 border-bottom: none; 12917 } 12918 12919 .holding-info { 12920 flex: 1; 12921 margin-right: 16px; 12922 } 12923 12924 .holding-name { 12925 font-size: var(--stock-text-size, 14px); 12926 color: var(--stock-value-color, #334155); 12927 font-weight: var(--stock-value-weight, 500); 12928 line-height: 1.3; 12929 } 12930 12931 .holding-code { 12932 font-size: 12px; 12933 color: var(--text-secondary-color, #666); 12934 margin-top: 2px; 12935 } 12936 12937 .holding-value { 12938 font-size: 14px; 12939 font-weight: 600; 12940 color: var(--text-primary-color, #333); 12941 min-width: 70px; 12942 text-align: right; 12943 } 12944 12945 .no-data { 12946 text-align: center; 12947 color: var(--text-secondary-color, #666); 12948 font-style: italic; 12949 padding: 20px; 12950 } 12951 12952 .chart-container { 12953 margin-top: 15px; 12954 max-height: 300px; 12955 overflow-y: auto; 12956 } 12957 12958 @media (max-width: 600px) { 12959 .breakdown-grid { 12960 grid-template-columns: 1fr; 12961 } 12962 12963 .top-holdings .breakdown-grid { 12964 grid-template-columns: 1fr; 12965 } 12966 } 12967 `; 12968 Ys([ 12969 C() 12970 ], Oe.prototype, "lastFetchedIsin", 2); 12971 Ys([ 12972 C() 12973 ], Oe.prototype, "fetchInProgress", 2); 12974 Oe = Ys([ 12975 lt(), 12976 it("fund-breakdown") 12977 ], Oe); 12978 var Gh = Object.defineProperty; 12979 var Xh = Object.getOwnPropertyDescriptor; 12980 var Ce = (s, t, e, i) => { 12981 for (var r = i > 1 ? void 0 : i ? Xh(t, e) : t, n = s.length - 1, a; n >= 0; n--) 12982 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 12983 return i && r && Gh(t, e, r), r; 12984 }; 12985 var Vt = class extends st { 12986 constructor() { 12987 super(...arguments), this.display = null, this.lastFetchedIsin = null, this.fetchInProgress = false, this.activeTab = "top10"; 12988 } 12989 fetchData() { 12990 return L(this, null, function* () { 12991 var s; 12992 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 12993 this.loading = true, this.error = null, this.fetchInProgress = true; 12994 try { 12995 const t = q.API_BASE_URL, i = (this.locale || "es").startsWith("es") ? "es" : "en", r = `${t}/funds/product/${encodeURIComponent(this.isin)}/breakdown?language=${i}`, n = this.showHeader ? [ 12996 R(r), 12997 R(`${t}/funds/product/${encodeURIComponent(this.isin)}`) 12998 ] : [R(r)], a = yield Promise.all(n); 12999 if (!a[0].ok) { 13000 if (a[0].status === 404) { 13001 this.fundData = null, this.error = null, this.lastFetchedIsin = this.isin; 13002 return; 13003 } 13004 throw new Error(u(A`Error al obtener desglose del fondo: ${a[0].statusText}`, { 13005 desc: "Error message when breakdown API request fails" 13006 })); 13007 } 13008 const o = yield a[0].json(); 13009 if (!this.hasAnyBreakdownData(o)) { 13010 this.fundData = null, this.error = null, this.lastFetchedIsin = this.isin; 13011 return; 13012 } 13013 if (this.showHeader && ((s = a[1]) != null && s.ok)) { 13014 const h = yield a[1].json(); 13015 this.processData(G(M({}, o), { 13016 name: h == null ? void 0 : h.name 13017 })); 13018 } else 13019 this.processData(o); 13020 this.lastFetchedIsin = this.isin; 13021 } catch (t) { 13022 this.error = t instanceof Error ? t.message : u("Error desconocido", { 13023 desc: "Generic error message", 13024 id: "fund-cartera.error.unknown" 13025 }), this.warnOnSeoFallback(t), console.error(u("Error al obtener desglose del fondo:", { desc: "Console error message prefix" }), t); 13026 } finally { 13027 this.loading = false, this.fetchInProgress = false;
13028 } 13029 } 13030 }); 13031 } 13032 firstUpdated(s) { 13033 super.firstUpdated(s), setTimeout(() => { 13034 yt(this); 13035 }, 0); 13036 } 13037 updated(s) { 13038 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(), setTimeout(() => { 13039 yt(this); 13040 }, 0); 13041 } 13042 processData(s) { 13043 this.fundData = s; 13044 const t = this.getFirstAvailableTab(); 13045 t && !this.hasDataForTab(this.activeTab) && (this.activeTab = t); 13046 } 13047 hasDataForTab(s) { 13048 switch (s) { 13049 case "top10": 13050 return this.hasTop10Data(); 13051 case "assets": 13052 return this.hasAssetsData(); 13053 case "sectors": 13054 return this.hasSectorsData(); 13055 default: 13056 return false; 13057 } 13058 } 13059 renderLoading() { 13060 return g`<div class="loading">${u("Cargando cartera del fondo...", { 13061 desc: "Loading message when fetching fund portfolio data" 13062 })}</div>`; 13063 } 13064 getNoDataMessage() { 13065 return u("No hay datos de cartera disponibles", { 13066 desc: "No portfolio data available message" 13067 }); 13068 } 13069 renderHeader() { 13070 var s; 13071 return !this.showHeader || !((s = this.fundData) != null && s.name) ? g`` : g` 13072 <div class="fund-header"> 13073 ${Dt(this.headerLevel, "fund-name", this.fundData.name)} 13074 <div class="fund-isin">ISIN: ${this.fundData.isin}</div> 13075 </div> 13076 `; 13077 } 13078 switchTab(s) { 13079 this.activeTab = s; 13080 } 13081 shouldShowTable() { 13082 return this.display === null || this.display === "" || this.display === "table"; 13083 } 13084 shouldShowBars() { 13085 return this.display === null || this.display === "" || this.display === "bars"; 13086 } 13087 hasTop10Data() { 13088 var s, t; 13089 return !!((t = (s = this.fundData) == null ? void 0 : s.top10) != null && t.breakdown && this.fundData.top10.breakdown.length > 0); 13090 } 13091 hasAssetsData() { 13092 var s, t; 13093 return !!((t = (s = this.fundData) == null ? void 0 : s.assetBreakdown) != null && t.breakdown && this.fundData.assetBreakdown.breakdown.length > 0); 13094 } 13095 hasSectorsData() { 13096 var s, t; 13097 return !!((t = (s = this.fundData) == null ? void 0 : s.sectorBreakdown) != null && t.breakdown && this.fundData.sectorBreakdown.breakdown.length > 0); 13098 } 13099 getFirstAvailableTab() { 13100 return this.hasTop10Data() ? "top10" : this.hasAssetsData() ? "assets" : this.hasSectorsData() ? "sectors" : null; 13101 } 13102 hasAnyBreakdownData(s) { 13103 var t, e, i, r, n, a, o; 13104 return !!((t = s.top10) != null && t.breakdown && s.top10.breakdown.length > 0 || (e = s.assetBreakdown) != null && e.breakdown && s.assetBreakdown.breakdown.length > 0 || (i = s.sectorBreakdown) != null && i.breakdown && s.sectorBreakdown.breakdown.length > 0 || (r = s.countryBreakdown) != null && r.breakdown && s.countryBreakdown.breakdown.length > 0 || (n = s.creditRatingBreakdown) != null && n.breakdown && s.creditRatingBreakdown.breakdown.length > 0 || (a = s.currencyBreakdown) != null && a.breakdown && s.currencyBreakdown.breakdown.length > 0 || (o = s.regionBreakdown) != null && o.breakdown && s.regionBreakdown.breakdown.length > 0); 13105 } 13106 getGradientColor(s) { 13107 const t = [ 13108 "#1A5275", 13109 // Dark blue 13110 "#E81949", 13111 // Red (updated) 13112 "#0C3852", 13113 // Dark gray (updated) 13114 "#FFAD33", 13115 // Orange (updated) 13116 "#428CC3", 13117 // Light blue (updated) 13118 "#996666", 13119 // Purple (updated) 13120 "#00856F", 13121 // Green (updated) 13122 "#5A6773", 13123 // Dark orange (updated) 13124 "#3498DB", 13125 // Blue 13126 "#9B59B6", 13127 // Light purple 13128 "#1ABC9C", 13129 // Teal 13130 "#34495E" 13131 // Dark slate 13132 ]; 13133 return t[s % t.length]; 13134 } 13135 renderTop10Content() { 13136 var e, i; 13137 if (!((i = (e = this.fundData) == null ? void 0 : e.top10) != null && i.breakdown) || this.fundData.top10.breakdown.length === 0) 13138 return g` 13139 <div class="no-data">${u("No hay datos de posiciones disponibles", { desc: "No top 10 positions data available" })}</div> 13140 `; 13141 const s = [...this.fundData.top10.breakdown].sort((r, n) => n.value - r.value), t = this.display === "table" ? "table-only" : this.display === "bars" ? "bars-only" : ""; 13142 return g` 13143 <div class="top10-scope"> 13144 <div class="content-layout ${t}"> 13145 ${this.shouldShowTable() ? g` 13146 <div class="data-table"> 13147 <table style="width: 100%; border-collapse: collapse;"> 13148 <thead class="table-header"> 13149 <tr> 13150 <th>${u("Posiciones", { desc: "Positions column header" })}</th> 13151 <th>${u("Peso en cartera", { desc: "Portfolio weight column header" })}</th> 13152 </tr> 13153 </thead> 13154 <tbody> 13155 ${s.map((r, n) => g` 13156 <tr class="table-row"> 13157 <td class="table-cell"> 13158 <div style="display: flex; align-items: center;"> 13159 <div class="position-number">${n + 1}</div> 13160 <div>${r.name}</div> 13161 </div> 13162 </td> 13163 <td class="table-cell">${this.formatPercentage(r.value)}</td> 13164 </tr> 13165 `)} 13166 </tbody> 13167 </table> 13168 </div> 13169 ` : ""} 13170 13171 ${this.shouldShowBars() ? g` 13172 <div class="chart-container"> 13173 ${s.map((r, n) => g` 13174 <div class="chart-item"> 13175 <div class="chart-text-row"> 13176 <div class="position-number">${n + 1}</div> 13177 <div class="chart-label">${r.name}</div> 13178 <div class="chart-value">${this.formatPercentage(r.value)}</div> 13179 </div> 13180 <div class="chart-bar-row"> 13181 <div class="chart-bar-container"> 13182 <div class="chart-bar" style="width: ${Math.max(0, r.value * 100)}%; background-color: #1A5275;"></div> 13183 </div> 13184 </div> 13185 </div> 13186 `)} 13187 </div> 13188 ` : ""} 13189 </div> 13190 </div> 13191 `; 13192 } 13193 renderAssetsContent() { 13194 var e, i; 13195 if (!((i = (e = this.fundData) == null ? void 0 : e.assetBreakdown) != null && i.breakdown) || this.fundData.assetBreakdown.breakdown.length === 0) 13196 return g` 13197 <div class="no-data">${u("No hay datos de distribuci\xF3n de activos disponibles", { desc: "No asset distribution data available" })}</div> 13198 `; 13199 const s = [...this.fundData.assetBreakdown.breakdown].sort((r, n) => n.value - r.value), t = this.display === "table" ? "table-only" : this.display === "bars" ? "bars-only" : ""; 13200 return g` 13201 <div class="content-layout ${t}"> 13202 ${this.shouldShowTable() ? g` 13203 <div class="data-table"> 13204 <table style="width: 100%; border-collapse: collapse;"> 13205 <thead class="table-header"> 13206 <tr> 13207 <th>${u("Clase de activo", { desc: "Asset class column header" })}</th> 13208 <th>${u("Fondo", { desc: "Fund column header", id: "fund-cartera.header.fund" })}</th> 13209 </tr> 13210 </thead> 13211 <tbody> 13212 ${s.map((r, n) => g` 13213 <tr class="table-row"> 13214 <td class="table-cell"> 13215 <div style="display: flex; align-items: center;"> 13216 <div class="position-number" style="background-color: ${this.getGradientColor(n)}; "></div> 13217 <div>${r.name}</div> 13218 </div> 13219 </td> 13220 <td class="table-cell">${this.formatPercentage(r.value)}</td> 13221 </tr> 13222 `)} 13223 </tbody> 13224 </table> 13225 </div> 13226 ` : ""} 13227 13228 ${this.shouldShowBars() ? g` 13229 <div class="chart-container"> 13230 ${s.map((r, n) => { 13231 const a = this.getGradientColor(n); 13232 return g` 13233 <div class="chart-item"> 13234 <div class="chart-text-row"> 13235 <div class="chart-label">${r.name}</div> 13236 <div class="chart-value">${this.formatPercentage(r.value)}</div> 13237 </div> 13238 <div class="chart-bar-row"> 13239 <div class="chart-bar-container"> 13240 <div class="chart-bar" style="width: ${Math.max(0, r.value * 100)}%; background-color: ${a};"></div> 13241 </div> 13242 </div> 13243 </div> 13244 `; 13245 })} 13246 </div> 13247 ` : ""} 13248 </div> 13249 `; 13250 } 13251 renderSectorsContent() { 13252 var e, i; 13253 if (!((i = (e = this.fundData) == null ? void 0 : e.sectorBreakdown) != null && i.breakdown) || this.fundData.sectorBreakdown.breakdown.length === 0) 13254 return g` 13255 <div class="no-data">${u("No hay datos de distribuci\xF3n por sectores disponibles", { desc: "No sector distribution data available" })}</div> 13256 `; 13257 const s = [...this.fundData.sectorBreakdown.breakdown].sort((r, n) => n.value - r.value), t = this.display === "table" ? "table-only" : this.display === "bars" ? "bars-only" : ""; 13258 return g` 13259 <div class="content-layout ${t}"> 13260 ${this.shouldShowTable() ? g` 13261 <div class="data-table"> 13262 <table style="width: 100%; border-collapse: collapse;"> 13263 <thead class="table-header"> 13264 <tr> 13265 <th>${u("Clase de activo", { desc: "Asset class column header" })}</th> 13266 <th>${u("Fondo", { desc: "Fund column header", id: "fund-cartera.header.fund" })}</th> 13267 </tr> 13268 </thead> 13269 <tbody> 13270 ${s.map((r, n) => g` 13271 <tr class="table-row"> 13272 <td class="table-cell"> 13273 <div style="display: flex; align-items: center;"> 13274 <div class="position-number" style="background-color: ${this.getGradientColor(n)}; "></div> 13275 <div>${r.name}</div> 13276 </div> 13277 </td> 13278 <td class="table-cell">${this.formatPercentage(r.value)}</td> 13279 </tr> 13280 `)} 13281 </tbody> 13282 </table> 13283 </div> 13284 ` : ""} 13285 13286 ${this.shouldShowBars() ? g` 13287 <div class="chart-container"> 13288 ${s.map((r, n) => { 13289 const a = this.getGradientColor(n); 13290 return g` 13291 <div class="chart-item"> 13292 <div class="chart-text-row"> 13293 <div class="chart-label">${r.name}</div> 13294 <div class="chart-value">${this.formatPercentage(r.value)}</div> 13295 </div> 13296 <div class="chart-bar-row"> 13297 <div class="chart-bar-container"> 13298 <div class="chart-bar" style="width: ${Math.max(0, r.value * 100)}%; background-color: ${a};"></div> 13299 </div> 13300 </div> 13301 </div> 13302 `; 13303 })} 13304 </div> 13305 ` : ""} 13306 </div> 13307 `; 13308 }
13309 getUpdateDate() { 13310 var t, e, i; 13311 const s = this.fundData; 13312 return (t = s == null ? void 0 : s.top10) != null && t.date ? s.top10.date : (e = s == null ? void 0 : s.assetBreakdown) != null && e.date ? s.assetBreakdown.date : (i = s == null ? void 0 : s.sectorBreakdown) != null && i.date ? s.sectorBreakdown.date : (/* @__PURE__ */ new Date()).toISOString(); 13313 } 13314 renderContent() { 13315 const s = this.getUpdateDate(), t = this.hasTop10Data() || this.hasAssetsData() || this.hasSectorsData(); 13316 return g` 13317 <div class="carpeta-container"> 13318 ${this.renderHeader()} 13319 13320 ${t ? g` 13321 <div class="tab-navigation horizontal-scroll-element"> 13322 <div class="horizontal-scroll-element-inner"> 13323 ${this.hasTop10Data() ? g` 13324 <button 13325 class="tab-button ${this.activeTab === "top10" ? "active" : ""}" 13326 @click="${() => this.switchTab("top10")}" 13327 > 13328 ${u("Top 10 posiciones", { desc: "Top 10 positions tab" })} 13329 </button> 13330 ` : ""} 13331 ${this.hasAssetsData() ? g` 13332 <button 13333 class="tab-button ${this.activeTab === "assets" ? "active" : ""}" 13334 @click="${() => this.switchTab("assets")}" 13335 > 13336 ${u("Distribuci\xF3n de activos", { desc: "Asset distribution tab" })} 13337 </button> 13338 ` : ""} 13339 ${this.hasSectorsData() ? g` 13340 <button 13341 class="tab-button ${this.activeTab === "sectors" ? "active" : ""}" 13342 @click="${() => this.switchTab("sectors")}" 13343 > 13344 ${u("Distribuci\xF3n por sectores", { desc: "Sector distribution tab" })} 13345 </button> 13346 ` : ""} 13347 </div> 13348 </div> 13349 ` : ""} 13350 13351 ${t ? g` 13352 ${this.hasTop10Data() ? g` 13353 <div class="tab-content ${this.activeTab === "top10" ? "active" : ""}"> 13354 ${this.renderTop10Content()} 13355 </div> 13356 ` : ""} 13357 13358 ${this.hasAssetsData() ? g` 13359 <div class="tab-content ${this.activeTab === "assets" ? "active" : ""}"> 13360 ${this.renderAssetsContent()} 13361 </div> 13362 ` : ""} 13363 13364 ${this.hasSectorsData() ? g` 13365 <div class="tab-content ${this.activeTab === "sectors" ? "active" : ""}"> 13366 ${this.renderSectorsContent()} 13367 </div> 13368 ` : ""} 13369 ` : ""} 13370 13371 <div class="update-date"> 13372 <div class="info-icon">i</div> 13373 <div> 13374 ${u("Datos actualizados a", { desc: "Data updated to text" })} ${this.formatDate(s)} 13375 </div> 13376 </div> 13377 </div> 13378 `; 13379 } 13380 }; 13381 Vt.styles = K` 13382 ${nt(st.styles)} 13383 ${nt(We)} 13384 ${_i} 13385 13386 .carpeta-container { 13387 width: 100%; 13388 display: block; 13389 } 13390 13391 .fund-header { 13392 margin-bottom: 20px; 13393 padding-bottom: 15px; 13394 border-bottom: 1px solid var(--stock-border-color, #f2f2f2); 13395 } 13396 13397 .fund-name { 13398 font-size: var(--stock-section-title-font-size, 1.2rem); 13399 font-weight: var(--stock-title-weight, 700); 13400 color: var(--stock-title-color, #1e293b); 13401 margin: 0 0 8px 0; 13402 } 13403 13404 .fund-isin { 13405 font-size: var(--stock-small-text-size, 14px); 13406 color: var(--stock-muted-color, #64748b); 13407 font-weight: var(--stock-value-weight, 500); 13408 } 13409 13410 .tab-navigation { 13411 width: 100%; 13412 margin-bottom: 20px; 13413 } 13414 13415 .tab-content { 13416 display: none; 13417 } 13418 13419 .tab-content.active { 13420 display: block; 13421 } 13422 13423 .content-layout { 13424 display: grid; 13425 grid-template-columns: 1fr 1fr; 13426 gap: 60px; 13427 margin-top: 20px; 13428 } 13429 13430 .content-layout.table-only, 13431 .content-layout.bars-only { 13432 grid-template-columns: 1fr; 13433 } 13434 13435 .data-table { 13436 } 13437 13438 .table-header { 13439 background: none; 13440 border-bottom: 2px solid var(--stock-danger-color, #E91101); 13441 margin-bottom: 15px; 13442 } 13443 13444 .table-header th { 13445 padding: 12px 8px; 13446 text-align: left; 13447 font-size: var(--stock-text-size, 14px); 13448 font-weight: var(--stock-title-weight, 700); 13449 color: var(--stock-text-color, #383d43); 13450 width: 50%; 13451 } 13452 13453 .table-header th:first-child { 13454 width: 70%; 13455 } 13456 13457 .table-header th:last-child { 13458 width: 30%; 13459 text-align: right; 13460 } 13461 13462 .table-row { 13463 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 13464 } 13465 13466 .table-row:last-child { 13467 border-bottom: none; 13468 } 13469 13470 .table-cell { 13471 padding: 12px 8px; 13472 font-size: var(--stock-text-size, 14px); 13473 width: 50%; 13474 } 13475 13476 .table-cell:first-child { 13477 width: 70%; 13478 font-weight: var(--stock-title-weight, 600); 13479 color: var(--stock-text-color, #383d43); 13480 } 13481 13482 .table-cell:last-child { 13483 width: 30%; 13484 text-align: right; 13485 } 13486
13487 .chart-container { 13488 margin-top: 36px; 13489 } 13490 13491 .chart-item { 13492 margin-bottom: 15px; 13493 position: relative; 13494 } 13495 13496 .chart-item:last-child { 13497 margin-bottom: 0; 13498 } 13499 13500 .chart-text-row { 13501 display: flex; 13502 align-items: center; 13503 margin-bottom: 8px; 13504 } 13505 13506 .position-number { 13507 width: 16px; 13508 height: 16px; 13509 border-radius: 50%; 13510 background-color: var(--stock-info-color, rgba(88, 168, 218, 0.15)); 13511 margin-right: 12px; 13512 flex-shrink: 0; 13513 } 13514 13515 .chart-label { 13516 font-size: var(--stock-text-size, 14px); 13517 color: var(--stock-text-color, #383d43); 13518 font-weight: var(--stock-value-weight, 500); 13519 margin-right: 12px; 13520 min-width: 0; 13521 flex: 1; 13522 } 13523 13524 .chart-value { 13525 font-size: var(--stock-text-size, 14px); 13526 color: var(--stock-text-color, #383d43); 13527 min-width: 60px; 13528 text-align: right; 13529 } 13530 13531 .chart-bar-row { 13532 display: flex; 13533 align-items: center; 13534 } 13535 13536 .chart-bar-container { 13537 flex: 1; 13538 height: 20px; 13539 background-color: var(--stock-border-color, #e0e0e0); 13540 border-radius: 4px; 13541 position: relative; 13542 overflow: hidden; 13543 } 13544 13545 .chart-bar { 13546 height: 100%; 13547 border-radius: 4px; 13548 transition: width 0.3s ease; 13549 } 13550 13551 .no-data { 13552 text-align: center; 13553 color: var(--stock-muted-color, #64748b); 13554 font-style: italic; 13555 padding: 40px 20px; 13556 } 13557 13558 .update-date { 13559 font-size: var(--stock-small-text-size, 14px); 13560 color: var(--stock-muted-color, #383D43); 13561 margin-top: 20px; 13562 display: flex; 13563 align-items: flex-end; 13564 gap: 8px; 13565 } 13566 13567 .info-icon { 13568 width: 16px; 13569 height: 16px; 13570 color: var(--stock-accent-color, #58A8DA); 13571 border-radius: 50%; 13572 display: flex; 13573 align-items: center; 13574 justify-content: center; 13575 font-size: 12px; 13576 font-weight: bold; 13577 flex-shrink: 0; 13578 margin-top: 2px; 13579 border: 1px solid var(--stock-accent-color, #58A8DA); 13580 } 13581 13582 /* Scoped style for first tab markers: square, single color, numbered */ 13583 .top10-scope .position-number { 13584 width: 20px; 13585 height: 20px; 13586 border-radius: 4px; 13587 background-color: #EBF6FF; 13588 color: #1A5275; 13589 display: flex; 13590 align-items: center; 13591 justify-content: center; 13592 margin-right: 12px; 13593 font-size: 12px; 13594 font-weight: 700; 13595 flex-shrink: 0; 13596 } 13597 13598 @media (max-width: 768px) { 13599 .content-layout { 13600 grid-template-columns: 1fr; 13601 gap: 32px; 13602 } 13603 13604 .table-header th, 13605 .table-cell { 13606 font-size: 12px; 13607 } 13608 13609 .chart-item { 13610 margin-bottom: 12px; 13611 } 13612 13613 .chart-text-row { 13614 margin-bottom: 6px; 13615 } 13616 13617 .chart-label { 13618 font-size: 12px; 13619 } 13620 13621 .chart-value { 13622 font-size: 12px; 13623 min-width: 50px; 13624 } 13625 } 13626 `; 13627 Ce([ 13628 $({ type: String, reflect: true }) 13629 ], Vt.prototype, "display", 2); 13630 Ce([ 13631 $({ type: String, attribute: "header-level" }) 13632 ], Vt.prototype, "headerLevel", 2); 13633 Ce([ 13634 C() 13635 ], Vt.prototype, "lastFetchedIsin", 2); 13636 Ce([ 13637 C() 13638 ], Vt.prototype, "fetchInProgress", 2); 13639 Ce([ 13640 C() 13641 ], Vt.prototype, "activeTab", 2); 13642 Vt = Ce([ 13643 lt(), 13644 it("fund-cartera") 13645 ], Vt); 13646 var Jh = Object.defineProperty; 13647 var tc = Object.getOwnPropertyDescriptor; 13648 var $i = (s, t, e, i) => { 13649 for (var r = i > 1 ? void 0 : i ? tc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 13650 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 13651 return i && r && Jh(t, e, r), r; 13652 }; 13653 var we = class extends st { 13654 constructor() { 13655 super(...arguments), this.lastFetchedIsin = null, this.fetchInProgress = false; 13656 } 13657 fetchData() { 13658 return L(this, null, function* () { 13659 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 13660 this.loading = true, this.error = null, this.fetchInProgress = true; 13661 try { 13662 const s = q.API_BASE_URL, t = yield R(`${s}/funds/product/${encodeURIComponent(this.isin)}`); 13663 if (!t.ok) { 13664 if (t.status === 404) { 13665 this.fundData = null, this.error = null, this.lastFetchedIsin = this.isin; 13666 return; 13667 } 13668 throw new Error(u(A`Error al obtener datos del fondo: ${t.statusText}`, { 13669 desc: "Error message when API request fails" 13670 })); 13671 } 13672 const e = yield t.json(); 13673 this.processData(e), this.lastFetchedIsin = this.isin; 13674 } catch (s) { 13675 this.error = s instanceof Error ? s.message : u("Error desconocido", { 13676 desc: "Generic error message", 13677 id: "fund-description.error.unknown" 13678 }), this.warnOnSeoFallback(s), console.error(u("Error al obtener datos del fondo:", { desc: "Console error message prefix", id: "fund-description.console.error" }), s); 13679 } finally { 13680 this.loading = false, this.fetchInProgress = false;
13681 } 13682 } 13683 }); 13684 } 13685 updated(s) { 13686 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 13687 } 13688 processData(s) { 13689 this.fundData = s; 13690 } 13691 renderLoading() { 13692 return g`<div class="loading">${u("Cargando informaci\xF3n del fondo...", { 13693 desc: "Loading message when fetching fund data", 13694 id: "fund-description.loading" 13695 })}</div>`; 13696 } 13697 formatCurrencyWithSymbol(s, t = "EUR") { 13698 return new Intl.NumberFormat(this.locale || void 0, { 13699 style: "currency", 13700 currency: t 13701 }).format(s); 13702 } 13703 formatTimestamp(s) { 13704 if (!s) 13705 return ""; 13706 const t = new Date(s); 13707 return new Intl.DateTimeFormat(this.locale || void 0, { 13708 day: "2-digit", 13709 month: "2-digit", 13710 year: "numeric" 13711 }).format(t); 13712 } 13713 renderContent() { 13714 var t, e, i, r, n, a, o, l, h, c; 13715 if (!this.fundData) 13716 return null; 13717 const s = this.fundData; 13718 return g` 13719 <div class="info-block"> 13720 ${this.showHeader ? g` 13721 <div class="info-header"> 13722 <div> 13723 ${Dt(this.headerLevel, "stock-name", s.name)} 13724 <p class="stock-symbol">${u("ISIN", { desc: "ISIN label", id: "fund-description.isin.label" })}: ${this.isin}</p> 13725 </div> 13726 </div> 13727 ` : ""} 13728 13729 <table class="info-table"> 13730 <tbody> 13731 <tr class="info-tableRow"> 13732 <th class="info-tableCell info-tableCell--Header">${u("Nombre", { desc: "Name label", id: "fund-description.name.label" })}</th> 13733 <td class="info-tableCell">${s.name}</td> 13734 </tr> 13735 13736 <tr class="info-tableRow"> 13737 <th class="info-tableCell info-tableCell--Header">${u("ISIN", { desc: "ISIN label", id: "fund-description.isin.label" })}</th> 13738 <td class="info-tableCell">${this.isin}</td> 13739 </tr> 13740 13741 ${s.launchDate ? g` 13742 <tr class="info-tableRow"> 13743 <th class="info-tableCell info-tableCell--Header">${u("Fecha de lanzamiento", { desc: "Launch date label", id: "fund-description.launch-date.label" })}</th> 13744 <td class="info-tableCell">${this.formatTimestamp(s.launchDate)}</td> 13745 </tr> 13746 ` : ""} 13747 13748 <tr class="info-tableRow"> 13749 <th class="info-tableCell info-tableCell--Header">${u("Divisa", { desc: "Currency label", id: "fund-description.currency.label" })}</th> 13750 <td class="info-tableCell">${s.currency}</td> 13751 </tr> 13752 13753 ${(t = s.srri) != null && t.value ? g` 13754 <tr class="info-tableRow"> 13755 <th class="info-tableCell info-tableCell--Header">${u("Nivel de riesgo", { desc: "Risk level label", id: "fund-description.risk-level.label" })}</th> 13756 <td class="info-tableCell">${s.srri.value}/7</td> 13757 </tr> 13758 ` : ""} 13759 13760 ${((e = s.fund) == null ? void 0 : e.isPassive) !== void 0 ? g` 13761 <tr class="info-tableRow"> 13762 <th class="info-tableCell info-tableCell--Header">${u("Estilo de inversi\xF3n", { desc: "Investment style label", id: "fund-description.investment-style.label" })}</th> 13763 <td class="info-tableCell">${s.fund.isPassive ? u("Pasiva", { desc: "Passive investment style", id: "fund-description.passive-style" }) : u("Activa", { desc: "Active investment style", id: "fund-description.active-style" })}</td> 13764 </tr> 13765 ` : ""} 13766 13767 ${(i = s.fees) != null && i.minimalInitialSubscriptionAmount ? g` 13768 <tr class="info-tableRow"> 13769 <th class="info-tableCell info-tableCell--Header">${u("Inversi\xF3n m\xEDnima inicial", { desc: "Minimum initial investment label", id: "fund-description.minimum-investment.label" })}</th> 13770 <td class="info-tableCell">${this.formatCurrencyWithSymbol(s.fees.minimalInitialSubscriptionAmount, s.currency)}</td> 13771 </tr> 13772 ` : ""} 13773 13774 ${(r = s.company) != null && r.name ? g` 13775 <tr class="info-tableRow"> 13776 <th class="info-tableCell info-tableCell--Header">${u("Gestora", { desc: "Manager label", id: "fund-description.manager.label" })}</th> 13777 <td class="info-tableCell">${s.company.name}</td> 13778 </tr> 13779 ` : ""} 13780 13781 ${(n = s.mainCategory) != null && n.name ? g` 13782 <tr class="info-tableRow"> 13783 <th class="info-tableCell info-tableCell--Header">${u("Categor\xEDa principal", { desc: "Main category label", id: "fund-description.main-category.label" })}</th> 13784 <td class="info-tableCell">${s.mainCategory.name}</td> 13785 </tr> 13786 ` : ""} 13787 13788 ${(o = (a = s.fund) == null ? void 0 : a.assetClass) != null && o.name ? g` 13789 <tr class="info-tableRow"> 13790 <th class="info-tableCell info-tableCell--Header">${u("Benchmark", { desc: "Benchmark label", id: "fund-description.benchmark.label" })}</th> 13791 <td class="info-tableCell">${s.fund.assetClass.name}</td> 13792 </tr> 13793 ` : ""} 13794 13795 ${(l = s.aum) != null && l.value ? g` 13796 <tr class="info-tableRow"> 13797 <th class="info-tableCell info-tableCell--Header">${u("Patrimonio actual", { desc: "Current assets label", id: "fund-description.current-assets.label" })}</th> 13798 <td class="info-tableCell">${F.formatNumber(s.aum.value, this.locale)} ${s.currency}</td> 13799 </tr> 13800 ` : ""} 13801 13802 ${(h = s.nav) != null && h.value ? g` 13803 <tr class="info-tableRow"> 13804 <th class="info-tableCell info-tableCell--Header">${u("Valor liquidativo", { desc: "Net asset value label", id: "fund-description.net-asset-value.label" })}</th> 13805 <td class="info-tableCell">${this.formatCurrencyWithSymbol(s.nav.value, s.currency)}</td> 13806 </tr> 13807 ` : ""} 13808 13809 ${(c = s.company) != null && c.name ? g` 13810 <tr class="info-tableRow"> 13811 <th class="info-tableCell info-tableCell--Header">${u("Equipo gestor", { desc: "Management team label", id: "fund-description.management-team.label" })}</th> 13812 <td class="info-tableCell">${s.company.name}</td> 13813 </tr> 13814 ` : ""} 13815
13816 ${s.distributionPolicy ? g` 13817 <tr class="info-tableRow"> 13818 <th class="info-tableCell info-tableCell--Header">${u("Pol\xEDtica de distribuci\xF3n", { desc: "Distribution policy label", id: "fund-description.distribution-policy.label" })}</th> 13819 <td class="info-tableCell">${s.distributionPolicy}</td> 13820 </tr> 13821 ` : ""} 13822 </tbody> 13823 </table> 13824 </div> 13825 `; 13826 } 13827 }; 13828 we.styles = K` 13829 ${nt(st.styles)} 13830 13831 :host { 13832 display: block; 13833 container-type: inline-size; 13834 container-name: info-block; 13835 width: 100%; 13836 min-width: 0; 13837 font-family: var(--stock-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 13838 --info-text-color: var(--stock-text-color, #383d43); 13839 --info-text-muted-color: var(--stock-muted-color, #5A6773); 13840 --info-light-gray-bg: var(--stock-light-gray-bg, #f0f0f0); 13841 --info-font-size-basis: var(--stock-font-size-basis, 18px); 13842 --info-font-size-lg-small: 1.278em; /* 23px */ 13843 background: none; 13844 padding: 0; 13845 margin: 0; 13846 box-sizing: border-box; 13847 } 13848 13849 :host *, :host *::before, :host *::after { 13850 box-sizing: border-box; 13851 } 13852 13853 .info-block { 13854 font-size: var(--info-font-size-basis); 13855 color: var(--info-text-color); 13856 } 13857 13858 .info-header { 13859 display: flex; 13860 align-items: center; 13861 margin-bottom: 20px; 13862 padding-bottom: 16px; 13863 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 13864 } 13865 13866 .stock-name { 13867 margin: 0; 13868 font-size: var(--info-font-size-lg-small); 13869 font-weight: 600; 13870 color: var(--info-text-color); 13871 line-height: 1.2; 13872 } 13873 13874 .stock-symbol { 13875 display: inline-block; 13876 margin: 2px 0 0; 13877 font-size: var(--info-font-size-basis); 13878 font-weight: 500; 13879 color: var(--info-text-color); 13880 background-color: var(--info-light-gray-bg); 13881 padding: 2px 8px; 13882 border-radius: 4px; 13883 } 13884 13885 .info-table { 13886 width: 100%; 13887 border-collapse: collapse; 13888 border-spacing: 0; 13889 } 13890 13891 .info-tableCell { 13892 padding: 16px 0 16px 8px; 13893 color: var(--info-text-muted-color); 13894 } 13895 13896 .info-tableCell--Header { 13897 padding-left: 0; 13898 padding-right: 8px; 13899 font-weight: 500; 13900 text-align: left; 13901 color: var(--info-text-color); 13902 } 13903 13904 .info-tableRow { 13905 border-bottom: 1px solid var(--info-text-muted-color); 13906 } 13907 13908 @container info-block (min-width: 600px) { 13909 .info-table > tbody { 13910 display: block; 13911 columns: 2; 13912 column-gap: 24px; 13913 } 13914 13915 .info-tableRow { 13916 display: grid; 13917 grid-template-columns: 1fr 1fr; 13918 break-inside: avoid; 13919 } 13920 .info-tableCell { 13921 padding: 24px 0 24px 8px; 13922 } 13923 } 13924 `; 13925 $i([ 13926 $({ type: String, attribute: "header-level" }) 13927 ], we.prototype, "headerLevel", 2); 13928 $i([ 13929 C() 13930 ], we.prototype, "lastFetchedIsin", 2); 13931 $i([ 13932 C() 13933 ], we.prototype, "fetchInProgress", 2); 13934 we = $i([ 13935 lt(), 13936 it("fund-description") 13937 ], we); 13938 var ec = Object.defineProperty; 13939 var ic = Object.getOwnPropertyDescriptor; 13940 var oe = (s, t, e, i) => { 13941 for (var r = i > 1 ? void 0 : i ? ic(t, e) : t, n = s.length - 1, a; n >= 0; n--) 13942 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 13943 return i && r && ec(t, e, r), r; 13944 }; 13945 var Pt = class extends st { 13946 constructor() { 13947 super(), this.lastFetchedIsin = null, this.fetchInProgress = false, this.fullFundData = [], this.ytdReturn = null, this.fiveYearReturn = null, this.fundDataService = new ae(q.API_BASE_URL); 13948 } 13949 /** 13950 * Renderiza el header del componente 13951 */ 13952 renderHeader() { 13953 if (!this.fundData || !this.showHeader) 13954 return g``; 13955 const { name: s } = this.fundData; 13956 return g` 13957 <div class="fund-header"> 13958 ${Dt(this.headerLevel, "fund-name", s)} 13959 <p class="fund-isin">${u("ISIN:", { desc: "ISIN label", id: "fund-periods-card.isin-label" })} ${this.isin}</p> 13960 </div> 13961 `; 13962 } 13963 fetchData() { 13964 return L(this, null, function* () { 13965 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 13966 this.loading = true, this.error = null, this.fetchInProgress = true; 13967 try { 13968 const s = yield this.fundDataService.fetchFundData({ 13969 isin: this.isin, 13970 timeframe: "max", 13971 // Get all available data 13972 showHeader: false 13973 // We don't need header info 13974 }); 13975 if (this.fullFundData = s.fundData, this.fullFundData.length === 0) { 13976 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 13977 return; 13978 } 13979 const t = q.API_BASE_URL, e = yield R(`${t}/funds/product/${encodeURIComponent(this.isin)}`); 13980 if (e.status === 404) { 13981 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 13982 return; 13983 } 13984 if (!e.ok) 13985 throw new Error(u(A`Error al obtener datos del fondo: ${e.statusText}`, { 13986 desc: "Error message when fund API request fails", 13987 id: "fund-periods-card.api-error" 13988 })); 13989 const i = yield e.json(); 13990 this.processData(i), this.filterAndCalculateReturns(), this.lastFetchedIsin = this.isin; 13991 } catch (s) { 13992 this.error = s instanceof Error ? s.message : u("Error desconocido", { 13993 desc: "Generic error message", 13994 id: "fund-periods-card.error.unknown" 13995 }), console.error(u("Error al obtener datos del fondo:", { 13996 desc: "Console error message prefix", 13997 id: "fund-periods-card.error.console" 13998 }), s); 13999 } finally { 14000 this.loading = false, this.fetchInProgress = false;
14001 } 14002 } 14003 }); 14004 } 14005 // Sobrescribir el método updated para controlar cuando se debe volver a cargar 14006 updated(s) { 14007 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 14008 } 14009 processData(s) { 14010 this.fundData = s; 14011 } 14012 /** 14013 * Filter historic data and calculate returns for different timeframes 14014 */ 14015 filterAndCalculateReturns() { 14016 if (this.fullFundData.length === 0) 14017 return; 14018 const s = mt.filterDataByTimeframe(this.fullFundData, "ytd"); 14019 if (!s.error && s.filteredData.length > 0) { 14020 const e = ht.calculateChange( 14021 s.filteredData, 14022 (i) => i.nav 14023 ); 14024 this.ytdReturn = e ? e.percentageChange : null; 14025 } 14026 const t = mt.filterDataByTimeframe(this.fullFundData, "5y"); 14027 if (!t.error && t.filteredData.length > 0) { 14028 const e = ht.calculateChange( 14029 t.filteredData, 14030 (i) => i.nav 14031 ); 14032 this.fiveYearReturn = e ? e.percentageChange : null; 14033 } 14034 } 14035 renderLoading() { 14036 return g`<div class="loading">${u("Cargando informaci\xF3n del fondo...", { 14037 desc: "Loading message when fetching fund data", 14038 id: "fund-periods-card.loading" 14039 })}</div>`; 14040 } 14041 getNoDataMessage() { 14042 return u("No hay datos del fondo disponibles. Por favor, proporcione un ISIN v\xE1lido.", { 14043 desc: "Message shown when no fund data is available", 14044 id: "fund-periods-card.no-data" 14045 }); 14046 } 14047 formatNumber(s, t = {}) { 14048 return new Intl.NumberFormat(this.locale || void 0, t).format(s); 14049 } 14050 formatPercentage(s) { 14051 return new Intl.NumberFormat(this.locale || void 0, { 14052 style: "percent", 14053 minimumFractionDigits: 2, 14054 maximumFractionDigits: 2 14055 }).format(s / 100); 14056 } 14057 renderContent() { 14058 if (!this.fundData) 14059 return null; 14060 const { currency: s } = this.fundData, t = this.fullFundData.length > 0 ? this.fullFundData[this.fullFundData.length - 1] : null, { value: e, date: i } = Ws(this.fundData.nav, t); 14061 return g` 14062 <div class="info-container"> 14063 ${this.renderHeader()} 14064 14065 <div class="fund-card"> 14066 <div class="nav-container"> 14067 <span class="fund-nav-label">${u("Valor liquidativo", { desc: "NAV label", id: "fund-periods-card.nav-label" })}</span> 14068 <p class="fund-nav"> 14069 ${e !== void 0 ? this.formatNumber(e, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : u("N/A", { desc: "Not available abbreviation", id: "fund-periods-card.not-available" })} 14070 ${s} 14071 </p> 14072 ${i ? g` 14073 <p class="fund-nav-date"> 14074 ${this.formatDate(i)} 14075 </p> 14076 ` : ""} 14077 </div> 14078 14079 ${this.ytdReturn !== null ? g` 14080 <div class="change-item"> 14081 <span class="change-label">${u("YTD", { desc: "Year-to-date return label", id: "fund-periods-card.ytd-label" })}</span> 14082 <span class="change-value ${this.getValueClass(this.ytdReturn)}"> 14083 <svg width="13" height="14" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 14084 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 14085 </svg> 14086 ${this.formatPercentage(this.ytdReturn)} 14087 </span> 14088 </div> 14089 ` : ""} 14090 14091 ${this.fiveYearReturn !== null ? g` 14092 <div class="change-item"> 14093 <span class="change-label">${u("5 a\xF1os", { desc: "5-year return label", id: "fund-periods-card.5y-label" })}</span> 14094 <span class="change-value ${this.getValueClass(this.fiveYearReturn)}"> 14095 <svg width="13" height="14" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 14096 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 14097 </svg> 14098 ${this.formatPercentage(this.fiveYearReturn)} 14099 </span> 14100 </div> 14101 ` : ""} 14102 </div> 14103 </div> 14104 `; 14105 } 14106 // Add the helper method for determining CSS classes 14107 getValueClass(s) { 14108 return s > 0 ? "positive" : s < 0 ? "negative" : ""; 14109 } 14110 }; 14111 Pt.styles = K` 14112 ${nt(st.styles)} 14113 14114 :host { 14115 display: block; 14116 container-type: inline-size; 14117 container-name: fund-periods-card; 14118 font-family: var(--stock-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 14119 --fund-card-bg: rgba(248, 250, 252, 0.6); 14120 --fund-name-color: var(--stock-title-color, #1e293b); 14121 --fund-isin-color: var(--stock-muted-color, #64748b); 14122 --fund-isin-bg: var(--stock-light-gray-bg, rgba(226, 232, 240, 0.7)); 14123 --fund-nav-color: var(--stock-text-color, #0f172a); 14124 --fund-positive-color: var(--stock-success-color, #00856F); 14125 --fund-negative-color: var(--stock-danger-color, #E91101); 14126 --fund-date-color: var(--stock-muted-color, #94a3b8); 14127 --fund-font-size-basis: var(--stock-font-size-basis, 18px); 14128 background: none; 14129 padding: 0; 14130 margin: 0; 14131 box-sizing: border-box; 14132 } 14133 14134 .fund-header { 14135 margin-bottom: 20px; 14136 padding-bottom: 16px; 14137 border-bottom: 1px solid var(--stock-divider-color, rgba(226, 232, 240, 0.8)); 14138 } 14139 14140 .fund-name { 14141 margin: 0; 14142 font-size: 1.556em; /* 28px */ 14143 font-weight: 600; 14144 color: var(--fund-name-color); 14145 line-height: 1.2; 14146 } 14147 14148 .fund-isin { 14149 margin: 2px 0 0; 14150 display: inline-block; 14151 font-size: 0.85rem; 14152 font-weight: 500; 14153 color: var(--fund-isin-color); 14154 background-color: var(--fund-isin-bg); 14155 padding: 2px 8px; 14156 border-radius: 4px; 14157 } 14158 14159 .fund-card { 14160 display: grid; 14161 grid-template-columns: max-content 1fr 1fr; 14162 gap: 16px; 14163 align-items: center; 14164 padding: 1rem; 14165 background-color: var(--fund-card-bg); 14166 border-radius: 12px; 14167 box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); 14168 transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; 14169 margin: 0; 14170 overflow: hidden; 14171 border: none; 14172 box-sizing: border-box; 14173 } 14174 14175 .nav-container { 14176 display: flex; 14177 flex-direction: column; 14178 align-items: flex-start; 14179 gap: 4px; 14180 } 14181 14182 .fund-nav-label { 14183 font-size: 0.75rem; 14184 color: var(--fund-date-color); 14185 font-weight: 500; 14186 } 14187 14188 .fund-nav { 14189 margin: 0; 14190 font-size: 1.2rem; 14191 font-weight: 700; 14192 color: var(--fund-nav-color); 14193 } 14194 14195 .fund-nav-date { 14196 margin: 0; 14197 font-size: 0.75rem; 14198 color: var(--fund-date-color); 14199 font-style: italic; 14200 } 14201 14202 .change-item { 14203 display: flex; 14204 flex-direction: column; 14205 align-items: center; 14206 gap: 4px; 14207 } 14208 14209 .fund-nav-label, 14210 .change-label { 14211 font-size: 0.75rem; 14212 color: var(--fund-date-color); 14213 font-weight: 500; 14214 } 14215 14216 .change-value { 14217 font-size: 0.9rem; 14218 font-weight: 600; 14219 display: flex; 14220 align-items: center; 14221 gap: 4px; 14222 } 14223 14224 .change-value.positive { 14225 color: var(--fund-positive-color); 14226 } 14227 14228 .change-value.negative { 14229 color: var(--fund-negative-color); 14230 } 14231 14232 .change-value.negative svg { 14233 transform: rotate(180deg); 14234 } 14235 14236 @container fund-periods-card (max-width: 400px) { 14237 .fund-card { 14238 grid-template-columns: 1fr 1fr; 14239 grid-template-areas: 14240 "nav nav" 14241 "year three-year"; 14242 text-align: center; 14243 } 14244 14245 .nav-container { 14246 grid-area: nav;
14247 align-self: start; 14248 } 14249 14250 .change-item { 14251 // align-items: center; 14252 } 14253 14254 .change-item:first-of-type { 14255 grid-area: year; 14256 } 14257 14258 .change-item:last-of-type { 14259 grid-area: three-year; 14260 } 14261 } 14262 `; 14263 oe([ 14264 $({ type: String, attribute: "header-level" }) 14265 ], Pt.prototype, "headerLevel", 2); 14266 oe([ 14267 C() 14268 ], Pt.prototype, "lastFetchedIsin", 2); 14269 oe([ 14270 C() 14271 ], Pt.prototype, "fetchInProgress", 2); 14272 oe([ 14273 C() 14274 ], Pt.prototype, "fullFundData", 2); 14275 oe([ 14276 C() 14277 ], Pt.prototype, "ytdReturn", 2); 14278 oe([ 14279 C() 14280 ], Pt.prototype, "fiveYearReturn", 2); 14281 Pt = oe([ 14282 lt(), 14283 it("fund-periods-card") 14284 ], Pt); 14285 var sc = Object.defineProperty; 14286 var rc = Object.getOwnPropertyDescriptor; 14287 var gt = (s, t, e, i) => { 14288 for (var r = i > 1 ? void 0 : i ? rc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 14289 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 14290 return i && r && sc(t, e, r), r; 14291 }; 14292 var dt = class extends st { 14293 constructor() { 14294 super(), this.benchmark = "", this.lastFetchedIsin = null, this.fetchInProgress = false, this.viewMode = "years", this.benchmarkData = null, this.benchmarkName = null, this.lastFetchedBenchmarkSymbol = null, this.fullFundData = [], this.benchmarkHistoricalData = [], this.ytdReturn = null, this.benchmarkFetchInProgress = false, this.fundDataService = new ae(q.API_BASE_URL); 14295 } 14296 fetchData() { 14297 return L(this, null, function* () { 14298 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 14299 this.loading = true, this.error = null, this.fetchInProgress = true; 14300 try { 14301 const s = q.API_BASE_URL, t = `${s}/funds/product/${encodeURIComponent(this.isin)}/statistic`, e = [ 14302 R(t), 14303 R(`${s}/funds/product/${encodeURIComponent(this.isin)}`) 14304 ]; 14305 this.showHeader; 14306 const i = yield Promise.all(e), r = i[0], n = i[1]; 14307 if (r.status === 404 || n.status === 404) { 14308 this.fundData = null, this.error = null, this.lastFetchedIsin = this.isin; 14309 return; 14310 } 14311 if (!r.ok) 14312 throw new Error(u(A`Error al obtener estadÃsticas del fondo: ${r.statusText}`, { 14313 desc: "Error message when statistics API request fails" 14314 })); 14315 if (!n.ok) 14316 throw new Error(u(A`Error al obtener información del producto: ${n.statusText}`, { 14317 desc: "Error message when product API request fails" 14318 })); 14319 const a = yield this.fundDataService.fetchFundData({ 14320 isin: this.isin, 14321 timeframe: "max", 14322 showHeader: false 14323 }).catch(() => ({ fundData: [] })), o = yield r.json(), l = yield n.json(); 14324 this.fullFundData = a.fundData, this.filterAndCalculateReturns(), this.showHeader ? this.processData(G(M({}, o), { 14325 name: l == null ? void 0 : l.name 14326 })) : this.processData(o), this.lastFetchedIsin = this.isin; 14327 } catch (s) { 14328 this.error = s instanceof Error ? s.message : u("Error desconocido", { 14329 desc: "Generic error message", 14330 id: "fund-profitability.error.unknown" 14331 }), this.warnOnSeoFallback(s), console.error(u("Error al obtener estad\xEDsticas del fondo:", { desc: "Console error message prefix" }), s); 14332 } finally { 14333 this.loading = false, this.fetchInProgress = false; 14334 } 14335 } 14336 }); 14337 } 14338 connectedCallback() { 14339 super.connectedCallback(), this.benchmark && this.benchmark.trim() && !this.lastFetchedBenchmarkSymbol && this.fetchBenchmarkData(); 14340 } 14341 firstUpdated(s) { 14342 super.firstUpdated(s), setTimeout(() => { 14343 yt(this); 14344 }, 0); 14345 } 14346 updated(s) { 14347 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(), setTimeout(() => { 14348 yt(this); 14349 }, 0), s.has("benchmark") && (this.benchmark && this.benchmark.trim() && this.benchmark !== this.lastFetchedBenc
14349hmarkSymbol ? (this.benchmarkName = null, this.lastFetchedBenchmarkSymbol = null, this.fetchBenchmarkData()) : (!this.benchmark || !this.benchmark.trim()) && (this.benchmarkData = null, this.benchmarkName = null, this.lastFetchedBenchmarkSymbol = null)); 14350 } 14351 processData(s) { 14352 this.fundData = s; 14353 } 14354 /** 14355 * Override renderHeader to support header-level attribute 14356 */ 14357 renderHeader() { 14358 if (!this.showHeader) 14359 return g``; 14360 if (!this.fundData) 14361 return this.isin ? g` 14362 <div class="info-header"> 14363 <div> 14364 ${Dt(this.headerLevel, "stock-name", this.isin)} 14365 <p class="stock-symbol">${u(A`ISIN: ${this.isin}`, { desc: "ISIN label" })}</p> 14366 </div> 14367 </div> 14368 ` : g``; 14369 const { isin: s } = this.fundData; 14370 let t; 14371 return "name" in this.fundData && (t = this.fundData.name), g` 14372 <div class="info-header"> 14373 <div> 14374 ${Dt(this.headerLevel, "stock-name", t || s)} 14375 <p class="stock-symbol">${u(A`ISIN: ${s}`, { desc: "ISIN label" })}</p> 14376 </div> 14377 </div> 14378 `; 14379 } 14380 /** 14381 * Filter historic data and calculate YTD return for the fund 14382 */ 14383 filterAndCalculateReturns() { 14384 if (this.fullFundData.length === 0) 14385 return; 14386 const s = mt.filterDataByTimeframe(this.fullFundData, "ytd"); 14387 if (!s.error && s.filteredData.length > 0) { 14388 const t = ht.calculateChange( 14389 s.filteredData, 14390 (e) => e.nav 14391 ); 14392 this.ytdReturn = t ? t.percentageChange / 100 : null; 14393 } 14394 } 14395 /** 14396 * Calculates profitability for a given timeframe using historical benchmark data 14397 */ 14398 calculateBenchmarkProfitabilityForTimeframe(s) { 14399 if (!this.benchmarkHistoricalData || this.benchmarkHistoricalData.length === 0) 14400 return; 14401 const t = mt.filterDataByTimeframe( 14402 this.benchmarkHistoricalData.map((i) => ({ date: i.date, nav: i.price })), 14403 s, 14404 false 14405 ); 14406 if (!t.filteredData || t.filteredData.length < 2) 14407 return; 14408 const e = ht.calculateChange( 14409 t.filteredData, 14410 (i) => i.nav 14411 ); 14412 if (e) 14413 return e.percentageChange; 14414 } 14415 /** 14416 * Fetches benchmark historical data and calculates profitability metrics 14417 */ 14418 fetchBenchmarkData() { 14419 return L(this, null, function* () { 14420 if (!this.benchmark || !this.benchmark.trim() || this.benchmarkFetchInProgress) 14421 return; 14422 const s = this.benchmark.trim(); 14423 if (!(this.lastFetchedBenchmarkSymbol === s && this.benchmarkData)) { 14424 this.benchmarkFetchInProgress = true; 14425 try { 14426 const t = q.API_BASE_URL, e = encodeURIComponent(s); 14427 try { 14428 const S = yield R(`${t}/asset-data/quote?symbol=${e}`); 14429 if (S.ok) { 14430 const w = yield S.json(); 14431 this.benchmarkName = (w == null ? void 0 : w.name) || s; 14432 } else 14433 this.benchmarkName = s; 14434 } catch (S) { 14435 this.benchmarkName = s; 14436 } 14437 const i = /* @__PURE__ */ new Date(), r = new Date(i); 14438 r.setFullYear(i.getFullYear() - 10); 14439 const n = r.toISOString().split("T")[0], a = i.toISOString().split("T")[0], o = yield R( 14440 `${t}/asset-data/basic-stock-chart?symbol=${e}&from_date=${n}&to_date=${a}` 14441 ); 14442 if (!o.ok) { 14443 this.benchmarkData = null, this.lastFetchedBenchmarkSymbol = null; 14444 return; 14445 } 14446 const l = yield o.json(); 14447 if (!l || l.length === 0) { 14448 this.benchmarkData = null, this.lastFetchedBenchmarkSymbol = null; 14449 return; 14450 } 14451 const h = l.sort( 14452 (S, w) => new Date(S.date).getTime() - new Date(w.date).getTime() 14453 ); 14454 this.benchmarkHistoricalData = h; 14455 const c = this.calculateBenchmarkProfitabilityForTimeframe("ytd"), d = this.calculateBenchmarkProfitabilityForTimeframe("1y"), f = this.calculateBenchmarkProfitabilityForTimeframe("2y"), m = this.calculateBenchmarkProfitabilityForTimeframe("3y"), p = this.calculateBenchmarkProfitabilityForTimeframe("4y"), v = this.calculateBenchmarkProfitabilityForTimeframe("1y"), b = this.calculateBenchmarkProfitabilityForTimeframe("3y"), y = this.calculateBenchmarkProfitabilityForTimeframe("5y"), x = this.calculateBenchmarkProfitabilityForTimeframe("10y"); 14456 this.benchmarkData = { 14457 name: this.benchmarkName || void 0, 14458 stats: { 14459 returnYtd: c !== void 0 ? c / 100 : void 0, 14460 returnLast1y: d !== void 0 ? d / 100 : void 0, 14461 returnLast2y: f !== void 0 ? f / 100 : void 0, 14462 returnLast3y: m !== void 0 ? m / 100 : void 0, 14463 returnLast4y: p !== void 0 ? p / 100 : void 0, 14464 return1y: v !== void 0 ? v / 100 : void 0, 14465 return3y: b !== void 0 ? b / 100 : void 0, 14466 return5y: y !== void 0 ? y / 100 : void 0, 14467 return10y: x !== void 0 ? x / 100 : void 0 14468 } 14469 }
14469, this.lastFetchedBenchmarkSymbol = s, this.requestUpdate(); 14470 } catch (t) { 14471 this.benchmarkData = null, this.lastFetchedBenchmarkSymbol = null; 14472 } finally { 14473 this.benchmarkFetchInProgress = false; 14474 } 14475 } 14476 }); 14477 } 14478 renderLoading() { 14479 return g`<div class="loading">${u("Cargando datos de rentabilidad...", { 14480 desc: "Loading message when fetching fund profitability data" 14481 })}</div>`; 14482 } 14483 getValueClass(s) { 14484 return s == null ? "neutral" : s > 0 ? "positive" : s < 0 ? "negative" : "neutral"; 14485 } 14486 switchViewMode(s) { 14487 this.viewMode = s; 14488 } 14489 renderYearsView() { 14490 var o, l; 14491 const s = (o = this.fundData) == null ? void 0 : o.stats; 14492 if (!s) 14493 return g``; 14494 const t = (/* @__PURE__ */ new Date()).getFullYear(), e = { 14495 year: "YTD", 14496 hasData: this.ytdReturn !== null, 14497 value: this.ytdReturn 14498 }, i = [ 14499 { year: t - 1, hasData: s.returnLast1y !== void 0, value: s.returnLast1y }, 14500 { year: t - 2, hasData: s.returnLast2y !== void 0, value: s.returnLast2y }, 14501 { year: t - 3, hasData: s.returnLast3y !== void 0, value: s.returnLast3y }, 14502 { year: t - 4, hasData: s.returnLast4y !== void 0, value: s.returnLast4y } 14503 ].filter((h) => h.hasData), r = [e, ...i], n = this.benchmarkData !== null, a = (l = this.benchmarkData) == null ? void 0 : l.stats; 14504 return g` 14505 <div class="table-container horizontal-scroll-element"> 14506 <div class="horizontal-scroll-element-inner"> 14507 <table class="profitability-table"> 14508 <thead class="table-header"> 14509 <tr> 14510 <th></th> 14511 ${r.map((h) => g`<th>${h.year}</th>`)} 14512 </tr> 14513 </thead> 14514 <tbody> 14515 <tr class="table-row"> 14516 <td class="table-cell">Fondo</td> 14517 ${r.map((h) => g` 14518 <td class="table-cell ${h.hasData ? this.getValueClass(h.value) : "neutral"}"> 14519 ${h.hasData ? this.formatPercentage(h.value) : "-"} 14520 </td> 14521 `)} 14522 </tr> 14523 ${n ? g` 14524 <tr class="table-row"> 14525 <td class="table-cell"> 14526 <div>${this.benchmarkName || this.benchmark}</div> 14527 <div class="benchmark-label">(Benchmark)</div> 14528 </td> 14529 ${r.map((h) => { 14530 let c; 14531 if (h.year === "YTD") 14532 c = a == null ? void 0 : a.returnYtd; 14533 else if (typeof h.year == "number") { 14534 const f = (/* @__PURE__ */ new Date()).getFullYear() - h.year; 14535 f === 1 ? c = a == null ? void 0 : a.returnLast1y : f === 2 ? c = a == null ? void 0 : a.returnLast2y : f === 3 ? c = a == null ? void 0 : a.returnLast3y : f === 4 && (c = a == null ? void 0 : a.returnLast4y); 14536 } 14537 return g` 14538 <td class="table-cell neutral"> 14539 ${c != null ? this.formatPercentage(c) : "-"} 14540 </td> 14541 `; 14542 })} 14543 </tr> 14544 ` : ""} 14545 </tbody> 14546 </table> 14547 </div> 14548 </div> 14549 `; 14550 } 14551 renderAccumulatedView() { 14552 var r, n; 14553 const s = (r = this.fundData) == null ? void 0 : r.stats; 14554 if (!s) 14555 return g``; 14556 const t = [ 14557 { key: "return1y", label: "1 a\xF1o" }, 14558 { key: "return3y", label: "3 a\xF1os" }, 14559 { key: "return5y", label: "5 a\xF1os" }, 14560 { key: "return10y", label: "10 a\xF1os" } 14561 ].filter((a) => s[a.key] !== void 0), e = this.benchmarkData !== null, i = (n = this.benchmarkData) == null ? void 0 : n.stats; 14562 return g` 14563 <div class="table-container horizontal-scroll-element"> 14564 <div class="horizontal-scroll-element-inner"> 14565 <table class="profitability-table"> 14566 <thead class="table-header"> 14567 <tr> 14568 <th></th> 14569 ${t.map((a) => g`<th>${a.label}</th>`)} 14570 </tr> 14571 </thead> 14572 <tbody> 14573 <tr class="table-row"> 14574 <td class="table-cell">Fondo</td> 14575 ${t.map((a) => { 14576 const o = s[a.key], l = a.key.replace("return", ""), h = o !== void 0 ? qt(o, l) : void 0; 14577 return g` 14578 <td class="table-cell ${h !== void 0 ? this.getValueClass(h) : "neutral"}"> 14579 ${h !== void 0 ? this.formatPercentage(h) : "-"} 14580 </td> 14581 `; 14582 })} 14583 </tr> 14584 ${e ? g` 14585 <tr class="table-row"> 14586 <td class="table-cell"> 14587 <div>${this.benchmarkName || this.benchmark}</div> 14588 <div class="benchmark-label">(Benchmark)</div> 14589 </td> 14590 ${t.map((a) => { 14591 const o = i == null ? void 0 : i[a.key], l = a.key.replace("return", ""), h = o !== void 0 ? qt(o, l) : void 0; 14592 return g` 14593 <td class="table-cell neutral"> 14594 ${h != null ? this.formatPercentage(h) : "-"} 14595 </td> 14596 `; 14597 })} 14598 </tr> 14599 ` : ""} 14600 </tbody> 14601 </table> 14602 </div> 14603 </div> 14604 `; 14605 } 14606 renderContent() { 14607 if (!this.fundData) 14608 return null; 14609 const s = this.fullFundData.length > 0 ? this.fullFundData[this.fullFundData.length - 1].date : (/* @__PURE__ */ new Date()).toISOString(); 14610 return g` 14611 <div class="profitability-container"> 14612 ${this.renderHeader()} 14613 14614 <div class="view-toggle"> 14615 <button 14616 class="tab-button ${this.viewMode === "years" ? "active" : ""}" 14617 @click="${() => this.switchViewMode("years")}" 14618 > 14619 ${u("Por a\xF1os", { desc: "By years toggle button" })} 14620 </button> 14621 <button 14622 class="tab-button ${this.viewMode === "accumulated" ? "active" : ""}" 14623 @click="${() => this.switchViewMode("accumulated")}" 14624 > 14625 ${u("Acumulado", { desc: "Accumulated toggle button" })} 14626 </button> 14627 </div> 14628 14629 ${this.viewMode === "years" ? this.renderYearsView() : this.renderAccumulatedView()} 14630 14631 <div class="info-disclaimer"> 14632 <div class="info-icon">i</div> 14633 <div> 14634 <div class="disclaimer-text"> 14635 ${u("Rentabilidades pasadas no garantizan resultados futuros. Rentabilidades anualizadas para periodos superiores a 1 a\xF1o.", { 14636 id: "disclaimer.past-returns", 14637 desc: "Past returns disclaimer text" 14638 })} 14639 </div> 14640 <div class="update-date"> 14641 ${u("Datos actualizados a", { id: "disclaimer.data-updated", desc: "Data updated to text" })} ${this.formatDate(s)} 14642 </div> 14643 </div> 14644 </div> 14645 </div> 14646 `; 14647 } 14648 }; 14649 dt.styles = K` 14650 ${nt(st.styles)} 14651 ${nt(We)} 14652 ${_i} 14653 14654 .profitability-container { 14655 width: 100%; 14656 display: block; 14657 } 14658 14659 .profitability-header { 14660 display: flex; 14661 justify-content: space-between; 14662 align-items: center; 14663 margin-bottom: 20px; 14664 } 14665 14666 .view-toggle { 14667 display: flex; 14668 gap: 8px; 14669 } 14670 14671 .profitability-table { 14672 width: 100%; 14673 border-collapse: collapse; 14674 margin-bottom: 20px; 14675 table-layout: auto; /* Allow flexible column sizing */ 14676 } 14677 14678 .table-container { 14679 width: 100%; 14680 margin-top: 32px; 14681 } 14682 14683 .profitability-table { 14684 min-width: 600px; 14685 } 14686 14687 .horizontal-scroll-element-inner { 14688 display: block; 14689 } 14690 14691 .table-container.horizontal-scroll-element.initiated{ 14692 width: 100%; 14693 max-width: 100%; 14694 margin-left: 0; 14695 margin-right: 0; 14696 } 14697 14698 .table-container.horizontal-scroll-element.initiated::before { 14699 display: none; 14700 } 14701 14702 .table-container.horizontal-scroll-element.initiated .horizontal-scroll-element-inner { 14703 padding-left: 0; 14704 padding-right: 0; 14705 } 14706 14707 .table-header { 14708 background: none; 14709 border-bottom: 2px solid var(--stock-danger-color, #E91101); 14710 } 14711 14712 .table-header th { 14713 padding: 12px 8px; 14714 text-align: left; 14715 font-size: var(--stock-text-size, 14px); 14716 font-weight: var(--stock-title-weight, 700); 14717 color: var(--stock-text-color, #383d43); 14718 } 14719 14720 .table-header th:first-child { 14721 width: auto; 14722 } 14723 14724 .table-header th:not(:first-child) { 14725 min-width: 88px; /* Consistent minimum width for data columns */ 14726 width: auto; /* Let browser distribute remaining space */ 14727 text-align: right; 14728 } 14729 14730 .table-row { 14731 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 14732 } 14733 14734 .table-row:last-child { 14735 border-bottom: none; 14736 } 14737 14738 .table-cell { 14739 min-width: 88px; 14740 padding: 12px 8px; 14741 font-size: var(--stock-text-size, 14px);
14742 font-weight: var(--stock-value-weight, 500); 14743 } 14744 14745 .table-cell:first-child { 14746 font-weight: var(--stock-title-weight, 600); 14747 color: var(--stock-text-color, #383d43); 14748 } 14749 14750 .table-cell:not(:first-child) { 14751 text-align: right; 14752 } 14753 14754 .table-cell.positive { 14755 color: var(--stock-positive-color, #00856F); 14756 } 14757 14758 .table-cell.negative { 14759 color: var(--stock-negative-color, #E91101); 14760 } 14761 14762 .table-cell.neutral { 14763 color: var(--stock-text-color, #383d43); 14764 } 14765 14766 .benchmark-label { 14767 font-size: 12px; 14768 color: var(--stock-muted-color, #64748b); 14769 font-weight: normal; 14770 margin-top: 2px; 14771 } 14772 14773 .info-disclaimer { 14774 display: flex; 14775 align-items: flex-start; 14776 gap: 8px; 14777 margin-top: 20px; 14778 } 14779 14780 .info-icon { 14781 width: 16px; 14782 height: 16px; 14783 color: var(--stock-accent-color, #58A8DA); 14784 border-radius: 50%; 14785 display: flex; 14786 align-items: center; 14787 justify-content: center; 14788 font-size: 12px; 14789 font-weight: bold; 14790 flex-shrink: 0; 14791 margin-top: 2px; 14792 border: 1px solid var(--stock-accent-color, #58A8DA); 14793 } 14794 14795 .disclaimer-text { 14796 font-size: var(--stock-small-text-size, 14px); 14797 color: var(--stock-muted-color, #383D43); 14798 line-height: 1.4; 14799 } 14800 14801 .update-date { 14802 font-size: var(--stock-small-text-size, 14px); 14803 color: var(--stock-muted-color, #383D43); 14804 margin-top: 4px; 14805 } 14806 14807 @media (max-width: 768px) { 14808 .profitability-header { 14809 flex-direction: column; 14810 align-items: flex-start; 14811 gap: 16px; 14812 } 14813 14814 .view-toggle { 14815 width: 100%; 14816 justify-content: center; 14817 } 14818 14819 .tab-button { 14820 flex: 1; 14821 text-align: center; 14822 } 14823 14824 .profitability-table { 14825 font-size: 12px; 14826 table-layout: auto; /* Flexible layout for variable columns */ 14827 } 14828 14829 .table-header th, 14830 .table-cell { 14831 padding: 8px; 14832 white-space: nowrap; /* Prevent text wrapping in cells */ 14833 } 14834 14835 .table-header th:first-child, 14836 .table-cell:first-child { 14837 position: sticky; 14838 left: 0; 14839 background: var(--stock-white-color, #ffffff); 14840 z-index: 1; 14841 border-right: 1px solid var(--stock-border-color, #e0e0e0); 14842 } 14843 } 14844 `; 14845 gt([ 14846 $({ type: String }) 14847 ], dt.prototype, "benchmark", 2); 14848 gt([ 14849 $({ type: String, attribute: "header-level" }) 14850 ], dt.prototype, "headerLevel", 2); 14851 gt([ 14852 C() 14853 ], dt.prototype, "lastFetchedIsin", 2); 14854 gt([ 14855 C() 14856 ], dt.prototype, "fetchInProgress", 2); 14857 gt([ 14858 C() 14859 ], dt.prototype, "viewMode", 2); 14860 gt([ 14861 C() 14862 ], dt.prototype, "benchmarkData", 2); 14863 gt([ 14864 C() 14865 ], dt.prototype, "benchmarkName", 2); 14866 gt([ 14867 C() 14868 ], dt.prototype, "lastFetchedBenchmarkSymbol", 2); 14869 gt([ 14870 C() 14871 ], dt.prototype, "fullFundData", 2); 14872 gt([ 14873 C() 14874 ], dt.prototype, "benchmarkHistoricalData", 2); 14875 gt([ 14876 C() 14877 ], dt.prototype, "ytdReturn", 2); 14878 dt = gt([ 14879 lt(), 14880 it("fund-profitability") 14881 ], dt); 14882 var nc = Object.defineProperty; 14883 var ac = Object.getOwnPropertyDescriptor; 14884 var vt = (s, t, e, i) => { 14885 for (var r = i > 1 ? void 0 : i ? ac(t, e) : t, n = s.length - 1, a; n >= 0; n--) 14886 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 14887 return i && r && nc(t, e, r), r; 14888 }; 14889 var ut = class extends st { 14890 constructor() { 14891 super(), this.isin = "", this.locale = "", this.lastFetchedIsin = null, this.fetchInProgress = false, this.fullFundData = [], this.ytdReturn = null, this.fiveYearReturn = null, this.threeYearReturn = null, this.fundDataService = new ae(q.API_BASE_URL); 14892 } 14893 /** 14894 * Datos del fondo (alias para mantener compatibilidad) 14895 */ 14896 get fundData() { 14897 return this.data; 14898 } 14899 set fundData(s) { 14900 this.data = s; 14901 } 14902 /** 14903 * Verifica si se debe obtener los datos 14904 */ 14905 shouldFetchData() { 14906 return !!this.isin; 14907 } 14908 /** 14909 * Verifica si una propiedad clave ha cambiado 14910 */ 14911 hasKeyPropertyChanged(s) { 14912 return s.has("isin") && !!this.isin; 14913 } 14914 /** 14915 * Este componente no usa header 14916 */ 14917 renderHeader() { 14918 return g``; 14919 } 14920 fetchData() { 14921 return L(this, null, function* () { 14922 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 14923 this.loading = true, this.error = null, this.fetchInProgress = true; 14924 try { 14925 const s = yield this.fundDataService.fetchFundData({ 14926 isin: this.isin, 14927 timeframe: "max", 14928 // Get all available data 14929 showHeader: false 14930 // We don't need header info 14931 }); 14932 if (this.fullFundData = s.fundData, this.fullFundData.length === 0) { 14933 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 14934 return; 14935 } 14936 const t = q.API_BASE_URL, e = yield R(`${t}/funds/product/${encodeURIComponent(this.isin)}`); 14937 if (e.status === 404) { 14938 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 14939 return; 14940 } 14941 if (!e.ok) 14942 throw new Error(u(A`Error al obtener datos del fondo: ${e.statusText}`, { 14943 desc: "Error message when fund API request fails", 14944 id: "fund-quote-card.api-error" 14945 })); 14946 const i = yield e.json(); 14947 this.processData(i), this.filterAndCalculateReturns(), this.lastFetchedIsin = this.isin; 14948 } catch (s) { 14949 this.error = s instanceof Error ? s.message : u("Error desconocido", { 14950 desc: "Generic error message", 14951 id: "fund-quote-card.error.unknown" 14952 }), this.warnOnSeoFallback(s), console.error(u("Error al obtener datos del fondo:", { 14953 desc: "Console error message prefix", 14954 id: "fund-quote-card.error.console" 14955 }), s); 14956 } finally { 14957 this.loading = false, this.fetchInProgress = false;
14958 } 14959 } 14960 }); 14961 } 14962 // Sobrescribir el método updated para controlar cuando se debe volver a cargar 14963 updated(s) { 14964 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 14965 } 14966 processData(s) { 14967 this.fundData = s; 14968 } 14969 /** 14970 * Filter historic data and calculate returns for different timeframes 14971 */ 14972 filterAndCalculateReturns() { 14973 if (this.fullFundData.length === 0) 14974 return; 14975 const s = mt.filterDataByTimeframe(this.fullFundData, "ytd"); 14976 if (!s.error && s.filteredData.length > 0) { 14977 const i = ht.calculateChange( 14978 s.filteredData, 14979 (r) => r.nav 14980 ); 14981 this.ytdReturn = i ? i.percentageChange : null; 14982 } 14983 const t = mt.filterDataByTimeframe(this.fullFundData, "5y"); 14984 if (!t.error && t.filteredData.length > 0) { 14985 const i = ht.calculateChange( 14986 t.filteredData, 14987 (r) => r.nav 14988 ); 14989 this.fiveYearReturn = i ? i.percentageChange : null; 14990 } 14991 const e = mt.filterDataByTimeframe(this.fullFundData, "3y"); 14992 if (!e.error && e.filteredData.length > 0) { 14993 const i = ht.calculateChange( 14994 e.filteredData, 14995 (r) => r.nav 14996 ); 14997 this.threeYearReturn = i ? i.percentageChange : null; 14998 } 14999 } 15000 renderLoading() { 15001 return g`<div class="loading">${u("Cargando informaci\xF3n del fondo...", { 15002 desc: "Loading message when fetching fund data", 15003 id: "fund-quote-card.loading" 15004 })}</div>`; 15005 } 15006 getNoDataMessage() { 15007 return u("No hay datos del fondo disponibles. Por favor, proporcione un ISIN v\xE1lido.", { 15008 desc: "Message shown when no fund data is available", 15009 id: "fund-quote-card.no-data" 15010 }); 15011 } 15012 /** 15013 * Renderiza el componente cuando no hay datos. 15014 * Proyecta el SSR fallback de `.rnk-SeoStaticData` si el host lo trae; si no, 15015 * usa renderNoDataBlock para un estado vacÃo consistente. 15016 */ 15017 renderNoData() { 15018 const s = this.renderSeoStaticFallback(); 15019 return s !== null ? s : g` 15020 ${Ye()} 15021 `; 15022 } 15023 formatNumber(s, t = {}) { 15024 return new Intl.NumberFormat(this.locale || void 0, t).format(s); 15025 } 15026 formatPercentage(s) { 15027 return new Intl.NumberFormat(this.locale || void 0, { 15028 style: "percent", 15029 minimumFractionDigits: 2, 15030 maximumFractionDigits: 2 15031 }).format(s / 100); 15032 } 15033 formatDate(s) { 15034 if (!s) 15035 return ""; 15036 const t = new Date(s); 15037 return new Intl.DateTimeFormat(this.locale || void 0, { 15038 day: "2-digit", 15039 month: "2-digit", 15040 year: "2-digit", 15041 hour: "2-digit", 15042 minute: "2-digit", 15043 timeZoneName: "short" 15044 }).format(t); 15045 } 15046 /** 15047 * Helper method to determine CSS classes for performance values 15048 */ 15049 getValueClass(s) { 15050 return s > 0 ? "positive" : s < 0 ? "negative" : ""; 15051 } 15052 /** 15053 * Build Schema.org InvestmentFund structured data 15054 */ 15055 buildInvestmentFundSchema() { 15056 var t, e, i, r; 15057 if (this.schema !== "InvestmentFund" || !this.fundData) 15058 return null; 15059 const s = { 15060 "@context": "https://schema.org", 15061 "@type": "InvestmentFund", 15062 name: this.fundData.name, 15063 identifier: this.isin 15064 }; 15065 return (i = (e = (t = this.fundData.fund) == null ? void 0 : t.investmentObjective) == null ? void 0 : e[0]) != null && i.text && (s.description = this.fundData.fund.investmentObjective[0].text), this.profileUrl && (s.mainEntityOfPage = { 15066 "@type": "WebPage", 15067 "@id": this.profileUrl 15068 }), (r = this.fundData.company) != null && r.name && (s.brand = { 15069 "@type": "Organization", 15070 name: this.fundData.company.name 15071 }), s; 15072 } 15073 /** 15074 * Insert Schema.org JSON-LD into document head 15075 */ 15076 insertSchemaInDOM() { 15077 if (!this.schema || !this.isin) 15078 return; 15079 const s = this.buildInvestmentFundSchema(); 15080 if (!s) 15081 return; 15082 const t = document.querySelector( 15083 `script[type="application/ld+json"][data-fund-schema="${this.isin}"]` 15084 ); 15085 t && t.remove(); 15086 const e = document.createElement("script"); 15087 e.type = "application/ld+json", e.setAttribute("data-fund-schema", this.isin), e.textContent = JSON.stringify(s, null, 2), document.head.appendChild(e); 15088 } 15089 /** 15090 * Clean up schema from DOM when component is disconnected 15091 */ 15092 disconnectedCallback() { 15093 if (super.disconnectedCallback(), this.schema && this.isin) { 15094 const s = document.querySelector( 15095 `script[type="application/ld+json"][data-fund-schema="${this.isin}"]` 15096 ); 15097 s && s.remove(); 15098 } 15099 } 15100 /**
15101 * Renders the fund name with a dynamic HTML tag based on the header-level attribute 15102 * @param name - the fund name to display 15103 * @returns Lit template with the appropriate heading tag 15104 */ 15105 renderFundName(s) { 15106 const t = qs(Vs(this.headerLevel)); 15107 return Us`<${t} class="fund-name">${s}</${t}>`; 15108 } 15109 renderContent() { 15110 if (!this.fundData) 15111 return null; 15112 this.insertSchemaInDOM(); 15113 const { name: s, currency: t, company: e, mainCategory: i } = this.fundData, r = this.fullFundData.length > 0 ? this.fullFundData[this.fullFundData.length - 1] : null, { value: n, date: a } = Ws(this.fundData.nav, r); 15114 return g` 15115 <div class="quote-card"> 15116 <div class="quote-card-header"> 15117 <!--<div class="fund-image-container"> 15118 <div class="fund-image-placeholder"></div> 15119 </div>--> 15120 15121 <div class="name-container"> 15122 ${this.renderFundName(s)} 15123 <p class="fund-symbol-container"> 15124 <span class="fund-symbol">${u("ISIN:", { desc: "ISIN label", id: "fund-periods-card.isin-label" })} ${this.isin}</span> 15125 ${e != null && e.name ? g`· ${e.name}` : ""} 15126 </p> 15127 ${i != null && i.name ? g` 15128 <div class="fund-category">${i.name}</div> 15129 ` : ""} 15130 </div> 15131 </div> 15132 15133 <div class="quote-card-body"> 15134 ${a ? g` 15135 <p class="fund-nav-label"> 15136 ${u("Valor liquidativo actual", { desc: "Current net asset value label", id: "fund-quote-card.nav-current-label" })} (${u("Act.:", { desc: "Updated timestamp label" })} ${this.formatDate(a)}) 15137 </p> 15138 ` : ""} 15139 15140 <div class="price-container"> 15141 <p class="fund-price"> 15142 <span class="fund-price-number">${n !== void 0 ? this.formatNumber(n, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : u("N/A", { desc: "Not available abbreviation", id: "fund-quote-card.not-available" })}</span> <span class="fund-price-currency">${t}</span> 15143 </p> 15144 </div> 15145 15146 <div class="returns-container"> 15147 ${this.ytdReturn !== null ? g` 15148 <div class="fund-return-block ${this.getValueClass(this.ytdReturn)}"> 15149 <span class="return-label">${u("Rentab. YTD", { desc: "Year-to-date return label", id: "fund-quote-card.ytd-label" })}</span> 15150 <div class="return-content"> 15151 <svg class="return-icon" width="12" height="12" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 15152 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 15153 </svg> 15154 <span class="return-value">${this.formatPercentage(this.ytdReturn)}</span> 15155 </div> 15156 </div> 15157 ` : ""} 15158 15159 ${this.fiveYearReturn !== null ? g` 15160 <div class="fund-return-block ${this.getValueClass(this.fiveYearReturn)}"> 15161 <span class="return-label">${u("Rentab. 5 a\xF1os", { desc: "5-year return label", id: "fund-quote-card.5y-label" })}</span> 15162 <div class="return-content"> 15163 <svg class="return-icon" width="12" height="12" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 15164 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 15165 </svg> 15166 <span class="return-value">${this.formatPercentage(this.fiveYearReturn)}</span> 15167 </div> 15168 </div> 15169 ` : this.threeYearReturn !== null ? g` 15170 <div class="fund-return-block ${this.getValueClass(this.threeYearReturn)}"> 15171 <span class="return-label">${u("Rentab. 3 a\xF1os", { desc: "3-year return label", id: "fund-quote-card.3y-label" })}</span> 15172 <div class="return-content"> 15173 <svg class="return-icon" width="12" height="12" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 15174 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 15175 </svg>
15176 <span class="return-value">${this.formatPercentage(this.threeYearReturn)}</span> 15177 </div> 15178 </div> 15179 ` : g` 15180 <div class="fund-return-block neutral"> 15181 <span class="return-label">${u("Rentab. 3 a\xF1os", { desc: "3-year return label", id: "fund-quote-card.3y-label" })}</span> 15182 <div class="return-content"> 15183 <span class="return-value">-</span> 15184 </div> 15185 </div> 15186 `} 15187 </div> 15188 </div> 15189 </div> 15190 `; 15191 } 15192 }; 15193 ut.styles = K` 15194 ${nt(Qe)} 15195 :host { 15196 display: block; 15197 container-type: inline-size; 15198 container-name: quote-card; 15199 width: 100%; 15200 min-width: 0; 15201 font-family: var(--fund-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 15202 --quote-placeholder-bg: #e2e8f0; 15203 --quote-text-color: var(--fund-text-color, #383d43); 15204 --quote-light-gray-bg: var(--fund-light-gray-bg, #f0f0f0); 15205 --quote-price-color: var(--fund-text-color, #383d43); 15206 --quote-positive-color: var(--fund-success-color, #00856F); 15207 --quote-positive-bg: var(--fund-success-bg, rgba(0, 133, 111, 0.15)); 15208 --quote-negative-color: var(--fund-danger-color, #E91101); 15209 --quote-negative-bg: var(--fund-danger-bg, rgba(233, 17, 1, 0.15)); 15210 --quote-timestamp-color: var(--fund-muted-color, #5A6773); 15211 --quote-font-size-basis: var(--fund-font-size-basis, 18px); 15212 --quote-font-size-xl: 1.944em; /* 35px */ 15213 --quote-font-size-xl-small: 1.444em; /* 26px */ 15214 --quote-font-size-lg: 1.556em; /* 28px */ 15215 --quote-font-size-lg-small: 1.278em; /* 23px */ 15216 --quote-font-size-md: 1.167em; /* 21px */ 15217 --quote-font-size-md-small: 0.889em; /* 16px */ 15218 --quote-font-size-sm: 0.778em; /* 14px */ 15219 background: none; 15220 padding: 0; 15221 margin: 0; 15222 box-sizing: border-box; 15223 } 15224 15225 .quote-card { 15226 display: grid; 15227 gap: 16px; 15228 align-items: center; 15229 margin: 0; 15230 width: 100%; 15231 min-width: 0; 15232 font-size: var(--quote-font-size-basis); 15233 border: none; 15234 box-sizing: border-box; 15235 color: var(--quote-text-color); 15236 } 15237 15238 .quote-card-header { 15239 display: flex; 15240 align-items: center; 15241 gap: 16px; 15242 } 15243 15244 .fund-image-container { 15245 display: flex; 15246 align-items: center; 15247 justify-content: center; 15248 } 15249 15250 .fund-image-placeholder { 15251 width: 72px; 15252 height: 72px; 15253 border-radius: 8px; 15254 background-color: var(--quote-placeholder-bg); 15255 display: flex; 15256 align-items: center; 15257 justify-content: center; 15258 } 15259 15260 .name-container { 15261 padding-right: 8px; 15262 } 15263 15264 .fund-name { 15265 margin: 0; 15266 font-size: var(--quote-font-size-lg-small); 15267 font-weight: 600; 15268 color: var(--quote-text-color); 15269 line-height: 1.2; 15270 } 15271 15272 .fund-symbol-container { 15273 margin-bottom: 0; 15274 } 15275 15276 .fund-symbol { 15277 margin: 2px 0 0; 15278 display: inline-block; 15279 font-size: var(--quote-font-size-basis); 15280 font-weight: 500; 15281 color: var(--quote-text-color); 15282 } 15283 15284 .fund-category { 15285 margin: 4px 0 0; 15286 display: inline-block; 15287 font-size: var(--quote-font-size-sm); 15288 font-weight: 500; 15289 color: var(--quote-timestamp-color); 15290 background-color: var(--quote-light-gray-bg); 15291 padding: 2px 8px; 15292 border-radius: 4px; 15293 } 15294 15295 .fund-nav-label { 15296 margin: 0 0 8px 0; 15297 font-size: var(--quote-font-size-sm); 15298 color: var(--quote-timestamp-color); 15299 font-weight: 500; 15300 } 15301 15302 .price-container { 15303 display: flex; 15304 flex-wrap: wrap; 15305 flex-direction: column; 15306 gap: 16px; 15307 margin-bottom: 16px; 15308 } 15309 15310 .fund-price { 15311 margin: 0; 15312 font-weight: 700; 15313 color: var(--quote-price-color); 15314 } 15315 15316 .fund-price-number { 15317 font-size: var(--quote-font-size-xl-small); 15318 } 15319 15320 .fund-price-currency { 15321 font-size: var(--quote-font-size-md-small); 15322 } 15323 15324 .returns-container { 15325 display: flex; 15326 gap: 12px; 15327 flex-wrap: wrap; 15328 } 15329 15330 .fund-return-block { 15331 padding: 8px 12px; 15332 border-radius: 6px; 15333 display: flex; 15334 flex-direction: column; 15335 align-items: center; 15336 gap: 4px; 15337 min-width: 100px; 15338 } 15339 15340 .fund-return-block.positive { 15341 color: var(--quote-positive-color); 15342 background-color: var(--quote-positive-bg); 15343 } 15344 15345 .fund-return-block.negative { 15346 color: var(--quote-negative-color); 15347 background-color: var(--quote-negative-bg); 15348 } 15349 15350 .fund-return-block.negative .return-icon { 15351 transform: rotate(180deg); 15352 } 15353 15354 .fund-return-block.neutral { 15355 color: var(--quote-timestamp-color); 15356 background-color: var(--quote-light-gray-bg); 15357 } 15358 15359 .return-label { 15360 font-size: var(--quote-font-size-sm); 15361 font-weight: 500; 15362 text-align: center; 15363 } 15364 15365 .return-content { 15366 display: flex; 15367 align-items: center; 15368 gap: 4px; 15369 } 15370 15371 .return-icon { 15372 width: 12px; 15373 height: 12px; 15374 } 15375 15376 .return-value { 15377 font-weight: 600; 15378 font-size: var(--quote-font-size-sm); 15379 } 15380 15381 .fund-timestamp { 15382 display: flex; 15383 flex-direction: column; 15384 align-items: flex-start; 15385 gap: 8px; 15386 margin: 0; 15387 font-size: var(--quote-font-size-sm); 15388 color: var(--quote-timestamp-color); 15389 } 15390 15391 /* Hide fund data elements on mobile (screens smaller than 600px) */ 15392 @media (max-width: 599px) { 15393 .fund-nav-label, 15394 .price-container, 15395 .returns-container { 15396 display: none; 15397 } 15398 } 15399 15400 @container quote-card (min-width: 600px) { 15401 .quote-card { 15402 grid-template-columns: auto 1fr auto; 15403 grid-template-areas: "header bar body"; 15404 gap: 30px; 15405 } 15406 15407 .quote-card::before { 15408 content: ''; 15409 display: block; 15410 grid-area: bar; 15411 margin: 0 auto; 15412 width: 1px; 15413 height: 29px; 15414 background-color: var(--quote-text-color); 15415 } 15416 15417 .quote-card-header { 15418 grid-area: header; 15419 } 15420 15421 .quote-card-body { 15422 grid-area: body; 15423 } 15424 15425 .fund-image-placeholder { 15426 width: 104px; 15427 height: 104px; 15428 } 15429 15430 .fund-name { 15431 font-size: var(--quote-font-size-lg); 15432 } 15433 15434 .fund-symbol { 15435 font-size: var(--quote-font-size-md); 15436 } 15437 15438 .price-container { 15439 flex-direction: row; 15440 justify-content: flex-end; 15441 } 15442 15443 .fund-price-number { 15444 font-size: var(--quote-font-size-xl); 15445 } 15446 15447 .fund-price-currency { 15448 font-size: var(--quote-font-size-md); 15449 } 15450 15451 .returns-container { 15452 flex-direction: row; 15453 justify-content: flex-end; 15454 } 15455 15456 .fund-return-block { 15457 min-width: 120px; 15458 } 15459 } 15460 `; 15461 vt([ 15462 $({ type: String }) 15463 ], ut.prototype, "isin", 2); 15464 vt([ 15465 $({ type: String }) 15466 ], ut.prototype, "locale", 2); 15467 vt([ 15468 $({ type: String, attribute: "schema" }) 15469 ], ut.prototype, "schema", 2); 15470 vt([ 15471 $({ type: String, attribute: "profile-url" }) 15472 ], ut.prototype, "profileUrl", 2); 15473 vt([ 15474 $({ type: String, attribute: "header-level" }) 15475 ], ut.prototype, "headerLevel", 2); 15476 vt([ 15477 C() 15478 ], ut.prototype, "lastFetchedIsin", 2); 15479 vt([ 15480 C() 15481 ], ut.prototype, "fetchInProgress", 2); 15482 vt([ 15483 C() 15484 ], ut.prototype, "fullFundData", 2); 15485 vt([ 15486 C() 15487 ], ut.prototype, "ytdReturn", 2); 15488 vt([ 15489 C() 15490 ], ut.prototype, "fiveYearReturn", 2); 15491 vt([ 15492 C() 15493 ], ut.prototype, "threeYearReturn", 2); 15494 ut = vt([ 15495 lt(), 15496 it("fund-quote-card") 15497 ], ut); 15498 var Ee = class { 15499 /** 15500 * Calculates profitability for a given timeframe using historical NAV data 15501 * Uses TimeframeFilter + ChangeCalculator 15502 */ 15503 static calculateProfitabilityForTimeframe(t, e) { 15504 if (!t || t.length === 0) 15505 return; 15506 const i = mt.filterDataByTimeframe( 15507 t, 15508 e, 15509 false 15510 ); 15511 if (!i.filteredData || i.filteredData.length < 2) 15512 return; 15513 const r = ht.calculateChange( 15514 i.filteredData, 15515 (n) => n.nav 15516 ); 15517 if (r) 15518 return ks(r.percentageChange, e); 15519 } 15520 /** 15521 * Calculates fund statistics from historical NAV data 15522 */ 15523 static calculateFundStatistics(t) { 15524 if (t.length < 2) 15525 return {}; 15526 const e = /* @__PURE__ */ new Date(), i = new Date(e); 15527 i.setFullYear(e.getFullYear() - 1); 15528 const r = new Date(e); 15529 r.setFullYear(e.getFullYear() - 3); 15530 const n = new Date(e); 15531 n.setFullYear(e.getFullYear() - 5); 15532 const a = new Date(e); 15533 a.setFullYear(e.getFullYear() - 10); 15534 const o = t.filter((Z) => new Date(Z.date) >= i), l = t.filter((Z) => new Date(Z.date) >= r), h = t.filter((Z) => new Date(Z.date) >= n), c = t.filter((Z) => new Date(Z.date) >= a), d = (Z) => Z.nav, f = T.calculateVolatility(o, d), m = T.calculateVolatility(l, d), p = T.calculateVolatility(h, d), v = T.calculateVolatility(c, d), b = T.calculateReturn(o, d), y = T.calculateReturn(l, d), x = T.calculateReturn(h, d), S = T.calculateReturn(c, d), w = b !== void 0 && o.length > 1 ? Math.pow(1 + b, 252 / o.length) - 1 : void 0, _ = y !== void 0 && l.length > 1 ? Math.pow(1 + y, 252 / l.length) - 1 : void 0, D = x !== void 0 && h.length > 1 ? Math.pow(1 + x, 252 / h.length) - 1 : void 0, z = S !== void 0 && c.length > 1 ? Math.pow(1 + S, 252 / c.length) - 1 : void 0, P = T.calculateSharpeRatio(w, f), E = T.calculateSharpeRatio(_, m), H = T.calculateSharpeRatio(D, p), J = T.calculateSharpeRatio(z, v), j = (Z) => Z.date, Q = T.calculateMaxDrawdown(o, d, j), N = T.calculateMaxDrawdown(l, d, j), W = T.calculateMaxDrawdown(h, d, j), at = T.calculateMaxDrawdown(c, d, j); 15535 return { 15536 sharpeRatio1y: P, 15537 sharpeRatio3y: E, 15538 sharpeRatio5y: H, 15539 sharpeRatio10y: J, 15540 deviation1y: f, 15541 deviation3y: m, 15542 deviation5y: p, 15543 deviation10y: v, 15544 maxDrawdownRatio1y: Q,
15545 maxDrawdownRatio3y: N, 15546 maxDrawdownRatio5y: W, 15547 maxDrawdownRatio10y: at 15548 }; 15549 } 15550 /** 15551 * Calculates benchmark statistics from historical price data 15552 */ 15553 static calculateBenchmarkStatistics(t, e = [], i = []) { 15554 if (t.length < 2) 15555 return {}; 15556 const r = /* @__PURE__ */ new Date(), n = new Date(r); 15557 n.setFullYear(r.getFullYear() - 1); 15558 const a = new Date(r); 15559 a.setFullYear(r.getFullYear() - 3); 15560 const o = new Date(r); 15561 o.setFullYear(r.getFullYear() - 5); 15562 const l = new Date(r); 15563 l.setFullYear(r.getFullYear() - 10); 15564 const h = t.filter((rt) => new Date(rt.date) >= n), c = t.filter((rt) => new Date(rt.date) >= a), d = t.filter((rt) => new Date(rt.date) >= o), f = t.filter((rt) => new Date(rt.date) >= l), m = (rt) => rt.price, p = T.calculateReturn(h, m), v = T.calculateReturn(c, m), b = T.calculateReturn(d, m), y = T.calculateReturn(f, m), x = T.calculateVolatility(h, m), S = T.calculateVolatility(c, m), w = T.calculateVolatility(d, m), _ = T.calculateVolatility(f, m), D = p !== void 0 && h.length > 1 ? Math.pow(1 + p, 252 / h.length) - 1 : void 0, z = v !== void 0 && c.length > 1 ? Math.pow(1 + v, 252 / c.length) - 1 : void 0, P = b !== void 0 && d.length > 1 ? Math.pow(1 + b, 252 / d.length) - 1 : void 0, E = y !== void 0 && f.length > 1 ? Math.pow(1 + y, 252 / f.length) - 1 : void 0, H = x !== void 0 && x !== 0 && D !== void 0 ? D / x : void 0, J = S !== void 0 && S !== 0 && z !== void 0 ? z / S : void 0, j = w !== void 0 && w !== 0 && P !== void 0 ? P / w : void 0, Q = _ !== void 0 && _ !== 0 && E !== void 0 ? E / _ : void 0, N = (rt) => rt.date, W = T.calculateMaxDrawdown(h, m, N), at = T.calculateMaxDrawdown(c, m, N), Z = T.calculateMaxDrawdown(d, m, N), Lt = T.calculateMaxDrawdown(f, m, N), U = this.calculateAlphaBetaR2(h, c, d, f, e, i), Et = this.calculateTrackingError(h, c, d, f, e, i); 15565 return M(M({ 15566 return1y: p !== void 0 ? p * 100 : void 0, 15567 return3y: v !== void 0 ? qt(v, "3y") * 100 : void 0, 15568 return5y: b !== void 0 ? qt(b, "5y") * 100 : void 0, 15569 return10y: y !== void 0 ? qt(y, "10y") * 100 : void 0, 15570 sharpeRatio1y: H, 15571 sharpeRatio3y: J, 15572 sharpeRatio5y: j, 15573 sharpeRatio10y: Q, 15574 deviation1y: x, 15575 deviation3y: S, 15576 deviation5y: w, 15577 deviation10y: _, 15578 maxDrawdownRatio1y: W, 15579 maxDrawdownRatio3y: at, 15580 maxDrawdownRatio5y: Z, 15581 maxDrawdownRatio10y: Lt 15582 }, U), Et); 15583 } 15584 /** 15585 * Calculates Alpha, Beta, and R² using linear regression 15586 */ 15587 static calculateAlphaBetaR2(t, e, i, r, n, a) { 15588 if (n.length === 0 || a.length === 0) 15589 return {}; 15590 const o = this.performRegression(t, n, a), l = this.performRegression(e, n, a), h = this.performRegression(i, n, a), c = this.performRegression(r, n, a); 15591 return { 15592 alpha1y: o == null ? void 0 : o.alpha, 15593 alpha3y: l == null ? void 0 : l.alpha, 15594 alpha5y: h == null ? void 0 : h.alpha, 15595 alpha10y: c == null ? void 0 : c.alpha, 15596 beta1y: o == null ? void 0 : o.beta, 15597 beta3y: l == null ? void 0 : l.beta, 15598 beta5y: h == null ? void 0 : h.beta, 15599 beta10y: c == null ? void 0 : c.beta, 15600 r21y: o == null ? void 0 : o.r2, 15601 r23y: l == null ? void 0 : l.r2, 15602 r25y: h == null ? void 0 : h.r2, 15603 r210y: c == null ? void 0 : c.r2 15604 }; 15605 } 15606 /** 15607 * Performs linear regression: Fund Return = Alpha + Beta * Benchmark Return 15608 */ 15609 static performRegression(t, e, i) { 15610 if (t.length < 2 || e.length === 0) 15611 return; 15612 const r = new Date(t[0].date), n = new Date(t[t.length - 1].date), a = e.filter((h) => { 15613 const c = new Date(h.date); 15614 return c >= r && c <= n; 15615 }); 15616 if (a.length < 2) 15617 return; 15618 const o = [], l = []; 15619 for (let h = 1; h < a.length; h++) { 15620 const c = a[h - 1].nav, d = a[h].nav, f = a[h].date, m = i.findIndex((b) => b.date === f); 15621 if (m <= 0) 15622 continue; 15623 const p = i[m - 1].price, v = i[m].price; 15624 c > 0 && d > 0 && p > 0 && v > 0 && Number.isFinite(c) && Number.isFinite(d) && Number.isFinite(p) && Number.isFinite(v) && (o.push(d / c - 1), l.push(v / p - 1)); 15625 } 15626 return T.performRegression(o, l); 15627 } 15628 /** 15629 * Calculates Tracking Error for multiple periods 15630 */ 15631 static calculateTrackingError(t, e, i, r, n, a) { 15632 if (n.length === 0 || a.length === 0) 15633 return {};
15634 const o = this.calculateTrackingErrorForPeriod(t, n, a), l = this.calculateTrackingErrorForPeriod(e, n, a), h = this.calculateTrackingErrorForPeriod(i, n, a), c = this.calculateTrackingErrorForPeriod(r, n, a); 15635 return { 15636 trackingError1y: o, 15637 trackingError3y: l, 15638 trackingError5y: h, 15639 trackingError10y: c 15640 }; 15641 } 15642 /** 15643 * Calculates Tracking Error for a specific period 15644 */ 15645 static calculateTrackingErrorForPeriod(t, e, i) { 15646 if (t.length < 2 || e.length === 0) 15647 return; 15648 const r = new Date(t[0].date), n = new Date(t[t.length - 1].date), a = e.filter((l) => { 15649 const h = new Date(l.date); 15650 return h >= r && h <= n; 15651 }); 15652 if (a.length < 2) 15653 return; 15654 const o = []; 15655 for (let l = 1; l < a.length; l++) { 15656 const h = a[l - 1].nav, c = a[l].nav, d = a[l].date, f = i.findIndex((v) => v.date === d); 15657 if (f <= 0) 15658 continue; 15659 const m = i[f - 1].price, p = i[f].price; 15660 if (h > 0 && c > 0 && m > 0 && p > 0 && Number.isFinite(h) && Number.isFinite(c) && Number.isFinite(m) && Number.isFinite(p)) { 15661 const v = c / h - 1, b = p / m - 1; 15662 o.push(v - b); 15663 } 15664 } 15665 return T.calculateTrackingError(o); 15666 } 15667 /** 15668 * Extracts period-specific data from stats based on selected period 15669 */ 15670 static getPeriodData(t, e, i) { 15671 if (!t) 15672 return {}; 15673 switch (e) { 15674 case "1y": 15675 return { 15676 return: i == null ? void 0 : i("1y"), 15677 sharpeRatio: t.sharpeRatio1y, 15678 deviation: t.deviation1y, 15679 alpha: t.alpha1y, 15680 beta: t.beta1y, 15681 r2: t.r21y, 15682 trackingError: t.trackingError1y, 15683 maxDrawdown: t.maxDrawdownRatio1y 15684 }; 15685 case "3y": 15686 return { 15687 return: i == null ? void 0 : i("3y"), 15688 sharpeRatio: t.sharpeRatio3y, 15689 deviation: t.deviation3y, 15690 alpha: t.alpha3y, 15691 beta: t.beta3y, 15692 r2: t.r23y, 15693 trackingError: t.trackingError3y, 15694 maxDrawdown: t.maxDrawdownRatio3y 15695 }; 15696 case "5y": 15697 return { 15698 return: i == null ? void 0 : i("5y"), 15699 sharpeRatio: t.sharpeRatio5y, 15700 deviation: t.deviation5y, 15701 alpha: t.alpha5y, 15702 beta: t.beta5y, 15703 r2: t.r25y, 15704 trackingError: t.trackingError5y, 15705 maxDrawdown: t.maxDrawdownRatio5y 15706 }; 15707 case "10y": 15708 return { 15709 return: i == null ? void 0 : i("10y"), 15710 sharpeRatio: t.sharpeRatio10y, 15711 deviation: t.deviation10y, 15712 alpha: t.alpha10y, 15713 beta: t.beta10y, 15714 r2: t.r210y, 15715 trackingError: t.trackingError10y, 15716 maxDrawdown: t.maxDrawdownRatio10y 15717 }; 15718 default: 15719 return {}; 15720 } 15721 } 15722 /** 15723 * Extracts benchmark period-specific data from stats 15724 */ 15725 static getBenchmarkPeriodData(t, e) { 15726 if (!t) 15727 return {}; 15728 switch (e) { 15729 case "1y": 15730 return { 15731 return: t.return1y, 15732 sharpeRatio: t.sharpeRatio1y, 15733 deviation: t.deviation1y, 15734 alpha: t.alpha1y, 15735 beta: t.beta1y, 15736 r2: t.r21y, 15737 trackingError: t.trackingError1y, 15738 maxDrawdown: t.maxDrawdownRatio1y 15739 }; 15740 case "3y": 15741 return { 15742 return: t.return3y, 15743 sharpeRatio: t.sharpeRatio3y, 15744 deviation: t.deviation3y, 15745 alpha: t.alpha3y, 15746 beta: t.beta3y, 15747 r2: t.r23y, 15748 trackingError: t.trackingError3y, 15749 maxDrawdown: t.maxDrawdownRatio3y 15750 }; 15751 case "5y": 15752 return { 15753 return: t.return5y, 15754 sharpeRatio: t.sharpeRatio5y, 15755 deviation: t.deviation5y, 15756 alpha: t.alpha5y, 15757 beta: t.beta5y, 15758 r2: t.r25y, 15759 trackingError: t.trackingError5y, 15760 maxDrawdown: t.maxDrawdownRatio5y 15761 }; 15762 case "10y": 15763 return { 15764 return: t.return10y, 15765 sharpeRatio: t.sharpeRatio10y, 15766 deviation: t.deviation10y, 15767 alpha: t.alpha10y, 15768 beta: t.beta10y, 15769 r2: t.r210y, 15770 trackingError: t.trackingError10y, 15771 maxDrawdown: t.maxDrawdownRatio10y 15772 }; 15773 default: 15774 return {}; 15775 } 15776 } 15777 }; 15778 var oc = Object.defineProperty; 15779 var lc = Object.getOwnPropertyDescriptor; 15780 var St = (s, t, e, i) => { 15781 for (var r = i > 1 ? void 0 : i ? lc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 15782 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 15783 return i && r && oc(t, e, r), r; 15784 }; 15785 var pt = class extends st { 15786 constructor() { 15787 super(), this.lastFetchedIsin = null, this.fetchInProgress = false, this.showTerPopup = false, this.selectedPeriod = "1y", this.benchmarkData = null, this.benchmarkLoading = false, this.benchmarkError = null, this.benchmarkName = null, this.benchmarkFetchInProgress = false, this.lastFetchedBenc
15787hmarkSymbol = null, this.fundHistoricalData = [], this.benchmarkHistoricalData = [], this.fundDataService = new ae(q.API_BASE_URL); 15788 } 15789 fetchData() { 15790 return L(this, null, function* () { 15791 var s, t, e; 15792 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 15793 this.loading = true, this.error = null, this.fetchInProgress = true; 15794 try { 15795 const i = q.API_BASE_URL, r = `${i}/funds/product/${encodeURIComponent(this.isin)}/statistic`, n = `${i}/funds/product/${encodeURIComponent(this.isin)}`, [a, o] = yield Promise.all([ 15796 R(r), 15797 R(n) 15798 ]); 15799 if (a.status === 404 || o.status === 404) { 15800 this.fundData = null, this.error = null, this.lastFetchedIsin = this.isin; 15801 return; 15802 } 15803 if (!a.ok) 15804 throw new Error(u(A`Error al obtener ratios del fondo: ${a.statusText}`, { 15805 desc: "Error message when ratios API request fails" 15806 })); 15807 const l = yield a.json(), h = o.ok ? yield o.json() : void 0; 15808 yield this.fetchFundHistoricalData(); 15809 const c = this.fundHistoricalData.length > 0 ? Ee.calculateFundStatistics(this.fundHistoricalData) : {}, d = { 15810 isin: l.isin || this.isin, 15811 name: this.showHeader ? h == null ? void 0 : h.name : l.name, 15812 fees: h == null ? void 0 : h.fees, 15813 stats: G(M(M({}, (l == null ? void 0 : l.stats) || {}), c), { 15814 // Merge locally calculated stats (overrides API values) 15815 ter: (e = (s = h == null ? void 0 : h.fees) == null ? void 0 : s.ongoingCharges) != null ? e : (t = l == null ? void 0 : l.stats) == null ? void 0 : t.ter 15816 }) 15817 }; 15818 this.processData(d), this.lastFetchedIsin = this.isin; 15819 } catch (i) { 15820 this.error = i instanceof Error ? i.message : u("Error desconocido", { 15821 desc: "Generic error message", 15822 id: "fund-ratios.error.unknown" 15823 }), this.warnOnSeoFallback(i); 15824 } finally { 15825 this.loading = false, this.fetchInProgress = false; 15826 } 15827 } 15828 }); 15829 } 15830 /** 15831 * Fetches fund historical NAV data for Alpha/Beta calculations 15832 */ 15833 fetchFundHistoricalData() { 15834 return L(this, null, function* () { 15835 if (this.isin) 15836 try { 15837 const s = yield this.fundDataService.fetchFundData({ 15838 isin: this.isin, 15839 timeframe: "10y", 15840 showHeader: false 15841 }); 15842 this.fundHistoricalData = s.fundData || []; 15843 } catch (s) { 15844 this.fundHistoricalData = []; 15845 } 15846 }); 15847 } 15848 firstUpdated(s) { 15849 super.firstUpdated(s), setTimeout(() => { 15850 yt(this); 15851 }, 0); 15852 } 15853 updated(s) { 15854 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(), s.has("benchmark") && (this.benchmark && this.benchmark.trim() ? (this.benchmarkName = null, this.lastFetchedBenchmarkSymbol = null, this.fetchBenchmarkData()) : (this.benchmarkData = null, this.benchmarkName = null, this.benchmarkError = null)), setTimeout(() => { 15855 yt(this); 15856 }, 0); 15857 } 15858 processData(s) { 15859 this.fundData = s; 15860 } 15861 /** 15862 * Override renderHeader to support header-level attribute 15863 */ 15864 renderHeader() { 15865 if (!this.showHeader) 15866 return g``; 15867 if (!this.fundData) 15868 return this.isin ? g` 15869 <div class="info-header"> 15870 <div> 15871 ${Dt(this.headerLevel, "stock-name", this.isin)} 15872 <p class="stock-symbol">${u(A`ISIN: ${this.isin}`, { desc: "ISIN label" })}</p> 15873 </div> 15874 </div> 15875 ` : g``; 15876 const { isin: s } = this.fundData; 15877 let t; 15878 return "name" in this.fundData && (t = this.fundData.name), g` 15879 <div class="info-header"> 15880 <div> 15881 ${Dt(this.headerLevel, "stock-name", t || s)} 15882 <p class="stock-symbol">${u(A`ISIN: ${s}`, { desc: "ISIN label" })}</p> 15883 </div> 15884 </div> 15885 `; 15886 } 15887 renderLoading() { 15888 return g`<div class="loading">${u("Cargando ratios del fondo...", {
15889 desc: "Loading message when fetching fund ratios data" 15890 })}</div>`; 15891 } 15892 switchPeriod(s) { 15893 this.selectedPeriod = s; 15894 } 15895 toggleTerPopup() { 15896 this.showTerPopup = !this.showTerPopup; 15897 } 15898 closeTerPopup() { 15899 this.showTerPopup = false; 15900 } 15901 hasDataForPeriod(s) { 15902 var e; 15903 const t = (e = this.fundData) == null ? void 0 : e.stats; 15904 return t ? s === "5y" ? t.return5y !== void 0 && t.return5y !== null : s === "10y" ? t.return10y !== void 0 && t.return10y !== null : false : false; 15905 } 15906 /** 15907 * Fetches benchmark historical data and calculates statistics 15908 */ 15909 fetchBenchmarkData() { 15910 return L(this, null, function* () { 15911 if (!this.benchmark || !this.benchmark.trim() || this.benchmarkFetchInProgress) 15912 return; 15913 const s = this.benchmark.trim(); 15914 if (!(this.lastFetchedBenchmarkSymbol === s && this.benchmarkData)) { 15915 this.benchmarkLoading = true, this.benchmarkError = null, this.benchmarkFetchInProgress = true; 15916 try { 15917 const t = q.API_BASE_URL, e = encodeURIComponent(s); 15918 try { 15919 const d = yield R(`${t}/asset-data/quote?symbol=${e}`); 15920 if (d.ok) { 15921 const f = yield d.json(); 15922 this.benchmarkName = (f == null ? void 0 : f.name) || s; 15923 } else 15924 this.benchmarkName = s; 15925 } catch (d) { 15926 this.benchmarkName = s; 15927 } 15928 const i = /* @__PURE__ */ new Date(), r = new Date(i); 15929 r.setFullYear(i.getFullYear() - 20); 15930 const n = r.toISOString().split("T")[0], a = i.toISOString().split("T")[0], o = yield R( 15931 `${t}/asset-data/basic-stock-chart?symbol=${e}&from_date=${n}&to_date=${a}` 15932 ); 15933 if (!o.ok) 15934 throw new Error(u(A`Error ${o.status}: ${o.statusText}`, { 15935 desc: "Error message when benchmark API request fails" 15936 })); 15937 const l = yield o.json(); 15938 if (!l || l.length === 0) 15939 throw new Error(u("No hay datos hist\xF3ricos disponibles para el benchmark", { 15940 desc: "Error when no historical data is available" 15941 })); 15942 const h = l.sort( 15943 (d, f) => new Date(d.date).getTime() - new Date(f.date).getTime() 15944 ); 15945 this.benchmarkHistoricalData = h, this.fundHistoricalData.length === 0 && this.isin && (yield this.fetchFundHistoricalData()); 15946 const c = Ee.calculateBenchmarkStatistics( 15947 h, 15948 this.fundHistoricalData, 15949 this.benchmarkHistoricalData 15950 ); 15951 this.benchmarkData = { 15952 isin: s, 15953 name: this.benchmarkName || void 0, 15954 stats: c 15955 }, this.fundData && (this.fundData = G(M({}, this.fundData), { 15956 stats: G(M({}, this.fundData.stats), { 15957 alpha1y: c.alpha1y, 15958 alpha3y: c.alpha3y, 15959 alpha5y: c.alpha5y, 15960 alpha10y: c.alpha10y, 15961 beta1y: c.beta1y, 15962 beta3y: c.beta3y, 15963 beta5y: c.beta5y, 15964 beta10y: c.beta10y, 15965 r21y: c.r21y, 15966 r23y: c.r23y, 15967 r25y: c.r25y, 15968 r210y: c.r210y, 15969 trackingError1y: c.trackingError1y, 15970 trackingError3y: c.trackingError3y, 15971 trackingError5y: c.trackingError5y, 15972 trackingError10y: c.trackingError10y 15973 }) 15974 }), this.requestUpdate()), this.lastFetchedBenchmarkSymbol = s, this.benchmarkError = null; 15975 } catch (t) { 15976 this.benchmarkError = t instanceof Error ? t.message : String(t), this.benchmarkData = null; 15977 } finally { 15978 this.benchmarkLoading = false, this.benchmarkFetchInProgress = false; 15979 } 15980 } 15981 }); 15982 } 15983 renderContent() { 15984 var a, o, l, h, c, d, f, m, p, v, b, y, x, S; 15985 if (!this.fundData) 15986 return null; 15987 const s = this.fundData.stats, t = Ee.getPeriodData( 15988 (a = this.fundData) == null ? void 0 : a.stats, 15989 this.selectedPeriod, 15990 (w) => Ee.calculateProfitabilityForTimeframe(this.fundHistoricalData, w) 15991 ), e = Ee.getBenchmarkPeriodData((o = this.benchmarkData) == null ? void 0 : o.stats, this.selectedPeriod), i = this.fundHistoricalData.length > 0 ? this.fundHistoricalData[this.fundHistoricalData.length - 1].date : (/* @__PURE__ */ new Date()).toISOString(), r = this.benchmarkData !== null && !this.benchmarkLoading && !this.benchmarkError, n = this.benchmarkName || this.benchmark || u("Benchmark", { desc: "Benchmark column header" }); 15992 return g` 15993 <div class="ratios-container"> 15994 ${this.renderHeader()} 15995 15996 <div class="period-selector horizontal-scroll-element"> 15997 <div class="horizontal-scroll-element-inner"> 15998 <button 15999 class="tab-button ${this.selectedPeriod === "1y" ? "active" : ""}" 16000 @click="${() => this.switchPeriod("1y")}" 16001 > 16002 ${u("1 a\xF1o", { desc: "1 year period button" })} 16003 </button> 16004 <button 16005 class="tab-button ${this.selectedPeriod === "3y" ? "active" : ""}" 16006 @click="${() => this.switchPeriod("3y")}" 16007 > 16008 ${u("3 a\xF1os", { desc: "3 years period button" })} 16009 </button> 16010 ${this.hasDataForPeriod("5y") ? g` 16011 <button 16012 class="tab-button ${this.selectedPeriod === "5y" ? "active" : ""}" 16013 @click="${() => this.switchPeriod("5y")}" 16014 > 16015 ${u("5 a\xF1os", { desc: "5 years period button" })} 16016 </button> 16017 ` : ""} 16018 ${this.hasDataForPeriod("10y") ? g` 16019 <button 16020 class="tab-button ${this.selectedPeriod === "10y" ? "active" : ""}" 16021 @click="${() => this.switchPeriod("10y")}" 16022 > 16023 ${u("10 a\xF1os", { desc: "10 years period button" })} 16024 </button> 16025 ` : ""} 16026 </div> 16027 </div> 16028 16029 ${this.benchmarkLoading ? g` 16030 <div class="loading">
16030${u("Cargando datos del benchmark...", { desc: "Loading benchmark data message" })}</div> 16031 ` : ""} 16032 ${this.benchmarkError ? g` 16033 <div class="error">${u("Error al cargar datos del benchmark:", { desc: "Error loading benchmark message" })} ${this.benchmarkError}</div> 16034 ` : ""} 16035 16036 <table class="ratios-table"> 16037 <thead class="table-header"> 16038 <tr> 16039 <th></th> 16040 <th>${u("Fondo", { desc: "Fund column header" })}</th> 16041 ${r ? g` 16042 <th>${n}</th> 16043 ` : ""} 16044 </tr> 16045 </thead> 16046 <tbody> 16047 <tr class="table-row"> 16048 <td class="table-cell">${u("Rentabilidad", { desc: "Return metric" })}</td> 16049 <td class="table-cell ${this.getValueClass(t.return)}"> 16050 ${t.return !== void 0 ? `${F.formatDecimal(t.return, this.locale || "en-US", 2)}%` : "-"} 16051 </td> 16052 ${r ? g` 16053 <td class="table-cell ${this.getValueClass(e.return)}"> 16054 ${e.return !== void 0 ? `${F.formatDecimal(e.return, this.locale || "en-US", 2)}%` : "-"} 16055 </td> 16056 ` : ""} 16057 </tr> 16058 <tr class="table-row"> 16059 <td class="table-cell">${u("Ratio de Sharpe", { desc: "Sharpe ratio metric" })}</td> 16060 <td class="table-cell ${this.getValueClass(t.sharpeRatio)}"> 16061 ${F.formatDecimal(t.sharpeRatio, this.locale || "en-US", 2)} 16062 </td> 16063 ${r ? g` 16064 <td class="table-cell ${this.getValueClass(e.sharpeRatio)}"> 16065 ${F.formatDecimal(e.sharpeRatio, this.locale || "en-US", 2)} 16066 </td> 16067 ` : ""} 16068 </tr> 16069 <tr class="table-row"> 16070 <td class="table-cell"> 16071 ${u("TER", { desc: "Total Expense Ratio metric" })} 16072 </td> 16073 <td class="table-cell neutral"> 16074 ${s.ter !== void 0 ? g` 16075 <span style="display: inline-flex; align-items: center; gap: 8px;"> 16076 <button class="ter-info-button" @click=${() => this.toggleTerPopup()}> 16077 <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> 16078 <path d="M8.50033 12.0417C8.70102 12.0417 8.86937 11.9737 9.00537 11.8377C9.14137 11.7017 9.20913 11.5336 9.20866 11.3334V8.50008C9.20866 8.29939 9.14066 8.13128 9.00466 7.99575C8.86866 7.86022 8.70055 7.79222 8.50033 7.79175C8.3001 7.79128 8.13199 7.85928 7.99599 7.99575C7.85999 8.13222 7.79199 8.30033 7.79199 8.50008V11.3334C7.79199 11.5341 7.85999 11.7025 7.99599 11.8385C8.13199 11.9745 8.3001 12.0422 8.50033 12.0417ZM8.50033 6.37508C8.70102 6.37508 8.86937 6.30708 9.00537 6.17108C9.14137 6.03508 9.20913 5.86697 9.20866 5.66675C9.20819 5.46653 9.14019 5.29841 9.00466 5.16241C8.86913 5.02641 8.70102 4.95841 8.50033 4.95841C8.29963 4.95841 8.13152 5.02641 7.99599 5.16241C7.86047 5.29841 7.79247 5.46653 7.79199 5.66675C7.79152 5.86697 7.85952 6.03532 7.99599 6.17179C8.13247 6.30826 8.30058 6.37603 8.50033 6.37508ZM8.50033 15.5834C7.52047 15.5834 6.59963 15.3974 5.73783 15.0252C4.87602 14.6531 4.12637 14.1486 3.48887 13.5115C2.85137 12.8745 2.3468 12.1249 1.97516 11.2626C1.60352 10.4003 1.41747 9.47947 1.41699 8.50008C1.41652 7.52069 1.60258 6.59986 1.97516 5.73758C2.34774 4.8753 2.85231 4.12565 3.48887 3.48862C4.12542 2.8516 4.87508 2.34703 5.73783 1.97491C6.60058 1.6028 7.52141 1.41675 8.50033 1.41675C9.47924 1.41675 10.4001 1.6028 11.2628 1.97491C12.1256 2.34703 12.8752 2.8516 13.5118 3.48862C14.1483 4.12565 14.6531 4.8753 15.0262 5.73758C15.3993 6.59986 15.5851 7.52069 15.5837 8.50008C15.5822 9.47947 15.3962 10.4003 15.0255 11.2626C14.6548 12.1249 14.1502 12.8745 13.5118 13.5115C12.8733 14.1486 12.1237 14.6534 11.2628 15.026C10.402 15.3985 9.48113 15.5844 8.50033 15.5834ZM8.50033 14.1667C10.0823 14.1667 11.4222 13.6178 12.5201 12.5199C13.618 11.422 14.167 10.082 14.167 8.50008C14.167 6.91814 13.618 5.57821 12.5201 4.48029C11.4222 3.38237 10.0823 2.83341 8.50033 2.83341C6.91838 2.83341 5.57845 3.38237 4.48053 4.48029C3.38262 5.57821 2.83366 6.91814 2.83366 8.50008C2.83366 10.082 3.38262 11.422 4.48053 12.5199C5.57845 13.6178 6.91838 14.1667 8.50033 14.1667Z" fill="currentColor"/> 16079 </svg> 16080 ${u("M\xE1s informaci\xF3n", { desc: "More information link for TER" })} 16081 </button> 16082 ${F.formatDecimal(s.ter, this.locale || "en-US", 2)}% 16083 </span> 16084 ` : "-"} 16085 </td> 16086 ${r ? g`
16087 <td class="table-cell neutral">-</td> 16088 ` : ""} 16089 </tr> 16090 <tr class="table-row"> 16091 <td class="table-cell">${u("Volatilidad", { desc: "Volatility metric" })}</td> 16092 <td class="table-cell neutral"> 16093 ${t.deviation !== void 0 ? `${F.formatDecimal(t.deviation * 100, this.locale || "en-US", 2)}%` : "-"} 16094 </td> 16095 ${r ? g` 16096 <td class="table-cell neutral"> 16097 ${e.deviation !== void 0 ? `${F.formatDecimal(e.deviation * 100, this.locale || "en-US", 2)}%` : "-"} 16098 </td> 16099 ` : ""} 16100 </tr> 16101 <tr class="table-row"> 16102 <td class="table-cell">${u("M\xE1ximo drawdown", { desc: "Maximum drawdown metric" })}</td> 16103 <td class="table-cell negative"> 16104 ${((l = t.maxDrawdown) == null ? void 0 : l.value) !== void 0 ? `${F.formatDecimal(t.maxDrawdown.value * 100, this.locale || "en-US", 2)}%` : "-"} 16105 </td> 16106 ${r ? g` 16107 <td class="table-cell negative"> 16108 ${((h = e.maxDrawdown) == null ? void 0 : h.value) !== void 0 ? `${F.formatDecimal(e.maxDrawdown.value * 100, this.locale || "en-US", 2)}%` : "-"} 16109 </td> 16110 ` : ""} 16111 </tr> 16112 ${r ? g` 16113 <tr class="table-row"> 16114 <td class="table-cell">${u("Alpha", { desc: "Alpha metric" })}</td> 16115 <td class="table-cell ${this.getValueClass(t.alpha)}"> 16116 ${F.formatDecimal(t.alpha, this.locale || "en-US", 2)} 16117 </td> 16118 <td class="table-cell neutral">-</td> 16119 </tr> 16120 <tr class="table-row"> 16121 <td class="table-cell">${u("Beta", { desc: "Beta metric" })}</td> 16122 <td class="table-cell neutral"> 16123 ${F.formatDecimal(t.beta, this.locale || "en-US", 2)} 16124 </td> 16125 <td class="table-cell neutral">-</td> 16126 </tr> 16127 <tr class="table-row"> 16128 <td class="table-cell">${u("R2", { desc: "R-squared metric" })}</td> 16129 <td class="table-cell neutral"> 16130 ${F.formatDecimal(t.r2, this.locale || "en-US", 2)} 16131 </td> 16132 <td class="table-cell neutral">-</td> 16133 </tr> 16134 <tr class="table-row"> 16135 <td class="table-cell">${u("Tracking Error", { desc: "Tracking error metric" })}</td> 16136 <td class="table-cell neutral"> 16137 ${t.trackingError !== void 0 ? `${F.formatDecimal(t.trackingError * 100, this.locale || "en-US", 2)}%` : "-"} 16138 </td> 16139 <td class="table-cell neutral">-</td> 16140 </tr> 16141 ` : g``} 16142 </tbody> 16143 </table> 16144 16145 <div class="info-disclaimer"> 16146 <div class="info-icon">i</div> 16147 <div> 16148 <div class="disclaimer-text"> 16149 ${u("Rentabilidades pasadas no garantizan resultados futuros. Rentabilidades anualizadas para periodos superiores a 1 a\xF1o.", { 16150 id: "disclaimer.past-returns", 16151 desc: "Past returns disclaimer text" 16152 })} 16153 </div> 16154 <div class="update-date"> 16155 ${u("Datos actualizados a", { id: "disclaimer.data-updated", desc: "Data updated to text" })} ${this.formatDate(i)} 16156 </div> 16157 </div> 16158 </div> 16159 16160 ${this.showTerPopup ? g` 16161 <div class="ter-popup-overlay" @click=${(w) => { 16162 w.target === w.currentTarget && this.closeTerPopup(); 16163 }}> 16164 <div class="ter-popup-content"> 16165 <div class="ter-popup-header"> 16166 <h3 class="ter-popup-title">${u("Desglose de comisiones", { desc: "Commission breakdown title" })}</h3> 16167 <button class="ter-popup-close" @click=${() => this.closeTerPopup()}>Ã</button> 16168 </div> 16169 16170 <ul class="ter-fees-list"> 16171 ${((d = (c = this.fundData) == null ? void 0 : c.fees) == null ? void 0 : d.managementFee) !== void 0 ? g` 16172 <li class="ter-fee-item">
16173 <span class="ter-fee-label">${u("Comisi\xF3n de gesti\xF3n", { desc: "Management fee label" })}</span> 16174 <span class="ter-fee-value">${F.formatDecimal(this.fundData.fees.managementFee, this.locale || "en-US", 2)}%</span> 16175 </li> 16176 ` : ""} 16177 16178 ${((m = (f = this.fundData) == null ? void 0 : f.fees) == null ? void 0 : m.ongoingCharges) !== void 0 ? g` 16179 <li class="ter-fee-item"> 16180 <span class="ter-fee-label">${u("Comisi\xF3n de dep\xF3sito", { desc: "Deposit fee label" })}</span> 16181 <span class="ter-fee-value">${F.formatDecimal(this.fundData.fees.ongoingCharges, this.locale || "en-US", 2)}%</span> 16182 </li> 16183 ` : ""} 16184 16185 ${((v = (p = this.fundData) == null ? void 0 : p.fees) == null ? void 0 : v.performanceFee) !== void 0 && this.fundData.fees.hasPerformanceFee ? g` 16186 <li class="ter-fee-item"> 16187 <span class="ter-fee-label">${u("Comisi\xF3n de \xE9xito", { desc: "Success fee label" })}</span> 16188 <span class="ter-fee-value">${F.formatDecimal(this.fundData.fees.performanceFee, this.locale || "en-US", 2)}%</span> 16189 </li> 16190 ` : ""} 16191 16192 ${((y = (b = this.fundData) == null ? void 0 : b.fees) == null ? void 0 : y.exPostTransactionCosts) !== void 0 ? g` 16193 <li class="ter-fee-item"> 16194 <span class="ter-fee-label">${u("Comisi\xF3n de suscripci\xF3n", { desc: "Subscription fee label" })}</span> 16195 <span class="ter-fee-value">${F.formatDecimal(this.fundData.fees.exPostTransactionCosts, this.locale || "en-US", 2)}%</span> 16196 </li> 16197 ` : ""} 16198 16199 ${((S = (x = this.fundData) == null ? void 0 : x.fees) == null ? void 0 : S.minimalInitialSubscriptionAmount) !== void 0 ? g` 16200 <li class="ter-fee-item"> 16201 <span class="ter-fee-label">${u("Comisi\xF3n de reembolso", { desc: "Redemption fee label" })}</span> 16202 <span class="ter-fee-value">${F.formatDecimal(this.fundData.fees.minimalInitialSubscriptionAmount, this.locale || "en-US", 2)}%</span> 16203 </li> 16204 ` : ""} 16205 </ul> 16206 </div> 16207 </div> 16208 ` : ""} 16209 </div> 16210 `; 16211 } 16212 }; 16213 pt.styles = K` 16214 ${nt(st.styles)} 16215 ${nt(We)} 16216 ${_i} 16217 16218 .ratios-container { 16219 width: 100%; 16220 display: block; 16221 } 16222 16223 .period-selector { 16224 width: 100%; 16225 } 16226 16227 .ratios-table { 16228 width: 100%; 16229 max-width: 800px; 16230 border-collapse: collapse; 16231 table-layout: fixed; 16232 } 16233 16234 .table-header { 16235 background: none; 16236 border-bottom: 2px solid var(--stock-danger-color, #E91101); 16237 } 16238 16239 .table-header th { 16240 padding: 12px 8px; 16241 text-align: left; 16242 font-size: var(--stock-text-size, 14px); 16243 font-weight: var(--stock-title-weight, 700); 16244 color: var(--stock-text-color, #383d43); 16245 } 16246 16247 .table-header th:not(:first-child) { 16248 text-align: right; 16249 } 16250 16251 .table-row { 16252 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 16253 } 16254 16255 .table-row:last-child { 16256 border-bottom: none; 16257 } 16258 16259 .table-cell { 16260 padding: 12px 8px; 16261 font-size: var(--stock-text-size, 14px); 16262 font-weight: var(--stock-value-weight, 500); 16263 } 16264 16265 .table-cell:first-child { 16266 font-weight: var(--stock-title-weight, 600); 16267 color: var(--stock-text-color, #383d43); 16268 } 16269 16270 .table-cell:not(:first-child) { 16271 text-align: right; 16272 } 16273 16274 16275 .table-cell.positive { 16276 color: var(--stock-positive-color, #00856F); 16277 } 16278 16279 .table-cell.negative { 16280 color: var(--stock-negative-color, #E91101); 16281 } 16282 16283 .table-cell.neutral { 16284 color: var(--stock-text-color, #383d43); 16285 } 16286 16287 .info-disclaimer { 16288 display: flex; 16289 align-items: flex-start; 16290 gap: 8px; 16291 margin-top: 20px; 16292 } 16293 16294 .info-icon { 16295 width: 16px; 16296 height: 16px; 16297 color: var(--stock-accent-color, #58A8DA); 16298 border-radius: 50%; 16299 display: flex; 16300 align-items: center; 16301 justify-content: center; 16302 font-size: 12px; 16303 font-weight: bold; 16304 flex-shrink: 0; 16305 margin-top: 2px; 16306 border: 1px solid var(--stock-accent-color, #58A8DA); 16307 } 16308 16309 .disclaimer-text { 16310 font-size: var(--stock-small-text-size, 14px); 16311 color: var(--stock-muted-color, #383D43); 16312 line-height: 1.4; 16313 } 16314 16315 .update-date { 16316 font-size: var(--stock-small-text-size, 14px); 16317 color: var(--stock-muted-color, #383D43); 16318 margin-top: 4px; 16319 } 16320 16321 /* TER Popup Styles */ 16322 .ter-info-button { 16323 background: none; 16324 border: none; 16325 color: #5A6773; 16326 text-decoration: none; 16327 cursor: pointer; 16328 font-size: var(--stock-small-text-size, 14px); 16329 display: inline-flex; 16330 align-items: center; 16331 gap: 4px; 16332 padding: 0; 16333 margin: 0; 16334 font-weight: 400; 16335 vertical-align: bottom; 16336 } 16337 16338 .ter-info-button:hover { 16339 text-decoration: underline; 16340 } 16341 16342 .ter-info-button:focus:not(:focus-visible) { 16343 outline: none; 16344 } 16345 16346 .ter-popup-overlay { 16347 position: fixed; 16348 top: 0; 16349 left: 0; 16350 right: 0; 16351 bottom: 0; 16352 background-color: rgba(0, 0, 0, 0.5); 16353 display: flex; 16354 align-items: center; 16355 justify-content: center; 16356 z-index: 1000; 16357 } 16358 16359 .ter-popup-content { 16360 background-color: var(--stock-white-color, #ffffff); 16361 border-radius: 8px; 16362 padding: 24px; 16363 width: 90%; 16364 max-width: 500px; 16365 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); 16366 position: relative; 16367 } 16368 16369 .ter-popup-header { 16370 display: flex; 16371 justify-content: space-between; 16372 align-items: center; 16373 margin-bottom: 20px; 16374 } 16375 16376 .ter-popup-title { 16377 font-size: 1.2rem; 16378 font-weight: 600; 16379 color: var(--stock-text-color, #383d43); 16380 margin: 0; 16381 } 16382 16383 .ter-popup-close { 16384 background: none; 16385 border: none; 16386 font-size: 1.5rem; 16387 cursor: pointer; 16388 color: var(--stock-muted-color, #64748b); 16389 padding: 0; 16390 width: 24px; 16391 height: 24px; 16392 display: flex; 16393 align-items: center; 16394 justify-content: center; 16395 } 16396 16397 .ter-popup-close:hover { 16398 color: var(--stock-text-color, #383d43); 16399 } 16400 16401 .ter-fees-list { 16402 list-style: none; 16403 padding: 0; 16404 margin: 0; 16405 } 16406 16407 .ter-fee-item { 16408 display: flex; 16409 justify-content: space-between; 16410 align-items: center; 16411 padding: 12px 0; 16412 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 16413 } 16414 16415 .ter-fee-item:last-child { 16416 border-bottom: none; 16417 } 16418 16419 .ter-fee-label { 16420 font-size: var(--stock-text-size, 14px); 16421 color: var(--stock-text-color, #383d43); 16422 font-weight: 500; 16423 } 16424 16425 .ter-fee-value { 16426 font-size: var(--stock-text-size, 14px); 16427 color: var(--stock-text-color, #383d43); 16428 font-weight: 600; 16429 } 16430 16431 @media (max-width: 768px) { 16432 .period-selector { 16433 justify-content: flex-start; 16434 } 16435 16436 .ratios-table { 16437 font-size: 12px; 16438 } 16439 16440 .table-header th, 16441 .table-cell { 16442 padding: 8px 4px; 16443 } 16444 } 16445 `; 16446 St([ 16447 $({ type: String }) 16448 ], pt.prototype, "benchmark", 2); 16449 St([ 16450 $({ type: String, attribute: "header-level" }) 16451 ], pt.prototype, "headerLevel", 2); 16452 St([ 16453 C() 16454 ], pt.prototype, "lastFetchedIsin", 2); 16455 St([ 16456 C() 16457 ], pt.prototype, "fetchInProgress", 2); 16458 St([ 16459 C() 16460 ], pt.prototype, "showTerPopup", 2); 16461 St([ 16462 C() 16463 ], pt.prototype, "selectedPeriod", 2); 16464 St([ 16465 C() 16466 ], pt.prototype, "benchmarkData", 2); 16467 St([ 16468 C() 16469 ], pt.prototype, "benchmarkLoading", 2); 16470 St([ 16471 C() 16472 ], pt.prototype, "benchmarkError", 2); 16473 St([ 16474 C() 16475 ], pt.prototype, "benchmarkName", 2);
16476 pt = St([ 16477 lt(), 16478 it("fund-ratios") 16479 ], pt); 16480 var hc = Object.defineProperty; 16481 var cc = Object.getOwnPropertyDescriptor; 16482 var Ht = (s, t, e, i) => { 16483 for (var r = i > 1 ? void 0 : i ? cc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 16484 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 16485 return i && r && hc(t, e, r), r; 16486 }; 16487 var Mt = class extends kt { 16488 constructor() { 16489 super(), this.isin = "", this.locale = "", this.lastFetchedIsin = null, this.fetchInProgress = false, this.fullFundData = [], this.ytdReturn = null, this.fundDataService = new ae(q.API_BASE_URL); 16490 } 16491 /** 16492 * Datos del fondo (alias para mantener compatibilidad) 16493 */ 16494 get fundData() { 16495 return this.data; 16496 } 16497 set fundData(s) { 16498 this.data = s; 16499 } 16500 /** 16501 * Verifica si se debe obtener los datos 16502 */ 16503 shouldFetchData() { 16504 return !!this.isin; 16505 } 16506 /** 16507 * Verifica si una propiedad clave ha cambiado 16508 */ 16509 hasKeyPropertyChanged(s) { 16510 return s.has("isin") && !!this.isin; 16511 } 16512 /** 16513 * Este componente no usa header 16514 */ 16515 renderHeader() { 16516 return g``; 16517 } 16518 fetchData() { 16519 return L(this, null, function* () { 16520 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 16521 this.loading = true, this.error = null, this.fetchInProgress = true; 16522 try { 16523 const s = yield this.fundDataService.fetchFundData({ 16524 isin: this.isin, 16525 timeframe: "max", 16526 showHeader: false 16527 }); 16528 if (this.fullFundData = s.fundData, this.fullFundData.length === 0) { 16529 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 16530 return; 16531 } 16532 const t = q.API_BASE_URL, e = yield R(`${t}/funds/product/${encodeURIComponent(this.isin)}`); 16533 if (e.status === 404) { 16534 this.data = null, this.error = null, this.lastFetchedIsin = this.isin; 16535 return; 16536 } 16537 if (!e.ok) 16538 throw new Error(u(A`Error al obtener datos del fondo: ${e.statusText}`, { 16539 desc: "Error message when fund API request fails", 16540 id: "fund-short-quote.api-error" 16541 })); 16542 const i = yield e.json(); 16543 this.processData(i), this.filterAndCalculateReturns(), this.lastFetchedIsin = this.isin; 16544 } catch (s) { 16545 this.error = s instanceof Error ? s.message : u("Error desconocido", { 16546 desc: "Generic error message", 16547 id: "fund-short-quote.error.unknown" 16548 }), console.error(u("Error al obtener datos del fondo:", { 16549 desc: "Console error message prefix", 16550 id: "fund-short-quote.error.console" 16551 }), s); 16552 } finally { 16553 this.loading = false, this.fetchInProgress = false; 16554 } 16555 } 16556 }); 16557 } 16558 // Sobrescribir el método updated para controlar cuando se debe volver a cargar 16559 updated(s) { 16560 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 16561 } 16562 processData(s) { 16563 this.fundData = s; 16564 } 16565 /** 16566 * Filter historic data and calculate returns for different timeframes 16567 */ 16568 filterAndCalculateReturns() { 16569 if (this.fullFundData.length === 0) 16570 return; 16571 const s = mt.filterDataByTimeframe(this.fullFundData, "ytd"); 16572 if (!s.error && s.filteredData.length > 0) { 16573 const t = ht.calculateChange( 16574 s.filteredData, 16575 (e) => e.nav 16576 ); 16577 this.ytdReturn = t ? t.percentageChange : null; 16578 } 16579 } 16580 renderLoading() { 16581 return g`<div class="loading">${u("Cargando informaci\xF3n del fondo...", { 16582 desc: "Loading message when fetching fund data", 16583 id: "fund-short-quote.loading" 16584 })}</div>`; 16585 } 16586 getNoDataMessage() { 16587 return u("No hay datos del fondo disponibles. Por favor, proporcione un ISIN v\xE1lido.", { 16588 desc: "Message shown when no fund data is available", 16589 id: "fund-short-quote.no-data" 16590 }); 16591 } 16592 /**
16593 * Renderiza el componente cuando no hay datos 16594 * Usa renderNoDataBlock para mostrar un estado vacÃo consistente 16595 */ 16596 renderNoData() { 16597 return g` 16598 ${Ye()} 16599 `; 16600 } 16601 formatNumber(s, t = {}) { 16602 return new Intl.NumberFormat(this.locale || void 0, t).format(s); 16603 } 16604 formatPercentage(s) { 16605 return new Intl.NumberFormat(this.locale || void 0, { 16606 style: "percent", 16607 minimumFractionDigits: 2, 16608 maximumFractionDigits: 2 16609 }).format(s / 100); 16610 } 16611 /** 16612 * Helper method to split fund name into two lines if needed 16613 */ 16614 splitFundName(s) { 16615 const t = s.split(" "); 16616 if (t.length <= 3) 16617 return [s]; 16618 const e = ["Funds", "Europe", "Strategic", "Value"]; 16619 for (const r of e) { 16620 const n = t.findIndex((a) => a.includes(r)); 16621 if (n > 0 && n < t.length - 1) 16622 return [ 16623 t.slice(0, n + 1).join(" "), 16624 t.slice(n + 1).join(" ") 16625 ]; 16626 } 16627 const i = Math.ceil(t.length / 2); 16628 return [ 16629 t.slice(0, i).join(" "), 16630 t.slice(i).join(" ") 16631 ]; 16632 } 16633 /** 16634 * Helper method to determine CSS classes for performance values 16635 */ 16636 getValueClass(s) { 16637 return s > 0 ? "positive" : s < 0 ? "negative" : ""; 16638 } 16639 /** 16640 * Renders the fund name with a dynamic HTML tag based on the header-level attribute 16641 * @param nameLines - array of name lines to display 16642 * @returns Lit template with the appropriate heading tag 16643 */ 16644 renderFundName(s) { 16645 const t = qs(Vs(this.headerLevel)); 16646 return Us`<${t} class="fund-name"> 16647 ${s.map((e) => g`<div class="name-line">${e}</div>`)} 16648 </${t}>`; 16649 } 16650 renderContent() { 16651 if (!this.fundData) 16652 return null; 16653 const { name: s, currency: t } = this.fundData, e = this.fullFundData.length > 0 ? this.fullFundData[this.fullFundData.length - 1] : null, { value: i, date: r } = Ws(this.fundData.nav, e), n = this.splitFundName(s); 16654 return g` 16655 <div class="fund-card"> 16656 <div class="name-container"> 16657 ${this.renderFundName(n)} 16658 <p class="fund-isin">${u("ISIN:", { desc: "ISIN label", id: "fund-quote-card.isin-label" })} ${this.isin}</p> 16659 </div> 16660 16661 <div class="nav-container"> 16662 <p class="fund-nav"> 16663 ${i !== void 0 ? this.formatNumber(i, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : u("N/A", { desc: "Not available abbreviation", id: "fund-quote-card.not-available" })} 16664 ${t} 16665 </p> 16666 16667 ${this.ytdReturn !== null ? g` 16668 <div class="fund-change ${this.getValueClass(this.ytdReturn)}"> 16669 <span class="change-label">${u("Rentab. YTD", { desc: "Year-to-date return label", id: "fund-quote-card.ytd-label" })}</span> 16670 <div class="change-content"> 16671 <svg class="change-icon" width="12" height="12" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 16672 <path d="M6.33331 14.5V2.25L1.08331 7.5L0.333313 6.84L6.83331 0.339996L13.3333 6.84L12.5833 7.5L7.33331 2.25V14.5H6.33331Z" fill="currentColor"/> 16673 </svg> 16674 <span class="change-value">${this.formatPercentage(this.ytdReturn)}</span> 16675 </div> 16676 </div> 16677 ` : ""} 16678 16679 ${r ? g` 16680 <p class="fund-nav-date"> 16681 ${u("Act.:", { desc: "Updated timestamp label" })} ${this.formatDate(r)} 16682 </p> 16683 ` : ""} 16684 </div> 16685 </div> 16686 `; 16687 } 16688 }; 16689 Mt.styles = K` 16690 ${nt(Qe)} 16691 :host { 16692 display: block; 16693 container-type: inline-size; 16694 container-name: fund-card; 16695 font-family: var(--fund-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 16696 --fund-name-color: var(--fund-accent-color, #1A5275); 16697 --fund-text-main-color: var(--fund-text-color, #383d43); 16698 --fund-nav-color: var(--fund-text-color, #383d43); 16699 --fund-positive-text-color: var(--fund-success-color, #00856F); 16700 --fund-positive-bg: var(--fund-success-bg, rgba(0, 133, 111, 0.15)); 16701 --fund-negative-color: var(--fund-danger-color, #dc2626); 16702 --fund-negative-bg: var(--fund-danger-bg, rgba(233, 17, 1, 0.15)); 16703 --fund-date-color: var(--fund-muted-color, #94A3B8); 16704 background: none; 16705 padding: 0; 16706 margin: 0; 16707 box-sizing: border-box; 16708 } 16709 16710 .fund-card { 16711 display: grid; 16712 grid-template-columns: 1fr; 16713 grid-template-areas: 16714 "name" 16715 "nav"; 16716 gap: 12px; 16717 align-items: center; 16718 margin: 0; 16719 overflow: hidden; 16720 border: none; 16721 box-sizing: border-box; 16722 text-align: left; 16723 text-decoration: none !important; 16724 } 16725 16726 .name-container { 16727 display: flex; 16728 flex-direction: column; 16729 height: 100%; 16730 grid-area: name; 16731 padding-right: 0; 16732 text-align: left; 16733 } 16734 16735 .fund-name { 16736 margin: 0; 16737 font-size: 1.1rem; 16738 font-weight: 600; 16739 color: var(--fund-name-color); 16740 line-height: 1.2; 16741 } 16742 16743 .name-line { 16744 margin: 0; 16745 } 16746 16747 .fund-isin { 16748 margin: auto 0 0; 16749 padding: 16px 0 0; 16750 display: inline-block; 16751 font-size: 1.12rem; 16752 font-weight: 500; 16753 color: var(--fund-text-main-color); 16754 } 16755 16756 .nav-container { 16757 grid-area: nav;
16758 text-align: left; 16759 display: flex; 16760 flex-direction: column; 16761 align-items: flex-start; 16762 gap: 4px; 16763 margin-top: 8px; 16764 } 16765 16766 .fund-nav { 16767 margin: 0; 16768 font-size: 1.75rem; 16769 font-weight: 500; 16770 color: var(--fund-nav-color); 16771 } 16772 16773 .fund-change { 16774 margin-top: 4px; 16775 font-size: 1.13rem; 16776 font-weight: 600; 16777 padding: 4px 8px; 16778 border-radius: 6px; 16779 display: flex; 16780 align-items: center; 16781 gap: 1rem; 16782 } 16783 16784 .fund-change.positive { 16785 color: var(--fund-positive-text-color); 16786 background-color: var(--fund-positive-bg); 16787 } 16788 16789 .fund-change.negative { 16790 color: var(--fund-negative-color); 16791 background-color: var(--fund-negative-bg); 16792 } 16793 16794 .change-label { 16795 font-size: 0.88rem; 16796 font-weight: 500; 16797 } 16798 16799 .change-content { 16800 display: flex; 16801 align-items: center; 16802 gap: 4px; 16803 } 16804 16805 .change-icon { 16806 width: 12px; 16807 height: 12px; 16808 } 16809 16810 .fund-change.negative .change-icon { 16811 transform: rotate(180deg); 16812 } 16813 16814 .change-value { 16815 font-weight: 600; 16816 } 16817 16818 .fund-nav-date { 16819 margin: 4px 0 0; 16820 font-size: 0.75rem; 16821 color: var(--fund-date-color); 16822 text-align: left; 16823 font-style: italic; 16824 } 16825 16826 @container fund-card (min-width: 450px) { 16827 .fund-card { 16828 grid-template-columns: 1fr auto; 16829 grid-template-areas: 16830 "name nav"; 16831 text-align: left; 16832 } 16833 16834 .name-container { 16835 text-align: left; 16836 padding-right: 8px; 16837 } 16838 16839 .nav-container { 16840 margin-top: 0; 16841 align-items: flex-end; 16842 text-align: right; 16843 } 16844 16845 .fund-nav-date { 16846 text-align: right; 16847 } 16848 } 16849 `; 16850 Ht([ 16851 $({ type: String }) 16852 ], Mt.prototype, "isin", 2); 16853 Ht([ 16854 $({ type: String }) 16855 ], Mt.prototype, "locale", 2); 16856 Ht([ 16857 $({ type: String, attribute: "header-level" }) 16858 ], Mt.prototype, "headerLevel", 2); 16859 Ht([ 16860 C() 16861 ], Mt.prototype, "lastFetchedIsin", 2); 16862 Ht([ 16863 C() 16864 ], Mt.prototype, "fetchInProgress", 2); 16865 Ht([ 16866 C() 16867 ], Mt.prototype, "fullFundData", 2); 16868 Ht([ 16869 C() 16870 ], Mt.prototype, "ytdReturn", 2); 16871 Mt = Ht([ 16872 lt(), 16873 it("fund-short-quote") 16874 ], Mt); 16875 var dc = Object.defineProperty; 16876 var uc = Object.getOwnPropertyDescriptor; 16877 var Ks = (s, t, e, i) => { 16878 for (var r = i > 1 ? void 0 : i ? uc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 16879 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 16880 return i && r && dc(t, e, r), r; 16881 }; 16882 var qe = class extends st { 16883 constructor() { 16884 super(...arguments), this.lastFetchedIsin = null, this.fetchInProgress = false; 16885 } 16886 fetchData() { 16887 return L(this, null, function* () { 16888 var s; 16889 if (this.isin && !(this.fetchInProgress || this.lastFetchedIsin === this.isin && this.fundData)) { 16890 this.loading = true, this.error = null, this.fetchInProgress = true; 16891 try { 16892 const t = q.API_BASE_URL, e = `${t}/funds/product/${encodeURIComponent(this.isin)}/statistic`, i = this.showHeader ? [ 16893 R(e), 16894 R(`${t}/funds/product/${encodeURIComponent(this.isin)}`) 16895 ] : [R(e)], r = yield Promise.all(i); 16896 if (!r[0].ok) 16897 throw new Error(u(A`Error al obtener estadÃsticas del fondo: ${r[0].statusText}`, { 16898 desc: "Error message when statistics API request fails" 16899 })); 16900 const n = yield r[0].json(); 16901 if (this.showHeader && ((s = r[1]) != null && s.ok)) { 16902 const a = yield r[1].json(); 16903 this.processData(G(M({}, n), { 16904 name: a == null ? void 0 : a.name 16905 })); 16906 } else 16907 this.processData(n); 16908 this.lastFetchedIsin = this.isin; 16909 } catch (t) { 16910 this.error = t instanceof Error ? t.message : u("Error desconocido", { 16911 desc: "Generic error message", 16912 id: "fund-statistics.error.unknown" 16913 }), console.error(u("Error al obtener estad\xEDsticas del fondo:", { desc: "Console error message prefix" }), t); 16914 } finally { 16915 this.loading = false, this.fetchInProgress = false;
16916 } 16917 } 16918 }); 16919 } 16920 updated(s) { 16921 super.updated(s), s.has("isin") && this.isin !== this.lastFetchedIsin && this.fetchData(); 16922 } 16923 processData(s) { 16924 this.fundData = s; 16925 } 16926 renderLoading() { 16927 return g`<div class="loading">${u("Cargando estad\xEDsticas del fondo...", { 16928 desc: "Loading message when fetching fund statistics" 16929 })}</div>`; 16930 } 16931 getQuartileIndicator(s) { 16932 return s ? s <= 1 ? "quartile-1" : s <= 2 ? "quartile-2" : s <= 3 ? "quartile-3" : "quartile-4" : ""; 16933 } 16934 getRiskLevel(s) { 16935 return s ? s < 0.1 ? "risk-low" : s < 0.2 ? "risk-medium" : "risk-high" : ""; 16936 } 16937 getRiskLabel(s) { 16938 return s ? s < 0.1 ? u("Bajo", { desc: "Low risk label" }) : s < 0.2 ? u("Medio", { desc: "Medium risk label" }) : u("Alto", { desc: "High risk label" }) : ""; 16939 } 16940 renderContent() { 16941 var t, e, i; 16942 if (!this.fundData) 16943 return null; 16944 const s = this.fundData.stats; 16945 return g` 16946 <div class="info-container"> 16947 ${this.renderHeader()} 16948 16949 <div class="section-title">${u("Rentabilidades por Periodo", { desc: "Returns by period section title" })}</div> 16950 16951 <div class="returns-period-grid"> 16952 ${s.return1m !== void 0 ? g` 16953 <div class="period-return"> 16954 <div class="period-label">${u("1 Mes", { desc: "1 month label" })}</div> 16955 <div class="period-value ${this.getValueClass(s.return1m)}">${this.formatPercentage(s.return1m)}</div> 16956 </div> 16957 ` : ""} 16958 16959 ${s.return3m !== void 0 ? g` 16960 <div class="period-return"> 16961 <div class="period-label">${u("3 Meses", { desc: "3 months label" })}</div> 16962 <div class="period-value ${this.getValueClass(s.return3m)}">${this.formatPercentage(s.return3m)}</div> 16963 </div> 16964 ` : ""} 16965 16966 ${s.return6m !== void 0 ? g` 16967 <div class="period-return"> 16968 <div class="period-label">${u("6 Meses", { desc: "6 months label" })}</div> 16969 <div class="period-value ${this.getValueClass(s.return6m)}">${this.formatPercentage(s.return6m)}</div> 16970 </div> 16971 ` : ""} 16972 16973 ${s.return1y !== void 0 ? g` 16974 <div class="period-return"> 16975 <div class="period-label">${u("1 A\xF1o", { desc: "1 year label" })}</div> 16976 <div class="period-value ${this.getValueClass(s.return1y)}">${this.formatPercentage(s.return1y)}</div> 16977 </div> 16978 ` : ""} 16979 16980 ${s.return3y !== void 0 ? g` 16981 <div class="period-return"> 16982 <div class="period-label">${u("3 A\xF1os", { desc: "3 years label" })}</div> 16983 <div class="period-value ${this.getValueClass(s.return3y)}">${this.formatPercentage(s.return3y)}</div> 16984 </div> 16985 ` : ""} 16986 16987 ${s.return5y !== void 0 ? g` 16988 <div class="period-return"> 16989 <div class="period-label">${u("5 A\xF1os", { desc: "5 years label" })}</div> 16990 <div class="period-value ${this.getValueClass(s.return5y)}">${this.formatPercentage(s.return5y)}</div> 16991 </div> 16992 ` : ""} 16993 16994 ${s.return10y !== void 0 ? g` 16995 <div class="period-return"> 16996 <div class="period-label">${u("10 A\xF1os", { desc: "10 years label" })}</div> 16997 <div class="period-value ${this.getValueClass(s.return10y)}">${this.formatPercentage(s.return10y)}</div> 16998 </div> 16999 ` : ""} 17000 17001 ${((t = s.returnYtd) == null ? void 0 : t.value) !== void 0 ? g` 17002 <div class="period-return"> 17003 <div class="period-label"> 17004 ${s.returnYtd.date && new Date(s.returnYtd.date).getFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? u(A`YTD (${this.formatDate(s.returnYtd.date)})`, { desc: "Year to date with date label" }) : u("YTD", { desc: "Year to date label", id: "fund-statistics.ytd-label" })} 17005 </div> 17006 <div class="period-value ${this.getValueClass(s.returnYtd.value)}"> 17007 ${s.returnYtd.date && new Date(s.returnYtd.date).getFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? this.formatPercentage(s.returnYtd.value) : "-"} 17008 </div> 17009 </div> 17010 ` : ""} 17011 </div> 17012 17013 <div class="section-title">${u("An\xE1lisis de Riesgo", { desc: "Risk analysis section title" })}</div> 17014 17015 <div class="stats-grid"> 17016 ${s.deviation1y !== void 0 ? g` 17017 <div class="stat-item"> 17018 <div class="stat-label">${u("Desviaci\xF3n Est\xE1ndar (1 a\xF1o)", { desc: "Standard deviation 1 year label" })}</div> 17019 <div class="stat-value"> 17020 ${this.formatPercentage(s.deviation1y)}
17021 <span class="risk-indicator ${this.getRiskLevel(s.deviation1y)}"> 17022 ${this.getRiskLabel(s.deviation1y)} 17023 </span> 17024 </div> 17025 </div> 17026 ` : ""} 17027 17028 ${s.deviation3y !== void 0 ? g` 17029 <div class="stat-item"> 17030 <div class="stat-label">${u("Desviaci\xF3n Est\xE1ndar (3 a\xF1os)", { desc: "Standard deviation 3 years label" })}</div> 17031 <div class="stat-value"> 17032 ${this.formatPercentage(s.deviation3y)} 17033 <span class="risk-indicator ${this.getRiskLevel(s.deviation3y)}"> 17034 ${this.getRiskLabel(s.deviation3y)} 17035 </span> 17036 </div> 17037 </div> 17038 ` : ""} 17039 17040 ${((e = s.maxDrawdownRatio5y) == null ? void 0 : e.value) !== void 0 ? g` 17041 <div class="stat-item"> 17042 <div class="stat-label">${u("M\xE1xima Ca\xEDda (5 a\xF1os)", { desc: "Maximum drawdown 5 years label" })}</div> 17043 <div class="stat-value negative">${this.formatPercentage(s.maxDrawdownRatio5y.value)}</div> 17044 </div> 17045 ` : ""} 17046 17047 ${((i = s.maxDrawdownDuration5yInMonths) == null ? void 0 : i.value) !== void 0 ? g` 17048 <div class="stat-item"> 17049 <div class="stat-label">${u("Duraci\xF3n M\xE1xima Ca\xEDda (meses)", { desc: "Maximum drawdown duration months label" })}</div> 17050 <div class="stat-value">${this.formatDecimal(s.maxDrawdownDuration5yInMonths.value, 0)}</div> 17051 </div> 17052 ` : ""} 17053 </div> 17054 17055 <div class="section-title">${u("Ratio de Sharpe", { desc: "Sharpe ratio metric" })}</div> 17056 17057 <div class="stats-grid"> 17058 ${s.sharpeRatio1y !== void 0 ? g` 17059 <div class="stat-item"> 17060 <div class="stat-label">${u("Ratio de Sharpe (1 a\xF1o)", { desc: "Sharpe ratio 1 year label" })}</div> 17061 <div class="stat-value ${this.getValueClass(s.sharpeRatio1y)}">${this.formatDecimal(s.sharpeRatio1y, 2)}</div> 17062 </div> 17063 ` : ""} 17064 17065 ${s.sharpeRatio3y !== void 0 ? g` 17066 <div class="stat-item"> 17067 <div class="stat-label">${u("Ratio de Sharpe (3 a\xF1os)", { desc: "Sharpe ratio 3 years label" })}</div> 17068 <div class="stat-value ${this.getValueClass(s.sharpeRatio3y)}">${this.formatDecimal(s.sharpeRatio3y, 2)}</div> 17069 </div> 17070 ` : ""} 17071 17072 ${s.sharpeRatio5y !== void 0 ? g` 17073 <div class="stat-item"> 17074 <div class="stat-label">${u("Ratio de Sharpe (5 a\xF1os)", { desc: "Sharpe ratio 5 years label" })}</div> 17075 <div class="stat-value ${this.getValueClass(s.sharpeRatio5y)}">${this.formatDecimal(s.sharpeRatio5y, 2)}</div> 17076 </div> 17077 ` : ""} 17078 </div> 17079 17080 ${s.performanceAcc1yQuartile !== void 0 || s.performanceAcc3yQuartile !== void 0 || s.performanceAcc5yQuartile !== void 0 ? g` 17081 <div class="section-title">${u("Ranking de Rendimiento", { desc: "Performance ranking section title" })}</div> 17082 17083 <div class="stats-grid"> 17084 ${s.performanceAcc1yQuartile !== void 0 ? g` 17085 <div class="stat-item"> 17086 <div class="stat-label">${u("Cuartil (1 a\xF1o)", { desc: "Quartile 1 year label" })}</div> 17087 <div class="stat-value"> 17088 ${s.performanceAcc1yQuartile} 17089 <span class="quartile-indicator ${this.getQuartileIndicator(s.performanceAcc1yQuartile)}"> 17090 Q${Math.ceil(s.performanceAcc1yQuartile)} 17091 </span> 17092 </div> 17093 </div> 17094 ` : ""} 17095 17096 ${s.performanceAcc3yQuartile !== void 0 ? g` 17097 <div class="stat-item"> 17098 <div class="stat-label">${u("Cuartil (3 a\xF1os)", { desc: "Quartile 3 years label" })}</div> 17099 <div class="stat-value"> 17100 ${s.performanceAcc3yQuartile} 17101 <span class="quartile-indicator ${this.getQuartileIndicator(s.performanceAcc3yQuartile)}"> 17102 Q${Math.ceil(s.performanceAcc3yQuartile)} 17103 </span> 17104 </div> 17105 </div> 17106 ` : ""} 17107 17108 ${s.performanceAcc5yQuartile !== void 0 ? g` 17109 <div class="stat-item"> 17110 <div class="stat-label">${u("Cuartil (5 a\xF1os)", { desc: "Quartile 5 years label" })}</div> 17111 <div class="stat-value"> 17112 ${s.performanceAcc5yQuartile}
17113 <span class="quartile-indicator ${this.getQuartileIndicator(s.performanceAcc5yQuartile)}"> 17114 Q${Math.ceil(s.performanceAcc5yQuartile)} 17115 </span> 17116 </div> 17117 </div> 17118 ` : ""} 17119 </div> 17120 ` : ""} 17121 </div> 17122 `; 17123 } 17124 }; 17125 qe.styles = K` 17126 ${nt(Ns)} 17127 17128 .info-container { 17129 width: 100%; 17130 display: block; 17131 } 17132 17133 .stats-grid { 17134 display: grid; 17135 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 17136 gap: 1rem; 17137 margin-top: 20px; 17138 } 17139 17140 .section-title { 17141 font-size: var(--stock-section-title-font-size, 1.1rem); 17142 font-weight: var(--stock-title-weight, 700); 17143 color: var(--stock-title-color, #1e293b); 17144 margin: 25px 0 15px 0; 17145 border-bottom: 1px solid var(--stock-border-color, #e0e0e0); 17146 padding-bottom: 5px; 17147 } 17148 17149 .section-title:first-of-type { 17150 margin-top: 15px; 17151 } 17152 17153 .stat-item { 17154 background: var(--stock-detail-background, #f8fafc); 17155 border: 1px solid var(--stock-detail-border, rgba(226, 232, 240, 0.6)); 17156 border-radius: 12px; 17157 padding: 16px; 17158 transition: box-shadow 0.2s ease; 17159 } 17160 17161 .stat-item:hover { 17162 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 17163 } 17164 17165 .stat-label { 17166 font-size: var(--stock-text-size, 14px); 17167 color: var(--stock-muted-color, #64748b); 17168 margin-bottom: 8px; 17169 font-weight: var(--stock-value-weight, 500); 17170 } 17171 17172 .stat-value { 17173 font-size: var(--stock-value-size, 18px); 17174 font-weight: var(--stock-title-weight, 600); 17175 color: var(--stock-value-color, #334155); 17176 } 17177 17178 .stat-value.positive { 17179 color: var(--stock-positive-color, #388e3c); 17180 } 17181 17182 .stat-value.negative { 17183 color: var(--stock-negative-color, #d32f2f); 17184 } 17185 17186 .quartile-indicator { 17187 font-size: var(--stock-small-text-size, 12px); 17188 padding: 2px 6px; 17189 border-radius: 10px; 17190 margin-left: 8px; 17191 } 17192 17193 .quartile-1 { 17194 background-color: rgba(56, 142, 60, 0.1); 17195 color: var(--stock-positive-color, #388e3c); 17196 } 17197 17198 .quartile-2 { 17199 background-color: rgba(245, 124, 0, 0.1); 17200 color: var(--stock-warning-color, #f57c00); 17201 } 17202 17203 .quartile-3 { 17204 background-color: rgba(194, 24, 91, 0.1); 17205 color: var(--stock-negative-color, #d32f2f); 17206 } 17207 17208 .quartile-4 { 17209 background-color: rgba(211, 47, 47, 0.1); 17210 color: var(--stock-negative-color, #d32f2f); 17211 } 17212 17213 .risk-indicator { 17214 display: inline-block; 17215 padding: 4px 8px; 17216 border-radius: 4px; 17217 font-size: var(--stock-small-text-size, 12px); 17218 font-weight: var(--stock-value-weight, 500); 17219 margin-left: 8px; 17220 } 17221 17222 .risk-low { 17223 background-color: rgba(56, 142, 60, 0.1); 17224 color: var(--stock-positive-color, #388e3c); 17225 } 17226 17227 .risk-medium { 17228 background-color: rgba(245, 124, 0, 0.1); 17229 color: var(--stock-warning-color, #f57c00); 17230 } 17231 17232 .risk-high { 17233 background-color: rgba(211, 47, 47, 0.1); 17234 color: var(--stock-negative-color, #d32f2f); 17235 } 17236 17237 .returns-period-grid { 17238 display: grid; 17239 grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); 17240 gap: 0.8rem; 17241 margin-top: 15px; 17242 } 17243 17244 .period-return { 17245 text-align: center; 17246 padding: 12px 8px; 17247 background: var(--stock-detail-background, #f8fafc); 17248 border: 1px solid var(--stock-detail-border, rgba(226, 232, 240, 0.6)); 17249 border-radius: 6px; 17250 } 17251 17252 .period-label { 17253 font-size: var(--stock-small-text-size, 12px); 17254 color: var(--stock-muted-color, #64748b); 17255 margin-bottom: 4px; 17256 font-weight: var(--stock-value-weight, 500); 17257 } 17258 17259 .period-value { 17260 font-size: var(--stock-value-size, 16px); 17261 font-weight: var(--stock-title-weight, 600); 17262 } 17263 17264 @media (max-width: 600px) { 17265 .stats-grid { 17266 grid-template-columns: 1fr; 17267 } 17268 17269 .returns-period-grid { 17270 grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 17271 } 17272 } 17273 `; 17274 Ks([ 17275 C() 17276 ], qe.prototype, "lastFetchedIsin", 2); 17277 Ks([ 17278 C() 17279 ], qe.prototype, "fetchInProgress", 2); 17280 qe = Ks([ 17281 lt(), 17282 it("fund-statistics") 17283 ], qe); 17284 var fc = Object.defineProperty; 17285 var mc = Object.getOwnPropertyDescriptor; 17286 var _e = (s, t, e, i) => { 17287 for (var r = i > 1 ? void 0 : i ? mc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 17288 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 17289 return i && r && fc(t, e, r), r; 17290 }; 17291 var jt = class extends kt { 17292 constructor() { 17293 super(...arguments), this.isins = "", this.locale = "", this.lastFetchedIsins = null, this.fetchInProgress = false, this.isAtScrollEnd = false;
17294 } 17295 shouldFetchData() { 17296 return !!this.isins && this.isins.trim().length > 0; 17297 } 17298 hasKeyPropertyChanged(s) { 17299 return s.has("isins") && !!this.isins; 17300 } 17301 fetchData() { 17302 return L(this, null, function* () { 17303 if (this.isins && !(this.fetchInProgress || this.lastFetchedIsins === this.isins && this.data)) { 17304 this.loading = true, this.error = null, this.fetchInProgress = true; 17305 try { 17306 const t = this.isins.split(",").map((i) => i.trim()).filter((i) => i).map((i) => L(this, null, function* () { 17307 var d, f, m, p; 17308 const [r, n] = yield Promise.all([ 17309 R(`${q.API_BASE_URL}/funds/product/${encodeURIComponent(i)}`), 17310 R(`${q.API_BASE_URL}/funds/product/${encodeURIComponent(i)}/statistic`) 17311 ]); 17312 let a, o, l, h, c; 17313 if (r.ok) { 17314 const v = yield r.json(); 17315 a = v.name, o = (d = v.mainCategory) == null ? void 0 : d.name; 17316 } 17317 if (n.ok) { 17318 const v = yield n.json(); 17319 l = (f = v.stats) == null ? void 0 : f.return1y, h = (m = v.stats) == null ? void 0 : m.return3y, c = (p = v.stats) == null ? void 0 : p.return5y; 17320 } 17321 return { 17322 isin: i, 17323 name: a, 17324 category: o, 17325 return1y: l, 17326 return3y: h, 17327 return5y: c 17328 }; 17329 })), e = yield Promise.all(t); 17330 this.processData({ funds: e }), this.lastFetchedIsins = this.isins; 17331 } catch (s) { 17332 this.error = s instanceof Error ? s.message : u("Error desconocido", { 17333 desc: "Generic error message", 17334 id: "funds-table.error.unknown" 17335 }), console.error("Error fetching funds table data:", s); 17336 } finally { 17337 this.loading = false, this.fetchInProgress = false; 17338 } 17339 } 17340 }); 17341 } 17342 updated(s) { 17343 super.updated(s), s.has("isins") && this.isins !== this.lastFetchedIsins && this.fetchData(), this.updateComplete.then(() => this.checkScrollPosition()); 17344 } 17345 processData(s) { 17346 this.data = s; 17347 } 17348 getNoDataMessage() { 17349 return u("No hay datos disponibles. Por favor, proporcione c\xF3digos ISIN v\xE1lidos.", { 17350 desc: "Message shown when no fund data is available", 17351 id: "funds-table.no-data" 17352 }); 17353 } 17354 renderHeader() { 17355 return null; 17356 } 17357 formatReturn(s, t) { 17358 if (s == null) 17359 return "-"; 17360 const e = qt(s, t); 17361 return F.formatPercentage(e, this.locale || "es-ES"); 17362 } 17363 renderLoading() { 17364 return g`<div class="loading">${u("Cargando datos de fondos...", { 17365 desc: "Loading message when fetching funds table data", 17366 id: "funds-table.loading" 17367 })}</div>`; 17368 } 17369 renderError() { 17370 return g`<div class="error">${this.error}</div>`; 17371 } 17372 renderNoData() { 17373 return g`<div class="no-data">${this.getNoDataMessage()}</div>`; 17374 } 17375 renderContent() { 17376 if (!this.data || !this.data.funds || this.data.funds.length === 0) 17377 return this.renderNoData(); 17378 const s = (/* @__PURE__ */ new Date()).toISOString(); 17379 return g` 17380 <div class="table-wrapper ${this.isAtScrollEnd ? "scroll-end" : ""}"> 17381 <div class="table-container" @scroll=${this.handleScroll}> 17382 <div class="table-header"> 17383 <div class="table-header-cell fund-column">${u("Fondo", { desc: "Fund column header", id: "funds-table.header.fund" })}</div> 17384 <div class="table-header-cell return-column">${u("Rent. 1 a\xF1o", { desc: "Return 1 year column header", id: "funds-table.header.return-1y" })}</div> 17385 <div class="table-header-cell return-column">${u("Rent. 3 a\xF1os", { desc: "Return 3 years column header", id: "funds-table.header.return-3y" })}</div> 17386 <div class="table-header-cell return-column">${u("Rent. 5 a\xF1os", { desc: "Return 5 years column header", id: "funds-table.header.return-5y" })}</div> 17387 <div class="table-header-cell update-column">${u("Datos actualizados", { desc: "Data updated column header", id: "funds-table.header.last-update" })}</div> 17388 </div> 17389 ${this.data.funds.map((t) => this.renderRow(t, s))} 17390 </div> 17391 </div> 17392 <div class="info-disclaimer"> 17393 <div class="info-icon">i</div> 17394 <div> 17395 <div class="disclaimer-text"> 17396 ${u("Rentabilidades pasadas no garantizan resultados futuros. Rentabilidades anualizadas para periodos superiores a 1 a\xF1o.", { 17397 id: "disclaimer.past-returns", 17398 desc: "Past returns disclaimer text" 17399 })} 17400 </div> 17401 </div> 17402 </div> 17403 `; 17404 } 17405 renderRow(s, t) { 17406 const e = qt(s.return3y, "3y"), i = qt(s.return5y, "5y"); 17407 return g` 17408 <div class="table-row"> 17409 <div class="table-cell fund-column">
17410 <span class="fund-name">${s.name || s.isin}</span> 17411 <span class="fund-isin">${s.isin}</span> 17412 </div> 17413 <div class="table-cell return-column ${this.getValueClass(s.return1y)}">${this.formatReturn(s.return1y, "1y")}</div> 17414 <div class="table-cell return-column ${this.getValueClass(e)}">${this.formatReturn(s.return3y, "3y")}</div> 17415 <div class="table-cell return-column ${this.getValueClass(i)}">${this.formatReturn(s.return5y, "5y")}</div> 17416 <div class="table-cell update-column">${this.formatDate(t)}</div> 17417 </div> 17418 `; 17419 } 17420 handleScroll(s) { 17421 const t = s.target, e = 2; 17422 this.isAtScrollEnd = t.scrollLeft + t.clientWidth >= t.scrollWidth - e; 17423 } 17424 checkScrollPosition() { 17425 var t; 17426 const s = (t = this.shadowRoot) == null ? void 0 : t.querySelector(".table-container"); 17427 s && (this.isAtScrollEnd = s.scrollLeft + s.clientWidth >= s.scrollWidth - 2); 17428 } 17429 }; 17430 jt.styles = K` 17431 :host { 17432 display: block; 17433 font-family: var(--fund-font-family, 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 17434 width: 100%; 17435 box-sizing: border-box; 17436 } 17437 17438 .table-container { 17439 width: 100%; 17440 box-shadow: var(--shadow-faded, 0px 0px 30px 5px rgba(0, 0, 0, 0.07)); 17441 border-radius: 8px; 17442 overflow: hidden; 17443 } 17444 17445 .table-header { 17446 display: flex; 17447 align-items: center; 17448 background: var(--Primary-colors-color-primary, #0C3852); 17449 border-radius: 8px 8px 0 0; 17450 } 17451 17452 .table-header-cell { 17453 padding: 12px 10px; 17454 font-size: 14px; 17455 font-weight: 400; 17456 color: var(--Neutral-colors-color-neutral-0, #FFFFFF); 17457 line-height: 21px; 17458 box-sizing: border-box; 17459 } 17460 17461 .table-header-cell.fund-column { 17462 flex: 1; 17463 } 17464 17465 .table-header-cell.return-column { 17466 width: 115px; 17467 text-align: center; 17468 } 17469 17470 .table-header-cell.update-column { 17471 width: 130px; 17472 text-align: center; 17473 } 17474 17475 .table-row { 17476 display: flex; 17477 align-items: center; 17478 background-color: var(--Neutral-colors-color-neutral-0, #FFFFFF); 17479 border: 1px solid var(--superlightgray, #E6E6E6); 17480 border-top: none; 17481 } 17482 17483 .table-row:first-of-type { 17484 border-top: 1px solid var(--superlightgray, #E6E6E6); 17485 } 17486 17487 .table-row:last-child { 17488 border-radius: 0 0 8px 8px; 17489 } 17490 17491 .table-cell { 17492 padding: 12px 10px; 17493 font-size: 14px; 17494 line-height: 21px; 17495 box-sizing: border-box; 17496 } 17497 17498 .table-cell.fund-column { 17499 flex: 1; 17500 display: flex; 17501 flex-direction: column; 17502 gap: 4px; 17503 padding-top: 8px; 17504 padding-bottom: 12px; 17505 } 17506 17507 .fund-name { 17508 font-weight: 600; 17509 color: var(--Neutral-colors-color-neutral-1, #4F5862); 17510 } 17511 17512 .fund-isin { 17513 display: inline-block; 17514 background-color: var(--Neutral-colors-color-neutral-3, #EBF4F9); 17515 padding: 6px; 17516 border-radius: 4px; 17517 font-weight: 500; 17518 color: var(--maintext, #636363); 17519 text-align: center; 17520 width: fit-content; 17521 } 17522 17523 .table-cell.return-column { 17524 width: 115px; 17525 text-align: center; 17526 font-weight: 400; 17527 } 17528 17529 .table-cell.update-column { 17530 width: 130px; 17531 text-align: center; 17532 font-weight: 400; 17533 color: var(--maintext, #636363); 17534 } 17535 17536 .positive { 17537 color: var(--Semantic-colors-color-success, #077D44); 17538 } 17539 17540 .negative { 17541 color: var(--Primary-colors-color-accent, #C73048); 17542 } 17543 17544 .loading { 17545 display: flex; 17546 align-items: center; 17547 justify-content: center; 17548 padding: 30px; 17549 font-size: 14px; 17550 color: var(--Neutral-colors-color-neutral-1, #4F5862); 17551 font-weight: 500; 17552 } 17553 17554 .loading::before { 17555 content: ''; 17556 display: block; 17557 width: 24px; 17558 height: 24px; 17559 margin-right: 12px; 17560 border: 3px solid var(--Primary-colors-color-primary, #0C3852); 17561 border-radius: 50%; 17562 border-top-color: transparent; 17563 animation: spinner 0.8s linear infinite; 17564 } 17565
17566 @keyframes spinner { 17567 to { transform: rotate(360deg); } 17568 } 17569 17570 .error { 17571 color: var(--Primary-colors-color-accent, #C73048); 17572 padding: 16px; 17573 border: 1px solid rgba(199, 48, 72, 0.2); 17574 border-radius: 12px; 17575 font-size: 14px; 17576 font-weight: 500; 17577 background-color: rgba(199, 48, 72, 0.05); 17578 text-align: center; 17579 } 17580 17581 .no-data { 17582 padding: 30px; 17583 text-align: center; 17584 color: var(--Neutral-colors-color-neutral-1, #4F5862); 17585 font-size: 14px; 17586 } 17587 17588 /* Responsive styles */ 17589 @media (max-width: 768px) { 17590 .table-wrapper { 17591 position: relative; 17592 width: 100%; 17593 clip-path: inset(-30px 0 -30px -30px); 17594 } 17595 17596 .table-wrapper.scroll-end { 17597 clip-path: inset(-30px -30px -30px -30px); 17598 } 17599 17600 .table-wrapper::after { 17601 content: ''; 17602 position: absolute; 17603 top: 0; 17604 bottom: 0; 17605 right: 0; 17606 width: 40px; 17607 background: linear-gradient(to left, 17608 var(--Neutral-colors-color-neutral-0, #FFF) 0px, 17609 rgba(255, 255, 255, 0.9) 10px, 17610 rgba(255, 255, 255, 0) 100% 17611 ); 17612 pointer-events: none; 17613 z-index: 2; 17614 opacity: 1; 17615 transition: opacity 0.2s ease; 17616 } 17617 17618 .table-wrapper.scroll-end::after { 17619 opacity: 0; 17620 } 17621 17622 .table-container { 17623 overflow-x: auto; 17624 -webkit-overflow-scrolling: touch; 17625 width: fit-content; 17626 max-width: 100%; 17627 } 17628 17629 .table-header, 17630 .table-row { 17631 min-width: max-content; 17632 } 17633 17634 .table-header-cell.fund-column, 17635 .table-cell.fund-column { 17636 position: sticky; 17637 left: 0; 17638 z-index: 1; 17639 width: 138px; 17640 min-width: 130px; 17641 flex: none; 17642 } 17643 17644 .table-header-cell.fund-column { 17645 background-color: var(--Primary-colors-color-primary, #0C3852); 17646 } 17647 17648 .table-cell.fund-column { 17649 background-color: var(--Neutral-colors-color-neutral-0, #FFFFFF); 17650 box-shadow: 0 0 30px 5px rgba(0, 0, 0, 0.07); 17651 } 17652 17653 .table-header-cell.return-column, 17654 .table-cell.return-column, 17655 .table-header-cell.update-column, 17656 .table-cell.update-column { 17657 width: 100px; 17658 min-width: 100px; 17659 } 17660 17661 /* Cropped right corners during scroll */ 17662 .table-container { 17663 border-radius: 8px 0 0 8px; 17664 } 17665 17666 .table-header { 17667 border-radius: 8px 0 0 0; 17668 } 17669 17670 .table-row:last-child { 17671 border-radius: 0 0 0 8px; 17672 } 17673 17674 /* Restore right corners at scroll end */ 17675 .table-wrapper.scroll-end .table-container { 17676 border-radius: 8px; 17677 } 17678 17679 .table-wrapper.scroll-end .table-header { 17680 border-radius: 8px 8px 0 0; 17681 } 17682 17683 .table-wrapper.scroll-end .table-row:last-child { 17684 border-radius: 0 0 8px 8px; 17685 } 17686 } 17687 17688 .info-disclaimer { 17689 display: flex; 17690 align-items: flex-start; 17691 gap: 8px; 17692 margin-top: 20px; 17693 } 17694 17695 .info-icon { 17696 width: 16px; 17697 height: 16px; 17698 color: var(--stock-accent-color, #58A8DA); 17699 border-radius: 50%; 17700 display: flex; 17701 align-items: center; 17702 justify-content: center; 17703 font-size: 12px; 17704 font-weight: bold; 17705 flex-shrink: 0; 17706 margin-top: 2px; 17707 border: 1px solid var(--stock-accent-color, #58A8DA); 17708 } 17709 17710 .disclaimer-text { 17711 font-size: var(--stock-small-text-size, 14px); 17712 color: var(--stock-muted-color, #383D43); 17713 line-height: 1.4; 17714 } 17715 17716 .update-date { 17717 font-size: var(--stock-small-text-size, 14px); 17718 color: var(--stock-muted-color, #383D43); 17719 margin-top: 4px; 17720 } 17721 `; 17722 _e([ 17723 $({ type: String }) 17724 ], jt.prototype, "isins", 2); 17725 _e([ 17726 $({ type: String }) 17727 ], jt.prototype, "locale", 2); 17728 _e([ 17729 C() 17730 ], jt.prototype, "lastFetchedIsins", 2); 17731 _e([ 17732 C() 17733 ], jt.prototype, "fetchInProgress", 2); 17734 _e([ 17735 C() 17736 ], jt.prototype, "isAtScrollEnd", 2); 17737 jt = _e([ 17738 lt(), 17739 it("funds-table") 17740 ], jt); 17741 var pc = Object.defineProperty; 17742 var gc = Object.getOwnPropertyDescriptor; 17743 var Tt = (s, t, e, i) => { 17744 for (var r = i > 1 ? void 0 : i ? gc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 17745 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 17746 return i && r && pc(t, e, r), r; 17747 }; 17748 var xt = class extends $t { 17749 constructor() { 17750 super(...arguments), this.targets = "", this.isOpen = false, this.searchType = "name", this.queryValue = "", this.error = null, this.results = [], this.selectedBenchmark = null, this.rememberedBenchmark = null, this.debounceTimer = null, this.DEBOUNCE_DELAY = 300; 17751 } 17752 /** 17753 * Update host attribute when selected state changes and init horizontal scroll 17754 */ 17755 updated(s) { 17756 s.has("selectedBenchmark") && (this.selectedBenchmark ? this.setAttribute("selected", "") : this.removeAttribute("selected")), s.has("isOpen") && (this.isOpen ? this.setAttribute("open", "") : this.removeAttribute("open")), s.has("isOpen") && this.isOpen && requestAnimationFrame(() => { 17757 yt(this); 17758 }); 17759 } 17760 /** 17761 * Handle toggle switch click 17762 */ 17763 handleToggle() { 17764 this.isOpen || this.selectedBenchmark ? (this.selectedBenchmark && (this.rememberedBenchmark = this.selectedBenchmark), this.selectedBenchmark = null, this.isOpen = false, this.clearSearch(), this.unapplyBenchmark()) : this.rememberedBenchmark ? (this.selectedBenchmark = this.rememberedBenchmark, this.applyBenchmark(this.rememberedBenchmark), this.isOpen = false) : this.isOpen = true; 17765 } 17766 /** 17767 * Set the search type (tab selection) 17768 */ 17769 setSearchType(s) { 17770 this.searchType = s, this.clearSearch(); 17771 } 17772 /** 17773 * Clear search state 17774 */ 17775 clearSearch() { 17776 this.queryValue = "", this.results = [], this.error = null, this.debounceTimer && (clearTimeout(this.debounceTimer), this.debounceTimer = null); 17777 } 17778 /** 17779 * Handle keydown to prevent Enter from creating new lines 17780 */ 17781 handleKeyDown(s) { 17782 s.key === "Enter" && s.preventDefault(); 17783 } 17784 /** 17785 * Handle input change with debouncing 17786 */ 17787 handleInputChange(s) { 17788 const t = s.target; 17789 this.queryValue = t.value, this.error = null, t.style.height = "auto", t.style.height = t.scrollHeight + "px", this.debounceTimer && clearTimeout(this.debounceTimer), this.queryValue.trim().length >= 3 ? this.debounceTimer = window.setTimeout(() => { 17790 this.performSearch(); 17791 }, this.DEBOUNCE_DELAY) : this.results = []; 17792 } 17793 /** 17794 * Get the API endpoint based on search type 17795 */ 17796 getEndpoint() { 17797 return { 17798 name: { path: "/asset-data/search-by-name", param: "name" }, 17799 ticker: { path: "/asset-data/search-by-symbol", param: "symbol" }, 17800 isin: { path: "/asset-data/search-by-isin", param: "isin" } 17801 }[this.searchType]; 17802 } 17803 /** 17804 * Get placeholder text based on search type 17805 */ 17806 getPlaceholder() { 17807 return { 17808 name: u("Escribe el nombre de un benchmark (Ejemplo: S&P 500, NASDAQ, etc.)", { 17809 desc: "Placeholder for name search", 17810 id: "benchmark-selector.placeholder-name" 17811 }), 17812 ticker: u("Escribe el s\xEDmbolo del ticker (Ejemplo: AAPL)", { 17813 desc: "Placeholder for ticker search", 17814 id: "benchmark-selector.placeholder-ticker" 17815 }), 17816 isin: u("Escribe un c\xF3digo ISIN (Ejemplo: US0378331005)", { 17817 desc: "Placeholder for ISIN search", 17818 id: "benchmark-selector.placeholder-isin" 17819 }) 17820 }[this.searchType]; 17821 } 17822 /** 17823 * Perform the search API call 17824 */ 17825 performSearch() { 17826 return L(this, null, function* () { 17827 if (this.queryValue.trim()) { 17828 this.error = null; 17829 try { 17830 const { path: s, param: t } = this.getEndpoint(), e = encodeURIComponent(this.queryValue.trim()), i = `${q.API_BASE_URL}${s}?${t}=${e}`, r = yield R(i); 17831 if (!r.ok) 17832 throw new Error(u("Error al buscar benchmark", { 17833 desc: "Error message when search fails", 17834 id: "benchmark-selector.search-error" 17835 })); 17836 const n = yield r.json(); 17837 let a = []; 17838 Array.isArray(n) ? a = n : n && typeof n == "object" && (a = [n]); 17839 const o = a.filter((l) => l && l.name).map((l) => M({ 17840 isin: l.isin || "", 17841 symbol: l.symbol || "", 17842 name: l.name, 17843 currency: l.currency, 17844 exchange: l.exchange 17845 }, l)); 17846 o.length === 0 ? (this.error = u("No se encontraron benchmarks", { 17847 desc: "Message when no benchmarks found", 17848 id: "benchmark-selector.not-found" 17849 }), this.results = []) : this.results = o; 17850 } catch (s) { 17851 this.error = s instanceof Error ? s.message : u("Ocurri\xF3 un error al buscar", { 17852 desc: "Generic error message", 17853 id: "benchmark-selector.generic-error" 17854 }), this.results = []; 17855 } 17856 } 17857 }); 17858 } 17859 /** 17860 * Select a benchmark from results 17861 */ 17862 selectBenchmark(s) { 17863 this.selectedBenchmark = s, this.applyBenchmark(s), this.clearSearch(); 17864 } 17865 /** 17866 * Apply benchmark to target components 17867 */ 17868 applyBenchmark(s) { 17869 if (!s) 17870 return; 17871 const t = s.isin || s.symbol || ""; 17872 if (!t) { 17873 console.warn("No se pudo determinar el identificador del benchmark"); 17874 return; 17875 } 17876 if (!this.targets || !this.targets.trim()) { 17877 console.warn("El atributo targets no est\xE1 especificado"); 17878 return; 17879 } 17880 const e = this.targets.split(",").map((i) => i.trim()).filter((i) => i.length > 0); 17881 if (e.length === 0) { 17882 console.warn("No se especificaron componentes objetivo en el atributo targets"); 17883 return; 17884 } 17885 e.forEach((i) => { 17886 const r = document.querySelectorAll(i); 17887 r.length === 0 ? console.log(`Componente ${i} no encontrado en la p\xE1gina`) : r.forEach((n) => { 17888 n.setAttribute("benchmark", t), console.log(`Benchmark ${t}
17888 aplicado al componente ${i}`); 17889 }); 17890 }); 17891 } 17892 /** 17893 * Remove benchmark from target components 17894 */ 17895 unapplyBenchmark() { 17896 if (!this.targets || !this.targets.trim()) 17897 return; 17898 this.targets.split(",").map((t) => t.trim()).filter((t) => t.length > 0).forEach((t) => { 17899 document.querySelectorAll(t).forEach((i) => { 17900 i.removeAttribute("benchmark"); 17901 }); 17902 }); 17903 } 17904 /** 17905 * Handle edit button click - return to search mode 17906 */ 17907 handleEdit() { 17908 var t; 17909 const s = ((t = this.selectedBenchmark) == null ? void 0 : t.name) || ""; 17910 this.rememberedBenchmark = this.selectedBenchmark, this.selectedBenchmark = null, this.isOpen = true, this.queryValue = s, this.results = [], this.error = null; 17911 } 17912 /** 17913 * Render the info icon SVG 17914 */ 17915 renderInfoIcon() { 17916 return g` 17917 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 17918 <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.5"/> 17919 <path d="M8 7V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> 17920 <circle cx="8" cy="5" r="0.75" fill="currentColor"/> 17921 </svg> 17922 `; 17923 } 17924 /** 17925 * Render the warning icon SVG 17926 */ 17927 renderWarningIcon() { 17928 return g` 17929 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 17930 <path d="M8.57514 3.21659L1.51681 14.9999C1.37128 15.2519 1.29428 15.5377 1.29346 15.8287C1.29265 16.1197 1.36805 16.4059 1.51216 16.6587C1.65627 16.9115 1.86408 17.1222 2.1149 17.2698C2.36571 17.4174 2.65081 17.4967 2.94181 17.4999H17.0585C17.3495 17.4967 17.6346 17.4174 17.8854 17.2698C18.1362 17.1222 18.344 16.9115 18.4881 16.6587C18.6322 16.4059 18.7076 16.1197 18.7068 15.8287C18.706 15.5377 18.629 15.2519 18.4835 14.9999L11.4251 3.21659C11.2766 2.97168 11.0674 2.76919 10.8178 2.62866C10.5682 2.48813 10.2866 2.41431 10.0001 2.41431C9.71369 2.41431 9.43208 2.48813 9.18248 2.62866C8.93287 2.76919 8.7237 2.97168 8.57514 3.21659Z" stroke="#383D43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 17931 <path d="M10 7.5V10.8333" stroke="#383D43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 17932 <path d="M10 14.1667H10.0083" stroke="#383D43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 17933 </svg> 17934 `; 17935 } 17936 /** 17937 * Render the edit icon SVG 17938 */ 17939 renderEditIcon() { 17940 return g` 17941 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 17942 <g clip-path="url(#clip0_edit)"> 17943 <path d="M9.1665 3.33325H3.33317C2.89114 3.33325 2.46722 3.50885 2.15466 3.82141C1.8421 4.13397 1.6665 4.55789 1.6665 4.99992V16.6666C1.6665 17.1086 1.8421 17.5325 2.15466 17.8451C2.46722 18.1577 2.89114 18.3333 3.33317 18.3333H14.9998C15.4419 18.3333 15.8658 18.1577 16.1783 17.8451C16.4909 17.5325 16.6665 17.1086 16.6665 16.6666V10.8333" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 17944 <path d="M15.4165 2.08344C15.748 1.75192 16.1977 1.56567 16.6665 1.56567C17.1353 1.56567 17.585 1.75192 17.9165 2.08344C18.248 2.41496 18.4343 2.8646 18.4343 3.33344C18.4343 3.80228 18.248 4.25192 17.9165 4.58344L9.99984 12.5001L6.6665 13.3334L7.49984 10.0001L15.4165 2.08344Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 17945 </g> 17946 <defs> 17947 <clipPath id="clip0_edit"> 17948 <rect width="20" height="20" fill="white"/> 17949 </clipPath> 17950 </defs> 17951 </svg> 17952 `; 17953 } 17954 /** 17955 * Render the toggle switch 17956 */ 17957 renderToggle() { 17958 return g` 17959 <div 17960 class="toggle-switch ${this.isOpen || this.selectedBenchmark ? "checked" : ""}" 17961 @click=${this.handleToggle} 17962 role="switch" 17963 aria-checked=${this.isOpen || this.selectedBenchmark ? "true" : "false"} 17964 tabindex="0" 17965 @keydown=${(s) => { 17966 (s.key === "Enter" || s.key === " ") && (s.preventDefault(), this.handleToggle()); 17967 }} 17968 ></div> 17969 `; 17970 } 17971 /**
17972 * Render closed state 17973 */ 17974 renderClosed() { 17975 return g` 17976 <div class="benchmark-selector--closed"> 17977 ${this.renderToggle()} 17978 <span class="benchmark-selector__label"> 17979 ${u("Comparar con benchmark", { 17980 desc: "Label for benchmark comparison toggle", 17981 id: "benchmark-selector.compare-label" 17982 })} 17983 </span> 17984 </div> 17985 `; 17986 } 17987 /** 17988 * Render open state (search mode) 17989 */ 17990 renderOpen() { 17991 return g` 17992 <div class="benchmark-selector--open"> 17993 <div class="benchmark-selector__header"> 17994 ${this.renderToggle()} 17995 <span class="benchmark-selector__label"> 17996 ${u("Comparar con benchmark", { 17997 desc: "Label for benchmark comparison toggle", 17998 id: "benchmark-selector.compare-label" 17999 })} 18000 </span> 18001 </div> 18002 18003 <div class="benchmark-selector__description-wrapper"> 18004 <p class="benchmark-selector__description"> 18005 ${u("Busca un benchmark para comparar el rendimiento del activo frente a \xEDndices u otros activos del mercado", { 18006 desc: "Description text for benchmark search", 18007 id: "benchmark-selector.description" 18008 })} 18009 </p> 18010 18011 <div class="benchmark-selector__info"> 18012 ${this.renderInfoIcon()} 18013 <span> 18014 ${u("El benchmark se aplicar\xE1 a toda la p\xE1gina.", { 18015 desc: "Info message about benchmark application", 18016 id: "benchmark-selector.info-message" 18017 })} 18018 </span> 18019 </div> 18020 </div> 18021 18022 <div class="benchmark-selector__search-wrapper"> 18023 <div class="horizontal-scroll-element"> 18024 <div class="horizontal-scroll-element-inner benchmark-selector__tabs"> 18025 <button 18026 class="benchmark-selector__tab ${this.searchType === "name" ? "active" : ""}" 18027 @click=${() => this.setSearchType("name")} 18028 > 18029 ${u("Buscar por nombre", { 18030 desc: "Search by name tab", 18031 id: "benchmark-selector.tab-name" 18032 })} 18033 </button> 18034 <button 18035 class="benchmark-selector__tab ${this.searchType === "ticker" ? "active" : ""}" 18036 @click=${() => this.setSearchType("ticker")} 18037 > 18038 ${u("Buscar por ticker", { 18039 desc: "Search by ticker tab", 18040 id: "benchmark-selector.tab-ticker" 18041 })} 18042 </button> 18043 <!-- ISIN tab hidden for now 18044 <button 18045 class="benchmark-selector__tab ${this.searchType === "isin" ? "active" : ""}" 18046 @click=${() => this.setSearchType("isin")} 18047 > 18048 ${u("Buscar por ISIN", { 18049 desc: "Search by ISIN tab", 18050 id: "benchmark-selector.tab-isin" 18051 })} 18052 </button> 18053 --> 18054 </div> 18055 </div> 18056 18057 <textarea 18058 class="benchmark-selector__input ${this.results.length > 0 ? "has-results" : ""}" 18059 .value=${this.queryValue} 18060 @input=${this.handleInputChange} 18061 @keydown=${this.handleKeyDown} 18062 placeholder=${this.getPlaceholder()} 18063 rows="1" 18064 ></textarea> 18065 18066 ${this.error ? g` 18067 <div class="benchmark-selector__error"> 18068 ${this.renderWarningIcon()} 18069 <span class="benchmark-selector__error-text"> 18070 ${u("No se ha encontrado ning\xFAn activo relacionado con tu b\xFAsqueda.", { 18071 desc: "Error message when no assets found", 18072 id: "benchmark-selector.not-found-error" 18073 })} 18074 </span> 18075 </div> 18076 ` : ""} 18077 18078 ${this.results.length > 0 ? g` 18079 <div class="benchmark-selector__results-wrapper"> 18080 <div class="benchmark-selector__results"> 18081 ${this.results.map((s) => g` 18082 <div 18083 class="benchmark-selector__result-item" 18084 @click=${() => this.selectBenchmark(s)} 18085 > 18086 <div class="benchmark-selector__result-name">${s.name}</div> 18087 ${s.currency || s.exchangeFullName ? g` 18088 <div class="benchmark-selector__result-details"> 18089 ${s.currency || ""}${s.currency && s.exchangeFullName ? " \xB7 " : ""}
18089${s.exchangeFullName || ""} 18090 </div> 18091 ` : ""} 18092 </div> 18093 `)} 18094 </div> 18095 </div> 18096 ` : ""} 18097 </div> 18098 </div> 18099 `; 18100 } 18101 /** 18102 * Render selected state 18103 */ 18104 renderSelected() { 18105 return this.selectedBenchmark ? g` 18106 <div class="benchmark-selector--selected"> 18107 ${this.renderToggle()} 18108 <div class="benchmark-selector__selected-content"> 18109 <span class="benchmark-selector__active-text"> 18110 ${u("Benchmark activo:", { 18111 desc: "Active benchmark label", 18112 id: "benchmark-selector.active-label" 18113 })} 18114 <strong>${this.selectedBenchmark.name}</strong> 18115 </span> 18116 <button class="benchmark-selector__edit-btn" @click=${this.handleEdit}> 18117 ${this.renderEditIcon()} 18118 ${u("Cambiar benchmark", { 18119 desc: "Change benchmark button", 18120 id: "benchmark-selector.change-button" 18121 })} 18122 </button> 18123 </div> 18124 </div> 18125 ` : ""; 18126 } 18127 render() { 18128 return this.selectedBenchmark && (this.isOpen || this.selectedBenchmark) ? this.renderSelected() : this.isOpen ? this.renderOpen() : this.renderClosed(); 18129 } 18130 }; 18131 xt.styles = [ 18132 We, 18133 K` 18134 :host { 18135 display: flex; 18136 padding: 24px; 18137 flex-direction: column; 18138 align-items: flex-start; 18139 gap: 24px; 18140 } 18141 18142 :host([selected]) { 18143 background: var(--Neutral-colors-light-background, #EBF6FF); 18144 } 18145 18146 /* Toggle Switch */ 18147 .toggle-switch { 18148 position: relative; 18149 width: 44px; 18150 height: 24px; 18151 background: #B0B5BA; 18152 border-radius: 12px; 18153 cursor: pointer; 18154 transition: background 0.2s ease; 18155 flex-shrink: 0; 18156 } 18157 18158 .toggle-switch.checked { 18159 background: var(--stock-primary-color, #1A5275); 18160 } 18161 18162 .toggle-switch::after { 18163 content: ''; 18164 position: absolute; 18165 width: 20px; 18166 height: 20px; 18167 background: white; 18168 border-radius: 50%; 18169 top: 2px; 18170 left: 2px; 18171 transition: transform 0.2s ease; 18172 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 18173 } 18174 18175 .toggle-switch.checked::after { 18176 transform: translateX(20px); 18177 } 18178 18179 /* Closed State */ 18180 .benchmark-selector--closed { 18181 display: flex; 18182 align-items: center; 18183 gap: 8px; 18184 align-self: stretch; 18185 } 18186 18187 .benchmark-selector__label { 18188 color: var(--Neutral-colors-color-neutral-1, #383D43); 18189 leading-trim: both; 18190 text-edge: cap; 18191 font-family: var(--stock-font-family, Poppins, sans-serif); 18192 font-size: 18px; 18193 font-style: normal; 18194 font-weight: 500; 18195 line-height: 27px; 18196 } 18197 18198 /* Open State */ 18199 .benchmark-selector--open { 18200 display: flex; 18201 flex-direction: column; 18202 gap: 24px; 18203 width: 100%; 18204 } 18205 18206 .benchmark-selector__header { 18207 display: flex; 18208 align-items: center; 18209 gap: 8px; 18210 align-self: stretch; 18211 } 18212 18213 .benchmark-selector__description-wrapper { 18214 display: flex; 18215 flex-direction: column; 18216 justify-content: center; 18217 align-items: flex-start; 18218 gap: 16px; 18219 align-self: stretch; 18220 } 18221 18222 .benchmark-selector__description { 18223 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18224 leading-trim: both; 18225 text-edge: cap; 18226 font-family: var(--stock-font-family, Poppins, sans-serif); 18227 font-size: 14px; 18228 font-style: normal; 18229 font-weight: 400; 18230 line-height: 21px; 18231 margin: 0; 18232 } 18233 18234 .benchmark-selector__info { 18235 display: flex; 18236 gap: 8px; 18237 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18238 leading-trim: both; 18239 text-edge: cap; 18240 font-family: var(--stock-font-family, Poppins, sans-serif); 18241 font-size: 14px; 18242 font-style: normal; 18243 font-weight: 400; 18244 line-height: 21px; 18245 } 18246 18247 .benchmark-selector__info svg { 18248 width: 24px; 18249 height: 24px; 18250 aspect-ratio: 1/1; 18251 flex-shrink: 0; 18252 color: var(--Semantic-colors-color-information, #58A8DA); 18253 } 18254 18255 /* Search Wrapper */ 18256 .benchmark-selector__search-wrapper { 18257 display: flex; 18258 flex-direction: column; 18259 justify-content: center; 18260 gap: 10px; 18261 align-self: stretch; 18262 width: 100%; 18263 position: relative; 18264 } 18265 18266 /* Horizontal scroll for tabs - override default full-width behavior */ 18267 .horizontal-scroll-element.initiated { 18268 width: 100%; 18269 margin-left: 0; 18270 margin-right: 0; 18271 } 18272 18273 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner { 18274 padding-left: 0; 18275 padding-right: 0; 18276 } 18277 18278 .horizontal-scroll-element.initiated::before { 18279 left: 0; 18280 background: linear-gradient(to right, 18281 var(--Neutral-colors-color-neutral-0, #FFF) 0px, 18282 rgba(255, 255, 255, 0.9) 10px, 18283 rgba(255, 255, 255, 0) 100% 18284 ); 18285 opacity: 0; 18286 transition: opacity 0.2s ease; 18287 } 18288 18289 .horizontal-scroll-element.initiated.scrolled-left::before { 18290 opacity: 1; 18291 } 18292 18293 .horizontal-scroll-element.initiated::after { 18294 right: 0; 18295 background: linear-gradient(to left, 18296 var(--Neutral-colors-color-neutral-0, #FFF) 0px, 18297 rgba(255, 255, 255, 0.9) 10px, 18298 rgba(255, 255, 255, 0) 100% 18299 ); 18300 opacity: 1; 18301 transition: opacity 0.2s ease; 18302 } 18303 18304 .horizontal-scroll-element.initiated.scrolled-right::after { 18305 opacity: 0; 18306 } 18307 18308 /* Tabs */ 18309 .benchmark-selector__tabs { 18310 display: flex; 18311 gap: 8px; 18312 flex-wrap: wrap; 18313 } 18314 18315 .benchmark-selector__tab { 18316 display: flex; 18317 padding: 12px 16px; 18318 justify-content: center; 18319 align-items: center; 18320 gap: 10px; 18321 border-radius: 4px; 18322 background: var(--Neutral-colors-color-neutral-3, #F0F0F0); 18323 border: none; 18324 color: var(--stock-text-color, #383D43); 18325 font-size: 15px; 18326 font-weight: 500; 18327 cursor: pointer; 18328 transition: all 0.2s ease; 18329 font-family: inherit; 18330 } 18331 18332 .benchmark-selector__tab:hover:not(.active) { 18333 background-color: var(--stock-light-gray-bg, #e0e0e0); 18334 } 18335 18336 .benchmark-selector__tab.active { 18337 display: flex; 18338 padding: 12px 16px; 18339 justify-content: center; 18340 align-items: center; 18341 gap: 10px; 18342 border-radius: 4px; 18343 background: var(--Primary-colors-color-primary, #1A5275); 18344 color: white; 18345 } 18346 18347 /* Input/Textarea */ 18348 .benchmark-selector__input { 18349 display: block; 18350 width: 100%; 18351 padding: 12px 16px; 18352 border-radius: 4px; 18353 border: 0.5px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18354 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18355 leading-trim: both; 18356 text-edge: cap; 18357 font-family: var(--stock-font-family, Poppins, sans-serif); 18358 font-size: 18px; 18359 font-style: normal; 18360 font-weight: 400; 18361 line-height: 27px; 18362 transition: border-color 0.2s ease; 18363 box-sizing: border-box; 18364 resize: none; 18365 overflow: hidden; 18366 field-sizing: content; 18367 min-height: 51px; 18368 } 18369 18370 .benchmark-selector__input::placeholder { 18371 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18372 leading-trim: both; 18373 text-edge: cap; 18374 font-family: var(--stock-font-family, Poppins, sans-serif); 18375 font-size: 14px; 18376 font-style: normal; 18377 font-weight: 400; 18378 line-height: 27px; 18379 } 18380 18381 .benchmark-selector__input:focus { 18382 outline: none; 18383 } 18384 18385 .benchmark-selector__input.has-results { 18386 border-radius: 8px 8px 0 0; 18387 border-top: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18388 border-right: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18389 border-left: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18390 border-bottom: none; 18391 } 18392 18393 .benchmark-selector__input:disabled { 18394 background-color: var(--stock-detail-background, #f8fafc);
18395 cursor: not-allowed; 18396 } 18397 18398 /* Results wrapper - handles border radius clipping */ 18399 .benchmark-selector__results-wrapper { 18400 position: absolute; 18401 top: 100%; 18402 left: 0; 18403 right: 0; 18404 border-radius: 0 0 8px 8px; 18405 border: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18406 border-top: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18407 background: var(--Neutral-colors-color-neutral-0, #FFF); 18408 box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.10); 18409 z-index: 10; 18410 overflow: hidden; 18411 } 18412 18413 /* Results - scrollable grid */ 18414 .benchmark-selector__results { 18415 display: grid; 18416 grid-template-columns: 1fr 1fr; 18417 background: var(--Neutral-colors-color-neutral-0, #FFF); 18418 overflow-x: hidden; 18419 overflow-y: auto; 18420 /* 3 rows max visible - each row ~100px (16px padding * 2 + content + 16px gap + borders) */ 18421 max-height: calc(3 * 100px); 18422 } 18423 18424 .benchmark-selector__result-item { 18425 display: flex; 18426 padding: 16px; 18427 flex-direction: column; 18428 align-items: flex-start; 18429 gap: 8px; 18430 align-self: stretch; 18431 cursor: pointer; 18432 transition: background-color 0.15s ease; 18433 border-bottom: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18434 border-right: 1px solid var(--Neutral-colors-color-neutral-2, #5A6773); 18435 background: var(--Neutral-colors-color-neutral-0, #FFF); 18436 } 18437 18438 /* Items in right column (even position) - no right border */ 18439 .benchmark-selector__result-item:nth-child(even) { 18440 border-right: none; 18441 } 18442 18443 /* Last row items - no bottom border */ 18444 .benchmark-selector__result-item:nth-last-child(1), 18445 .benchmark-selector__result-item:nth-last-child(2):nth-child(odd) { 18446 border-bottom: none; 18447 } 18448 18449 /* Last item when odd - span full width and no right border */ 18450 .benchmark-selector__result-item:last-child:nth-child(odd) { 18451 grid-column: 1 / -1; 18452 border-right: none; 18453 } 18454 18455 .benchmark-selector__result-item:hover, 18456 .benchmark-selector__result-item:focus { 18457 background: var(--Primary-colors-color-primary, #1A5275); 18458 } 18459 18460 .benchmark-selector__result-item:hover .benchmark-selector__result-name, 18461 .benchmark-selector__result-item:focus .benchmark-selector__result-name { 18462 color: var(--Neutral-colors-color-neutral-0, #FFF); 18463 } 18464 18465 .benchmark-selector__result-item:hover .benchmark-selector__result-details, 18466 .benchmark-selector__result-item:focus .benchmark-selector__result-details { 18467 color: var(--Neutral-colors-color-neutral-0, #FFF); 18468 } 18469 18470 .benchmark-selector__result-name { 18471 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18472 leading-trim: both; 18473 text-edge: cap; 18474 font-family: var(--stock-font-family, Poppins, sans-serif); 18475 font-size: 18px; 18476 font-style: normal; 18477 font-weight: 600; 18478 line-height: 27px; 18479 } 18480 18481 .benchmark-selector__result-details { 18482 color: var(--Neutral-colors-color-neutral-2, #5A6773); 18483 leading-trim: both; 18484 text-edge: cap; 18485 font-family: var(--stock-font-family, Poppins, sans-serif); 18486 font-size: 18px; 18487 font-style: normal; 18488 font-weight: 400; 18489 line-height: 27px; 18490 } 18491 18492 /* Error State */ 18493 .benchmark-selector__error { 18494 display: flex; 18495 padding: 12px 16px; 18496 align-items: center; 18497 gap: 10px; 18498 flex: 1 0 0; 18499 align-self: stretch; 18500 border-radius: 8px; 18501 background: var(--Semantic-colors-color-alert, #FCFF74); 18502 } 18503 18504 .benchmark-selector__error svg { 18505 flex-shrink: 0; 18506 width: 20px; 18507 height: 20px; 18508 } 18509 18510 .benchmark-selector__error-text { 18511 color: var(--Neutral-colors-color-neutral-1, #383D43); 18512 leading-trim: both; 18513 text-edge: cap; 18514 font-family: var(--stock-font-family, Poppins, sans-serif); 18515 font-size: 14px; 18516 font-style: normal; 18517 font-weight: 400; 18518 line-height: 21px; 18519 } 18520 18521 /* Selected State */ 18522 .benchmark-selector--selected { 18523 display: flex; 18524 align-items: center; 18525 gap: 8px; 18526 width: 100%; 18527 } 18528 18529 .benchmark-selector__selected-content { 18530 display: flex; 18531 align-items: center; 18532 gap: 8px; 18533 flex: 1; 18534 } 18535 18536 .benchmark-selector__active-text { 18537 flex: 1; 18538 color: var(--stock-text-color, #383D43); 18539 font-size: 15px; 18540 } 18541 18542 .benchmark-selector__active-text strong { 18543 font-weight: 600; 18544 color: var(--stock-title-color, #1e293b); 18545 } 18546 18547 .benchmark-selector__edit-btn { 18548 display: flex; 18549 align-items: center; 18550 gap: 8px; 18551 align-self: stretch; 18552 padding: 0; 18553 background: transparent; 18554 border: none; 18555 color: var(--Primary-colors-color-primary, #1A5275); 18556 text-align: right; 18557 leading-trim: both; 18558 text-edge: cap; 18559 font-family: var(--stock-font-family, Poppins, sans-serif); 18560 font-size: 18px; 18561 font-style: normal; 18562 font-weight: 400; 18563 line-height: 27px; 18564 cursor: pointer; 18565 transition: color 0.2s ease; 18566 white-space: nowrap; 18567 } 18568 18569 .benchmark-selector__edit-btn:hover { 18570 color: var(--stock-accent-color, #3b82f6); 18571 } 18572 18573 .benchmark-selector__edit-btn svg { 18574 flex-shrink: 0; 18575 } 18576 18577 /* Mobile Responsive */ 18578 @media (max-width: 600px) { 18579 :host { 18580 padding: 16px 8px; 18581 gap: 16px; 18582 } 18583 18584 :host([open]){ 18585 padding: 16px 8px 8px 8px; 18586 } 18587 18588 .benchmark-selector__label { 18589 color: var(--Neutral-colors-color-neutral-1, #383D43); 18590 leading-trim: both; 18591 text-edge: cap; 18592 font-family: var(--stock-font-family, Poppins, sans-serif); 18593 font-size: 14px; 18594 font-style: normal; 18595 font-weight: 500; 18596 line-height: 21px; 18597 } 18598 18599 .benchmark-selector__tabs { 18600 flex-wrap: nowrap; 18601 } 18602 18603 .benchmark-selector__tab { 18604 width: auto; 18605 flex-shrink: 0; 18606 white-space: nowrap; 18607 } 18608 18609 .benchmark-selector__input { 18610 height: calc(27px * 3); /* para 3 lÃneas */ 18611 } 18612 18613 .benchmark-selector__results { 18614 grid-template-columns: 1fr; 18615 /* 3 rows max visible on mobile */ 18616 max-height: calc(3 * 100px); 18617 } 18618 18619 .benchmark-selector__result-item {
18620 border-right: none; 18621 } 18622 18623 .benchmark-selector--selected { 18624 align-items: flex-start; 18625 } 18626 18627 .benchmark-selector__selected-content { 18628 display: flex; 18629 flex-direction: column; 18630 align-items: flex-start; 18631 gap: 16px; 18632 align-self: stretch; 18633 } 18634 18635 .benchmark-selector__edit-btn { 18636 width: 100%; 18637 font-size: 14px; 18638 line-height: 21px; 18639 } 18640 18641 .benchmark-selector__active-text { 18642 color: var(--Neutral-colors-color-neutral-1, #383D43); 18643 font-size: 14px; 18644 font-weight: 400; 18645 line-height: 21px; 18646 } 18647 18648 .benchmark-selector__active-text strong { 18649 color: var(--Neutral-colors-color-neutral-1, #383D43); 18650 font-size: 14px; 18651 font-weight: 600; 18652 line-height: 21px; 18653 } 18654 18655 .benchmark-selector__result-name { 18656 leading-trim: both; 18657 text-edge: cap; 18658 font-size: 14px; 18659 font-style: normal; 18660 line-height: 21px; 18661 /* font-weight: 600 preserved from base styles */ 18662 } 18663 18664 .benchmark-selector__result-details { 18665 leading-trim: both; 18666 text-edge: cap; 18667 font-size: 14px; 18668 font-style: normal; 18669 line-height: 21px; 18670 /* font-weight: 400 preserved from base styles */ 18671 } 18672 } 18673 ` 18674 ]; 18675 Tt([ 18676 $({ type: String }) 18677 ], xt.prototype, "targets", 2); 18678 Tt([ 18679 C() 18680 ], xt.prototype, "isOpen", 2); 18681 Tt([ 18682 C() 18683 ], xt.prototype, "searchType", 2); 18684 Tt([ 18685 C() 18686 ], xt.prototype, "queryValue", 2); 18687 Tt([ 18688 C() 18689 ], xt.prototype, "error", 2); 18690 Tt([ 18691 C() 18692 ], xt.prototype, "results", 2); 18693 Tt([ 18694 C() 18695 ], xt.prototype, "selectedBenchmark", 2); 18696 Tt([ 18697 C() 18698 ], xt.prototype, "rememberedBenchmark", 2); 18699 xt = Tt([ 18700 lt(), 18701 it("benchmark-selector") 18702 ], xt); 18703 var vc = Object.defineProperty; 18704 var bc = Object.getOwnPropertyDescriptor; 18705 var It = (s, t, e, i) => { 18706 for (var r = i > 1 ? void 0 : i ? bc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 18707 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 18708 return i && r && vc(t, e, r), r; 18709 }; 18710 var xe = class extends $t { 18711 constructor() { 18712 super(...arguments), this.activeTab = "", this.mutationObserver = null; 18713 } 18714 firstUpdated() { 18715 requestAnimationFrame(() => { 18716 this.assignSlots(), this.initializeTabs(), this.setupMutationObserver(), setTimeout(() => { 18717 yt(this); 18718 }, 0); 18719 }); 18720 } 18721 disconnectedCallback() { 18722 super.disconnectedCallback(), this.mutationObserver && this.mutationObserver.disconnect(); 18723 } 18724 updated(s) { 18725 s.has("activeTab") && this.activeTab && this.switchToTab(this.activeTab), setTimeout(() => { 18726 yt(this); 18727 }, 0); 18728 } 18729 /** 18730 * The panels a tab switch may hide: only the component's own `tab-panel` 18731 * children, never everything the host put in the slot. 18732 * 18733 * Hosts do slot other things next to the panels â Rankia's ficha slots an 18734 * educational-mode notice that has to stay visible on every tab. Hiding by 18735 * slot assignment set `hidden="until-found"` on it, which is 18736 * `content-visibility: hidden`: the box kept its padding but its contents 18737 * were never painted, so the notice rendered as an empty coloured band. 18738 */ 18739 static panelesDe(s) { 18740 return s.assignedElements({ flatten: true }).filter((t) => t.tagName.toLowerCase() === "tab-panel"); 18741 } 18742 assignSlots() { 18743 const s = this.querySelectorAll("tab-button"), t = this.querySelectorAll("tab-panel"); 18744 s.forEach((e) => { 18745 e.hasAttribute("slot") || e.setAttribute("slot", "buttons"); 18746 }), t.forEach((e) => { 18747 e.hasAttribute("slot") || e.setAttribute("slot", "panels"); 18748 }); 18749 } 18750 initializeTabs() { 18751 setTimeout(() => { 18752 this.performTabInitialization(); 18753 }, 0); 18754 } 18755 performTabInitialization() { 18756 var l, h; 18757 const s = (l = this.shadowRoot) == null ? void 0 : l.querySelector('slot[name="buttons"]'), t = (h = this.shadowRoot) == null ? void 0 : h.querySelector('slot[name="panels"]'); 18758 if (!s || !t) { 18759 setTimeout(() => this.performTabInitialization(), 10); 18760 return; 18761 } 18762 const e = s.assignedElements({ flatten: true }), i = xe.panelesDe(t); 18763 if (e.length === 0 || i.length === 0) { 18764 setTimeout(() => this.performTabInitialization(), 10); 18765 return; 18766 } 18767 const r = []; 18768 e.forEach((c) => { 18769 const d = c.getAttribute("data-for"); 18770 d && r.push(d); 18771 }); 18772 let n = ""; 18773 const a = "stock-tabs-last-tab", o = localStorage.getItem(a); 18774 if (o && r.includes(o)) 18775 n = o; 18776 else { 18777 const c = e.find((d) => d.hasAttribute("active")); 18778 c ? (n = c.getAttribute("data-for") || "", c.setAttribute("disabled", "")) : e.length > 0 && r.length > 0 && (e[0].setAttribute("active", ""), e[0].setAttribute("disabled", ""), n = r[0]); 18779 } 18780 e.forEach((c) => { 18781 c.getAttribute("data-for") === n ? (c.setAttribute("active", ""), c.setAttribute("disabled", "")) : (c.removeAttribute("active"), c.removeAttribute("disabled")); 18782 }
18782), i.forEach((c) => { 18783 c.getAttribute("id") === n ? c.removeAttribute("hidden") : c.setAttribute("hidden", "until-found"); 18784 }), e.forEach((c) => { 18785 c.addEventListener("click", this.handleTabClick.bind(this)); 18786 }); 18787 } 18788 handleTabClick(s) { 18789 const e = s.currentTarget.getAttribute("data-for"); 18790 e && this.switchToTab(e); 18791 } 18792 switchToTab(s) { 18793 var o, l; 18794 const t = (o = this.shadowRoot) == null ? void 0 : o.querySelector('slot[name="panels"]'), e = (l = this.shadowRoot) == null ? void 0 : l.querySelector('slot[name="buttons"]'); 18795 if (!t || !e) 18796 return; 18797 const i = xe.panelesDe(t); 18798 i.forEach((h) => { 18799 h.setAttribute("hidden", "until-found"); 18800 }); 18801 const r = i.find((h) => h.id === s); 18802 r && r.removeAttribute("hidden"), e.assignedElements({ flatten: true }).forEach((h) => { 18803 h.getAttribute("data-for") === s ? (h.setAttribute("active", ""), h.setAttribute("disabled", "")) : (h.removeAttribute("active"), h.removeAttribute("disabled")); 18804 }); 18805 const a = "stock-tabs-last-tab"; 18806 localStorage.setItem(a, s), this.dispatchEvent(new CustomEvent("tab-changed", { 18807 detail: { activeTab: s }, 18808 bubbles: true, 18809 composed: true 18810 })); 18811 } 18812 setupMutationObserver() { 18813 this.mutationObserver = new MutationObserver((s) => { 18814 let t = false;
18815 s.forEach((e) => { 18816 e.type === "childList" && e.addedNodes.forEach((i) => { 18817 if (i.nodeType === Node.ELEMENT_NODE) { 18818 const r = i; 18819 (r.tagName === "TAB-BUTTON" || r.tagName === "TAB-PANEL") && (t = true); 18820 } 18821 }); 18822 }), t && setTimeout(() => { 18823 this.assignSlots(), this.initializeTabs(); 18824 }, 0); 18825 }), this.mutationObserver.observe(this, { 18826 childList: true, 18827 subtree: true 18828 }); 18829 } 18830 render() { 18831 return g` 18832 <div class="tabs-container"> 18833 <div class="tabs-header horizontal-scroll-element"> 18834 <div class="horizontal-scroll-element-inner"> 18835 <slot name="buttons"></slot> 18836 </div> 18837 </div> 18838 <div class="tabs-content"> 18839 <slot name="panels"></slot> 18840 </div> 18841 </div> 18842 `; 18843 } 18844 }; 18845 xe.styles = K` 18846 :host { 18847 display: block; 18848 width: 100%; 18849 font-family: var(--stock-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif); 18850 --tabs-text-color: var(--stock-text-color, #383d43); 18851 --tabs-active-color: var(--stock-white-color, #FFFFFF); 18852 --tabs-bg: var(--stock-light-gray-bg, #f0f0f0); 18853 --tabs-bg-active: var(--stock-primary-color, #1A5275); 18854 --tabs-bg-hover: var(--stock-info-color, rgba(88, 168, 218, 0.15)); 18855 --tabs-font-size-basis: var(--stock-font-size-basis, 18px); 18856 --tabs-gap: var(--stock-gap, 16px); 18857 --tabs-button-padding: var(--stock-button-padding, 10px 16px); 18858 --tabs-button-border-radius: var(--stock-button-border-radius, 4px); 18859 --tabs-button-gap: var(--stock-button-gap, 8px); 18860 } 18861 18862 .tabs-container { 18863 width: 100%; 18864 } 18865 18866 .tabs-header { 18867 padding-bottom: 16px; 18868 } 18869 18870 /* Elemento horizontal con scroll */ 18871 .horizontal-scroll-element { 18872 width: 100%; 18873 display: block; 18874 position: relative; 18875 box-sizing: border-box; 18876 } 18877 18878 .horizontal-scroll-element.initiated { 18879 width: calc(100% + var(--stock-padding, 16px) * 2); 18880 margin-left: calc(-1 * var(--stock-padding, 16px)); 18881 margin-right: calc(-1 * var(--stock-padding, 16px)); 18882 overflow: hidden; 18883 } 18884 18885 .horizontal-scroll-element.initiated::before, 18886 .horizontal-scroll-element.initiated::after { 18887 content: ''; 18888 position: absolute; 18889 top: 0; 18890 bottom: 0; 18891 width: var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)); 18892 pointer-events: none; 18893 z-index: 1; 18894 } 18895 18896 .horizontal-scroll-element.initiated::before { 18897 left: 0; 18898 background: linear-gradient(to right, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); 18899 } 18900 18901 .horizontal-scroll-element.initiated::after { 18902 right: 0; 18903 background: linear-gradient(to left, 18904 rgba(255, 255, 255, 1) 0px, 18905 rgba(255, 255, 255, 0.9) 10px, 18906 rgba(255, 255, 255, 0) 100% 18907 ); 18908 width: calc(var(--horizontal-scroll-gradient-width, var(--stock-padding, 16px)) * 1.6); 18909 } 18910 18911 .horizontal-scroll-element-inner { 18912 display: flex; 18913 flex-direction: row; 18914 align-items: center; 18915 gap: 8px; 18916 width: 100%; 18917 overflow-x: auto; 18918 -webkit-overflow-scrolling: touch; 18919 scrollbar-width: none; 18920 padding-bottom: 5px; 18921 scroll-behavior: smooth; 18922 box-sizing: border-box; 18923 } 18924 18925 .horizontal-scroll-element-inner::-webkit-scrollbar {
18926 display: none; 18927 } 18928 18929 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner { 18930 padding-left: var(--stock-padding, 16px); 18931 padding-right: var(--stock-padding, 16px); 18932 cursor: grab; 18933 user-select: none; 18934 } 18935 18936 .horizontal-scroll-element.initiated .horizontal-scroll-element-inner:active { 18937 cursor: grabbing; 18938 } 18939 .tabs-content { 18940 padding: 16px 0; 18941 width: 100%; 18942 } 18943 `; 18944 It([ 18945 $({ type: String }) 18946 ], xe.prototype, "activeTab", 2); 18947 xe = It([ 18948 lt(), 18949 it("stock-tabs") 18950 ], xe); 18951 var ke = class extends $t { 18952 constructor() { 18953 super(...arguments), this["data-for"] = "", this.active = false, this.disabled = false; 18954 } 18955 render() { 18956 return g` 18957 <button 18958 class="tab-button" 18959 ?active="${this.active}" 18960 ?disabled="${this.disabled}" 18961 role="tab" 18962 aria-selected="${this.active}" 18963 type="button" 18964 > 18965 <slot></slot> 18966 </button> 18967 `; 18968 } 18969 }; 18970 ke.styles = K` 18971 :host { 18972 display: block; 18973 } 18974 18975 .tab-button { 18976 display: flex; 18977 align-items: center; 18978 gap: var(--tabs-button-gap); 18979 padding: var(--tabs-button-padding); 18980 background: var(--tabs-bg); 18981 border: none; 18982 color: var(--tabs-text-color); 18983 /* 18984 * Por token: la Entrega 2 baja las pestanas a 14/21, pero estos mismos 18985 * tabs los pinta retails-next con los 18/27 de hoy. El valor por defecto 18986 * es el de siempre. 18987 */ 18988 font-size: var(--tabs-font-size, var(--tabs-font-size-basis)); 18989 line-height: var(--tabs-line-height, 1.5); 18990 font-weight: 500; 18991 border-radius: var(--tabs-button-border-radius); 18992 cursor: pointer; 18993 transition: all 0.2s ease; 18994 white-space: nowrap; 18995 } 18996 18997 .tab-button:hover { 18998 background-color: var(--tabs-bg-hover); 18999 } 19000 19001 .tab-button[active] { 19002 color: var(--tabs-active-color); 19003 background-color: var(--tabs-bg-active); 19004 } 19005 19006 .tab-button[disabled] { 19007 cursor: auto; 19008 } 19009 19010 .tab-button:focus:not(:focus-visible) { 19011 outline: none; 19012 } 19013 `; 19014 It([ 19015 $({ type: String }) 19016 ], ke.prototype, "data-for", 2); 19017 It([ 19018 $({ type: Boolean, reflect: true }) 19019 ], ke.prototype, "active", 2); 19020 It([ 19021 $({ type: Boolean, reflect: true }) 19022 ], ke.prototype, "disabled", 2); 19023 ke = It([ 19024 it("tab-button") 19025 ], ke); 19026 var Ue = class extends $t { 19027 constructor() { 19028 super(...arguments), this.id = "", this.hidden = false; 19029 } 19030 updated(s) { 19031 s.has("hidden") && (this.hidden ? this.setAttribute("hidden", "until-found") : this.removeAttribute("hidden")); 19032 } 19033 render() { 19034 return g` 19035 <div class="tab-panel" ?hidden="${this.hidden}"> 19036 <slot></slot> 19037 </div> 19038 `; 19039 } 19040 }; 19041 Ue.styles = K` 19042 :host { 19043 display: block; 19044 width: 100%; 19045 } 19046 19047 .tab-panel { 19048 width: 100%; 19049 } 19050 19051 .tab-panel[hidden] { 19052 display: none; 19053 } 19054 `; 19055 It([ 19056 $({ type: String }) 19057 ], Ue.prototype, "id", 2); 19058 It([ 19059 $({ type: Boolean, reflect: true }) 19060 ], Ue.prototype, "hidden", 2); 19061 Ue = It([ 19062 it("tab-panel") 19063 ], Ue); 19064 var yc = "es-ES"; 19065 var { getLocale: ca } = qa({ 19066 sourceLocale: yc 19067 }); 19068 var wc = Object.defineProperty; 19069 var xc = Object.getOwnPropertyDescriptor; 19070 var Rt = (s, t, e, i) => { 19071 for (var r = i > 1 ? void 0 : i ? xc(t, e) : t, n = s.length - 1, a; n >= 0; n--) 19072 (a = s[n]) && (r = (i ? a(t, e, r) : a(r)) || r); 19073 return i && r && wc(t, e, r), r; 19074 }; 19075 var Ss = 6e4; 19076 var Cs = 60 * Ss; 19077 var _s = 24 * Cs; 19078 var yn = 30 * _s; 19079 function kc(s) { 19080 let t = 0; 19081 for (let r = 0; r < s.length; r += 1) 19082 t = t * 31 + s.charCodeAt(r) >>> 0; 19083 const e = t % 360, i = (e + 38) % 360; 19084 return `linear-gradient(135deg, hsl(${e} 58% 52%), hsl(${i} 64% 42%))`; 19085 } 19086 function Sc(s) { 19087 var r; 19088 const t = (s || "").trim(); 19089 if (!t) 19090 return "\xB7"; 19091 const e = t.replace(/([a-zà -ÿ])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9Ã-É]+/).filter(Boolean); 19092 return e.length >= 2 ? (e[0][0] + e[1][0]).toUpperCase() : ((r = e[0]) != null ? r : t).slice(0, 2).toUpperCase(); 19093 } 19094 function Xt(s) { 19095 return typeof s == "string" ? s : ""; 19096 } 19097 function $s(s) { 19098 const t = s && typeof s == "object" ? s : {}, e = Di(Xt(t.photoUrl)), i = { 19099 name: Xt(t.name), 19100 avatar: typeof t.avatar == "string" ? t.avatar : void 0 19101 }; 19102 return e && (i.photoUrl = e), i; 19103 } 19104 function Di(s) { 19105 const t = s.trim(); 19106 if (!t) 19107 return ""; 19108 if (t.startsWith("//")) { 19109 const i = typeof location != "undefined" ? location.origin : "http://localhost";
19110 try { 19111 return /^https?:$/i.test(new URL(t, i).protocol) ? t : ""; 19112 } catch (r) { 19113 return ""; 19114 } 19115 } 19116 const e = t.match(/^([a-z][a-z0-9+.-]*):/i); 19117 return e && !/^https?$/i.test(e[1]) ? "" : t; 19118 } 19119 function Ds(s) { 19120 const t = typeof s == "number" ? s : typeof s == "string" ? Number(s) : NaN; 19121 return Number.isFinite(t) ? Math.max(0, t) : 0; 19122 } 19123 function Cc(s) { 19124 const t = s && typeof s == "object" ? s : {}, e = Di(Xt(t.href)), i = Xt(t.text); 19125 return i ? e ? { author: $s(t.author), text: i, href: e } : { author: $s(t.author), text: i } : null; 19126 } 19127 function _c(s) { 19128 const t = s && typeof s == "object" ? s : {}, e = Xt(t.title), i = Di(Xt(t.href)); 19129 if (!e || !i) 19130 return null; 19131 const r = Ds(t.commentCount), n = Array.isArray(t.comments) ? t.comments.map(Cc).filter((a) => a !== null) : []; 19132 return { 19133 title: e, 19134 href: i, 19135 author: $s(t.author), 19136 commentCount: r, 19137 lastCommentAt: Xt(t.lastCommentAt), 19138 comments: n 19139 }; 19140 } 19141 function $c(s, t = Date.now()) { 19142 const e = Date.parse(s); 19143 if (Number.isNaN(e)) 19144 return ""; 19145 const i = Math.max(0, t - e); 19146 if (i < Ss) 19147 return u("un momento", { id: "forum.age.now", desc: 'Relative-time duration, under a minute. Consumed by forum.meta.lastComment: "hace un momento" / "a moment ago"' }); 19148 if (i < Cs) { 19149 const n = Math.floor(i / Ss); 19150 return n === 1 ? u("1 minuto", { id: "forum.age.minute", desc: 'Relative-time duration: 1 minute. Consumed by forum.meta.lastComment: "hace 1 minuto"' }) : u(A`${n} minutos`, { id: "forum.age.minutes", desc: 'Relative-time duration: N minutes. Consumed by forum.meta.lastComment: "hace N minutos"' }); 19151 } 19152 if (i < _s) { 19153 const n = Math.floor(i / Cs); 19154 return n === 1 ? u("1 hora", { id: "forum.age.hour", desc: 'Relative-time duration: 1 hour. Consumed by forum.meta.lastComment: "hace 1 hora"' }) : u(A`${n} horas`, { id: "forum.age.hours", desc: 'Relative-time duration: N hours. Consumed by forum.meta.lastComment: "hace N horas"' }); 19155 } 19156 if (i < yn) { 19157 const n = Math.floor(i / _s); 19158 return n === 1 ? u("1 d\xEDa", { id: "forum.age.day", desc: 'Relative-time duration: 1 day. Consumed by forum.meta.lastComment: "hace 1 d\xEDa"' }) : u(A`${n} dÃas`, { id: "forum.age.days", desc: 'Relative-time duration: N days. Consumed by forum.meta.lastComment: "hace N d\xEDas"' }); 19159 } 19160 const r = Math.floor(i / yn); 19161 return r === 1 ? u("1 mes", { id: "forum.age.month", desc: 'Relative-time duration: 1 month. Consumed by forum.meta.lastComment: "hace 1 mes"' }) : u(A`${r} meses`, { id: "forum.age.months", desc: 'Relative-time duration: N months. Consumed by forum.meta.lastComment: "hace N meses"' }); 19162 } 19163 function Dc(s) { 19164 if (!Number.isFinite(s) || s < 1e3) 19165 return String(Math.max(0, Math.floor(s || 0))); 19166 const t = s / 1e3; 19167 let e; 19168 try { 19169 e = new Intl.NumberFormat(ca(), { maximumFractionDigits: 1 }).format(t); 19170 } catch (i) { 19171 e = String(Math.round(t * 10) / 10); 19172 } 19173 return `${e}K`; 19174 } 19175 var X = class extends $t { 19176 constructor() { 19177 super(...arguments), this.symbol = "", this.name = "", this.forumHref = "", this.plainHeading = false, this.threads = "", this.maxThreads = 2, this.totalComments = 0, this.totalThreads = 0; 19178 } 19179 createRenderRoot() { 19180 return this; 19181 } 19182 connectedCallback() { 19183 super.connectedCallback(); 19184 const s = this.clearStaleLightDom(); 19185 X.injectStyles(), s && this.performUpdate(); 19186 } 19187 disconnectedCallback() { 19188 super.disconnectedCallback(), this.removeAttribute(X.RENDERED_MARKER_ATTR); 19189 } 19190 /** 19191 * Turbo Drive idempotency. rankia.com navigates with Turbo Drive: pressing 19192 * Back restores a page snapshot whose light-DOM already contains a previous 19193 * render of this component. Because the restored element is a brand-new 19194 * instance, Lit would append a *second* render next to the restored one and 19195 * the forum block would visibly duplicate (the bug Maoly/Edmond reported). 19196 * 19197 * GATING: this runs on every `connectedCallback`, but only clears when the 19198 * host carries the `data-rnk-rendered` marker (stamped in `updated` and 19199 * serialized by Turbo into the snapshot). Its presence on a fresh instance 19200 * means a previous render is petrified in the restored light-DOM. On a cold 19201 * mount, or a disconnect/reconnect (DOM move, Turbo frame reattach) where no 19202 * render has committed yet, the marker is absent â we leave the light-DOM 19203 * untouched and never wipe a valid render before any update runs. After 19204 * clearing we consume the marker; the subsequent render re-stamps it. 19205 * 19206 * When it does clear, it keeps the SSR seed (`.rnk-SeoStaticData`) the host 19207 * renders for crawlers â and any node that CONTAINS it (an SSR wrapper) â 19208 * matched by class, not position, so the seed survives wherever it sits. This 19209 * component does NOT project its own `.rnk-SeoStaticData` clone in `render()` 19210 * (it only renders `.rnk-ForumBlock`), so the simple seed-preserve is enough; 19211 * no projected-clone exclusion (the `data-rnk-ssr-projection` marker that the 19212 * IA block needs in PR #236) is required here. 19213 */ 19214 clearStaleLightDom() { 19215 if (!this.hasAttribute(X.RENDERED_MARKER_ATTR)) 19216 return false;
19217 this.removeAttribute(X.RENDERED_MARKER_ATTR); 19218 for (const s of Array.from(this.childNodes)) 19219 s.nodeType === Node.ELEMENT_NODE && X.holdsServerSeed(s) || this.removeChild(s); 19220 return true; 19221 } 19222 /** `true` if `el` IS the SSR seed or CONTAINS it (an SSR wrapper around it). */ 19223 static holdsServerSeed(s) { 19224 var t, e; 19225 return ((t = s.classList) == null ? void 0 : t.contains("rnk-SeoStaticData")) === true || ((e = s.querySelector) == null ? void 0 : e.call(s, ".rnk-SeoStaticData")) != null; 19226 } 19227 updated(s) { 19228 super.updated(s), this.setAttribute(X.RENDERED_MARKER_ATTR, ""); 19229 } 19230 static injectStyles() { 19231 var e; 19232 if (typeof document == "undefined") 19233 return; 19234 const s = (e = document.head) != null ? e : document.documentElement; 19235 if (!s || document.getElementById(X.STYLE_TAG_ID)) 19236 return; 19237 const t = document.createElement("style"); 19238 t.id = X.STYLE_TAG_ID, t.textContent = Mc, s.appendChild(t); 19239 } 19240 get parsedThreads() { 19241 if (!this.threads) 19242 return []; 19243 let s; 19244 try { 19245 s = JSON.parse(this.threads); 19246 } catch (t) { 19247 return []; 19248 } 19249 return Array.isArray(s) ? s.map((t) => _c(t)).filter((t) => t !== null).slice(0, Math.max(0, this.maxThreads)) : []; 19250 } 19251 /** Display name with a sensible fallback for the title / CTA. */ 19252 get displayName() { 19253 return (this.name == null ? "" : String(this.name)).trim() || this.symbol.trim().toUpperCase(); 19254 } 19255 // ---- formatting helpers ------------------------------------------------- 19256 commentCountLabel(s) { 19257 if (s === 1) 19258 return u("1 comentario", { id: "forum.comments.one", desc: "Comment count, singular" }); 19259 const t = Dc(s); 19260 return u(A`${t} comentarios`, { id: "forum.comments.many", desc: "Comment count, plural (value may be abbreviated, e.g. 1,2K)" }); 19261 } 19262 /** 19263 * Locale-aware thousands separator (e.g. 12480 â "12.480" in es-ES). Uses the 19264 * ACTIVE @lit/localize locale (`getLocale()`) rather than the runtime default, 19265 * so the grouping separator always matches the translated strings â in 19266 * transform mode `getLocale()` resolves to the locale baked into each bundle. 19267 */ 19268 formatCount(s) { 19269 try { 19270 return new Intl.NumberFormat(ca()).format(s); 19271 } catch (t) { 19272 return String(s); 19273 } 19274 } 19275 /** 19276 * Localized "N comentarios en total" fragment, with the comment noun 19277 * pluralized INDEPENDENTLY from the thread count (so "1 comentario en total" 19278 * vs "12.480 comentarios en total" read grammatically in every locale). 19279 */ 19280 totalCommentsLabel(s) { 19281 if (s === 1) 19282 return u("1 comentario en total", { id: "forum.header.comments.one", desc: "Forum totals: total comment count, singular" }); 19283 const t = this.formatCount(s); 19284 return u(A`${t} comentarios en total`, { id: "forum.header.comments.other", desc: "Forum totals: total comment count, plural (value is locale-formatted)" }); 19285 } 19286 /** 19287 * Localized "M hilos" fragment, pluralized INDEPENDENTLY from the comment 19288 * count ("1 hilo" vs "47 hilos"). 19289 */ 19290 totalThreadsLabel(s) { 19291 if (s === 1) 19292 return u("1 hilo", { id: "forum.header.threads.one", desc: "Forum totals: thread count, singular" }); 19293 const t = this.formatCount(s); 19294 return u(A`${t} hilos`, { id: "forum.header.threads.other", desc: "Forum totals: thread count, plural (value is locale-formatted)" }); 19295 } 19296 /** 19297 * Totals subtitle under the heading: "N comentarios en total · M hilos". 19298 * Composed from two independently-pluralized, locale-formatted fragments and 19299 * the "·" separator. Rendered only when both totals are present and positive â 19300 * when the host does not supply them the line degrades gracefully (nothing). 19301 */ 19302 renderTotals() { 19303 const s = Ds(this.totalComments), t = Ds(this.totalThreads); 19304 return s <= 0 || t <= 0 ? I : g`<p class="sub">${this.totalCommentsLabel(s)} · ${this.totalThreadsLabel(t)}</p>`; 19305 } 19306 // ---- render ------------------------------------------------------------- 19307 /** Speech-bubble icon shown next to the comment count (matches the handoff). */ 19308 renderCountIcon() { 19309 return g`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-8.5 8.5 8.5 8.5 0 0 1-3.7-.85L3 21l1.85-5.55A8.5 8.5 0 1 1 21 11.5z"/></svg>`; 19310 } 19311 /** 19312 * Avatar chip for an author: a real profile photo when the host supplied a 19313 * valid `photoUrl` (already sanitized in `normalizeAuthor`), otherwise the 19314 * deterministic initials-on-gradient fallback. The `<img>` is decorative 19315 * (`alt=""`) â the author name is already announced next to it in the body / 19316 * meta line â and lazy-loaded; CSS gives it `object-fit:cover` at the circle 19317 * size of its class. `variant` adds a modifier (e.g. `tc-av--sm` for the 19318 * smaller thread-author avatar in the meta line). 19319 */ 19320 renderAvatar(s, t = "") { 19321 const e = t ? `tc-av ${t}` : "tc-av"; 19322 if (s.photoUrl) 19323 return g`<img class="${e}" src=${s.photoUrl} alt="" loading="lazy" />`; 19324 const i = s.avatar || kc(s.name || ""); 19325 return g`<span class="${e}" style="background:${i}" aria-hidden="true">${Sc(s.name)}</span>`;
19326 } 19327 renderComment(s, t) { 19328 const e = `tcomment-mini${t ? " tcomment-mini--solo" : ""}`, i = g`${this.renderAvatar(s.author)} 19329 <span class="tcm-body" 19330 >${s.author.name ? g`<span class="who">${s.author.name}</span> ` : I}${s.text}</span 19331 >`; 19332 return s.href ? g`<a class="${e} is-link" href=${s.href}>${i}</a>` : g`<div class="${e}">${i}</div>`; 19333 } 19334 renderEmpty(s) { 19335 return g` 19336 <a class="tcomment-mini empty is-link" href=${s}> 19337 <span class="tcm-empty-text" 19338 >${u("A\xFAn no hay comentarios.", { id: "forum.empty.text", desc: "Empty thread state" })}</span 19339 > 19340 <span class="tcm-empty-cta" 19341 >${u("S\xE9 el primero", { id: "forum.empty.cta", desc: "Empty thread call to action (be the first to comment)" })} 19342 <span aria-hidden="true">â</span></span 19343 > 19344 </a> 19345 `; 19346 } 19347 renderCard(s) { 19348 var n; 19349 const t = ((n = s.comments) != null ? n : []).slice(0, 2), e = s.author.name.trim(), i = $c(s.lastCommentAt), r = t.length === 1; 19350 return g` 19351 <article class="tcard"> 19352 <a class="tcard-title" href=${s.href}>${s.title}</a> 19353 <div class="tmeta"> 19354 ${e ? g`<span class="tmeta-author" 19355 >${this.renderAvatar(s.author, "tc-av--sm")}<span class="tmeta-prefix" 19356 >${u("iniciado por", { id: "forum.meta.author.prefix", desc: 'Standalone thread-author prefix in the meta line, immediately followed by the emphasized author name (rendered separately): reads "iniciado por <name>" / "started by <name>". Translate only the prefix.' })}</span 19357 > <span class="tmeta-who">${e}</span></span 19358 ><span class="tmeta-sep" aria-hidden="true">·</span>` : I} 19359 <span class="tmeta-count" 19360 >${this.renderCountIcon()} ${this.commentCountLabel(s.commentCount)}</span 19361 > 19362 ${i ? g`<span class="tmeta-sep" aria-hidden="true">·</span><span class="tmeta-last" 19363 >${u(A`hace ${i}`, { id: "forum.meta.lastComment", desc: 'Last activity in the meta line. Carries the relative-time connector ("hace" / "ago" / "vor" \u2026); the age placeholder is the bare localized duration from formatForumAge (e.g. "5 d\xEDas"), so it reads "hace 5 d\xEDas" / "5 days ago". Translate the connector to agree grammatically with the unit per locale.' })}</span 19364 >` : I} 19365 </div> 19366 ${t.length > 0 ? t.map((a) => this.renderComment(a, r)) : s.commentCount === 0 ? this.renderEmpty(s.href) : I} 19367 </article> 19368 `; 19369 } 19370 render() { 19371 const s = this.parsedThreads; 19372 if (s.length === 0) 19373 return I; 19374 const t = this.displayName, e = Di(this.forumHref); 19375 return g` 19376 <section class="rnk-ForumBlock forum" role="region" aria-label=${u("Foros de la comunidad", { id: "forum.region.label", desc: "Accessible label for the forum block region" })}> 19377 <div class="f-head"> 19378 <div class="f-headmain"> 19379 ${this.plainHeading ? I : g`<div class="eyebrow-row"> 19380 <span class="rk-eyebrow">${u("Comunidad", { id: "forum.eyebrow", desc: "Eyebrow label above the forum block heading" })}</span> 19381 </div>`} 19382 <h2 class="f-title"> 19383 ${t ? g`${u("Hilos sobre", { id: "forum.section.title", desc: "Section heading, followed by the asset name" })} 19384 ${this.plainHeading ? g`${t}` : g`<em class="f-deco">${t}</em>`}` : u("Foros de la comunidad", { id: "forum.section.title.generic", desc: "Section heading when the asset name is unknown" })} 19385 </h2> 19386 ${this.renderTotals()} 19387 </div> 19388 </div> 19389 19390 <div class="threads">${s.map((i) => this.renderCard(i))}</div> 19391 19392 ${e ? g`<div class="card-cta"> 19393 ${t ? g`<p class="f-footnote">${u(A`Estos son los hilos más activos de ${t}. Entra en cualquiera para leer y comentar.`, { id: "forum.footer.intro", desc: "Forum block footer intro line" })}</p>` : I} 19394 <a class="rk-btn rk-btn--comment" href=${e}> 19395 ${t ? u(A`Ver foro de ${t}`, { id: "forum.cta", desc: "Call to action: go to the full forum of <asset>" }) : u("Ver foro completo", { id: "forum.cta.generic", desc: "Call to action when the asset name is unknown" })}
19396 <span aria-hidden="true">â</span> 19397 </a> 19398 </div>` : I} 19399 </section> 19400 `; 19401 } 19402 }; 19403 X.RENDERED_MARKER_ATTR = "data-rnk-rendered"; 19404 X.STYLE_TAG_ID = "rnk-stock-forum-block-styles"; 19405 Rt([ 19406 $({ type: String }) 19407 ], X.prototype, "symbol", 2); 19408 Rt([ 19409 $({ type: String }) 19410 ], X.prototype, "name", 2); 19411 Rt([ 19412 $({ type: String, attribute: "forum-href" }) 19413 ], X.prototype, "forumHref", 2); 19414 Rt([ 19415 $({ type: Boolean, attribute: "plain-heading" }) 19416 ], X.prototype, "plainHeading", 2); 19417 Rt([ 19418 $({ type: String }) 19419 ], X.prototype, "threads", 2); 19420 Rt([ 19421 $({ type: Number, attribute: "max-threads" }) 19422 ], X.prototype, "maxThreads", 2); 19423 Rt([ 19424 $({ type: Number, attribute: "total-comments" }) 19425 ], X.prototype, "totalComments", 2); 19426 Rt([ 19427 $({ type: Number, attribute: "total-threads" }) 19428 ], X.prototype, "totalThreads", 2); 19429 X = Rt([ 19430 lt(), 19431 it("stock-forum-block") 19432 ], X); 19433 var Mc = ` 19434.rnk-ForumBlock { 19435 --_primary: var(--rk-primary, #1A5275); 19436 --_primary-dark: var(--rk-primary-dark, #1C4B6C); 19437 --_accent: var(--rk-accent, #D4324B); 19438 --_accent-hover: #E81949; 19439 --_neutral-1: var(--rk-neutral-1, #F0F0F0); 19440 --_neutral-2: var(--rk-neutral-2, #D7E3EA); 19441 --_neutral-4: var(--rk-neutral-4, #383D43); 19442 --_neutral-light: var(--rk-neutral-light, #F6F6F6); 19443 --_muted: var(--rk-text-muted, #5A6773); 19444 --_border: var(--rk-border, #E6ECEF); 19445 --_radius-md: var(--rk-radius-md, 8px); 19446 --_radius-lg: var(--rk-radius-lg, 20px); 19447 --_shadow-sm: var(--rk-shadow-sm, 0 4px 10px 0 rgba(0,0,0,0.10)); 19448 --_shadow-md: var(--rk-shadow-md, 0 0 30px 5px rgba(0,0,0,0.07)); 19449 --_font-display: var(--rk-font-display, "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif); 19450 --_font-body: var(--rk-font-body, "Roboto", system-ui, -apple-system, "Segoe UI", sans-serif); 19451 --_font-deco: var(--rk-font-deco, "Playfair Display", "Times New Roman", Georgia, serif); 19452 19453 display: block; 19454 /* The block is NOT a card itself \u2014 each thread is. Transparent shell. */ 19455 background: transparent; 19456 padding: 0; 19457 font-family: var(--_font-body); 19458 color: var(--_neutral-4); 19459 box-sizing: border-box; 19460} 19461.rnk-ForumBlock *, .rnk-ForumBlock *::before, .rnk-ForumBlock *::after { box-sizing: border-box; } 19462 19463/* ---- header ---- */ 19464.rnk-ForumBlock .f-head { 19465 display: flex; 19466 align-items: flex-start; 19467 justify-content: space-between; 19468 gap: 24px; 19469 flex-wrap: wrap; 19470 margin-bottom: 24px; 19471} 19472.rnk-ForumBlock .eyebrow-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } 19473.rnk-ForumBlock .rk-eyebrow { 19474 font-family: var(--_font-display); 19475 font-weight: 600; 19476 font-size: 13px; 19477 line-height: 1; 19478 letter-spacing: 0.14em; 19479 text-transform: uppercase; 19480 color: var(--_accent); 19481} 19482.rnk-ForumBlock .f-title { 19483 font-family: var(--_font-display); 19484 font-weight: 500; 19485 font-size: 34px; 19486 line-height: 1.15; 19487 color: var(--_neutral-4); 19488 letter-spacing: -0.01em; 19489 margin: 0; 19490} 19491.rnk-ForumBlock .f-title .f-deco { 19492 font-family: var(--_font-deco); 19493 font-style: italic; 19494 font-weight: 500; 19495} 19496@media (max-width: 720px) { .rnk-ForumBlock .f-title { font-size: 26px; } } 19497.rnk-ForumBlock .sub { 19498 margin: 10px 0 0; 19499 font-family: var(--_font-body); 19500 font-size: 15px; 19501 line-height: 1.4; 19502 color: var(--_muted); 19503} 19504 19505/* ---- threads grid: two columns, one column under 820px ---- */ 19506.rnk-ForumBlock .threads { 19507 display: grid; 19508 grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); 19509 gap: 14px; 19510 align-items: start; 19511} 19512@media (max-width: 820px) { .rnk-ForumBlock .threads { grid-template-columns: 1fr; } } 19513 19514/* ---- thread card (whole card is the link) ---- */ 19515.rnk-ForumBlock .tcard { 19516 display: block; 19517 min-width: 0; 19518 overflow: hidden; 19519 background: #fff; 19520 border: 1px solid var(--_border); 19521 border-radius: var(--_radius-lg); 19522 padding: 16px 20px; 19523 color: inherit; 19524} 19525 19526.rnk-ForumBlock .tcard-title { 19527 display: block; 19528 font-family: var(--_font-display); 19529 font-weight: 600; 19530 font-size: 18px; 19531 line-height: 1.35; 19532 color: var(--_neutral-4); 19533 margin: 0; 19534 text-decoration: none; 19535 transition: color .12s ease; 19536} 19537.rnk-ForumBlock a.tcard-title:hover, 19538.rnk-ForumBlock a.tcard-title:focus-visible { color: var(--_primary); text-decoration: underline; } 19539.rnk-ForumBlock a.tcard-title:focus-visible, 19540.rnk-ForumBlock a.tcomment-mini:focus-visible { outline: 2px solid var(--_primary); outline-offset: 2px; } 19541 19542/* ---- single de-emphasized meta line: [avatar] author \xB7 count \xB7 age ---- */ 19543.rnk-ForumBlock .tmeta { 19544 display: flex; 19545 align-items: center; 19546 gap: 8px; 19547 margin: 7px 0 0; 19548 font-family: var(--_font-body); 19549 font-size: 13px; 19550 color: var(--_muted); 19551 white-space: nowrap; 19552} 19553/* El separador es texto, no un filete: va en el gris de la propia linea de 19554 metadatos. --_neutral-2 es el tinte claro que usan los fondos de foco, y 19555 ahi dejaba el punto casi invisible frente al #5A6773 del prototipo. */ 19556.rnk-ForumBlock .tmeta-sep { color: var(--_muted); } 19557/* Thread author: small avatar + "iniciado por <name>", name emphasized. */ 19558.rnk-ForumBlock .tmeta-author { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
19559.rnk-ForumBlock .tmeta-who { font-weight: 600; color: var(--_neutral-4); } 19560/* Comment count in the meta line: muted, with the same speech-bubble icon. */ 19561.rnk-ForumBlock .tmeta-count { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; } 19562.rnk-ForumBlock .tmeta-count svg { width: 15px; height: 15px; flex-shrink: 0; } 19563@media (max-width: 720px) { .rnk-ForumBlock .tmeta { flex-wrap: wrap; white-space: normal; } } 19564 19565/* ---- two-line latest-comment teaser (non-interactive) ---- */ 19566.rnk-ForumBlock .tcomment-mini { 19567 display: flex; 19568 align-items: flex-start; 19569 gap: 9px; 19570 min-width: 0; 19571 background: var(--_neutral-light); 19572 border-radius: var(--_radius-md); 19573 padding: 9px 12px; 19574 margin-top: 11px; 19575} 19576.rnk-ForumBlock .tcomment-mini + .tcomment-mini { margin-top: 6px; } 19577/* A comment that links to its post anchor: subtle affordance, not a blue link. */ 19578.rnk-ForumBlock a.tcomment-mini { 19579 text-decoration: none; 19580 color: inherit; 19581 cursor: pointer; 19582 transition: background .12s ease; 19583} 19584.rnk-ForumBlock a.tcomment-mini:hover, 19585.rnk-ForumBlock a.tcomment-mini:focus-visible { background: var(--_neutral-2); } 19586.rnk-ForumBlock .tc-av { 19587 width: 24px; 19588 height: 24px; 19589 border-radius: 50%; 19590 flex-shrink: 0;
19591 margin-top: 1px; 19592 display: grid; 19593 place-items: center; 19594 color: #fff; 19595 font-family: var(--_font-display); 19596 font-weight: 600; 19597 font-size: 10px; 19598 line-height: 1; 19599} 19600/* Real profile photo variant: same 24px circle, cropped to fill (no distortion). */ 19601.rnk-ForumBlock img.tc-av { 19602 display: block; 19603 object-fit: cover; 19604 background: var(--_neutral-2); 19605} 19606/* Smaller avatar for the thread author in the meta line (20px). */ 19607.rnk-ForumBlock .tc-av--sm { width: 20px; height: 20px; font-size: 9px; margin-top: 0; } 19608.rnk-ForumBlock .tcm-body { 19609 flex: 1; 19610 min-width: 0; 19611 font-family: var(--_font-body); 19612 font-size: 13.5px; 19613 line-height: 1.42; 19614 color: var(--_muted); 19615 display: -webkit-box; 19616 -webkit-line-clamp: 2; 19617 -webkit-box-orient: vertical; 19618 overflow: hidden; 19619} 19620/* Miguel: a lone comment gets a third line so it is not over-truncated. */ 19621.rnk-ForumBlock .tcomment-mini--solo .tcm-body { -webkit-line-clamp: 3; } 19622.rnk-ForumBlock .tcm-body .who { 19623 font-family: var(--_font-display); 19624 font-weight: 600; 19625 color: var(--_neutral-4); 19626 margin-right: 6px; 19627}
19628.rnk-ForumBlock .tcomment-mini.empty { align-items: center; flex-wrap: wrap; } 19629.rnk-ForumBlock .tcm-empty-text { font-family: var(--_font-body); font-size: 13.5px; color: var(--_muted); } 19630.rnk-ForumBlock .tcm-empty-cta { font-family: var(--_font-display); font-weight: 600; font-size: 13px; color: var(--_primary); } 19631 19632/* ---- footer: intro text (left) + CTA (right) ---- */ 19633.rnk-ForumBlock .card-cta { 19634 display: flex; 19635 justify-content: space-between; 19636 align-items: center; 19637 gap: 16px; 19638 margin-top: 22px; 19639} 19640.rnk-ForumBlock .f-footnote { 19641 margin: 0; 19642 min-width: 0; 19643 font-family: var(--_font-body); 19644 font-size: 14px; 19645 line-height: 1.45; 19646 color: var(--_muted); 19647} 19648.rnk-ForumBlock .rk-btn { 19649 display: inline-flex; 19650 align-items: center; 19651 justify-content: center; 19652 gap: 8px; 19653 font-family: var(--_font-display); 19654 font-weight: 500; 19655 font-size: 15px; 19656 line-height: 1; 19657 padding: 14px 24px; 19658 border-radius: 4px; 19659 border: 1px solid transparent; 19660 cursor: pointer; 19661 text-decoration: none; 19662 white-space: nowrap; 19663 transition: background 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease; 19664} 19665.rnk-ForumBlock .rk-btn--comment { 19666 background: #fff; 19667 color: var(--_neutral-4); 19668 border: 2px solid var(--_neutral-4); 19669} 19670.rnk-ForumBlock .rk-btn--comment:hover, 19671.rnk-ForumBlock .rk-btn--comment:focus-visible { 19672 background: var(--_neutral-4); 19673 color: #fff; 19674 border-color: var(--_neutral-4); 19675 box-shadow: var(--_shadow-sm); 19676} 19677@media (max-width: 720px) { 19678 .rnk-ForumBlock .card-cta { 19679 flex-direction: column; 19680 align-items: flex-start; 19681 width: 100%; 19682 } 19683} 19684`; 19685})(); 19686/** 19687 * @license 19688 * Copyright 2019 Google LLC 19689 * SPDX-License-Identifier: BSD-3-Clause 19690 */ 19691/** 19692 * @license 19693 * Copyright 2017 Google LLC 19694 * SPDX-License-Identifier: BSD-3-Clause 19695 */ 19696/** 19697 * @license 19698 * Copyright 2021 Google LLC 19699 * SPDX-License-Identifier: BSD-3-Clause 19700 */ 19701/** 19702 * @license 19703 * Copyright 2020 Google LLC 19704 * SPDX-License-Identifier: BSD-3-Clause 19705 */ 19706/** 19707 * @license 19708 * Copyright 2014 Travis Webb 19709 * SPDX-License-Identifier: MIT 19710 */ 19711/*! 19712 * @license 19713 * TradingView Lightweight Charts⢠v5.2.0 19714 * Copyright (c) 2026 TradingView, Inc. 19715 * Licensed under Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0 19716 */ 19717//
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.