1(() => { 2 // console.log('>> Site Assets index.js LOADED <<'); 3 // TABS system 4 let tabGroups = document.querySelectorAll('.container-tabs'); 5 tabGroups.forEach((g) => { 6 let groupHead = document.createElement('div'); 7 let groupBody = document.createElement('div'); 8 groupHead.classList.add('container-tab-head-group'); 9 groupHead.setAttribute('data-tab-head', 'tab-head-group'); 10 groupBody.classList.add('container-tab-body-group'); 11 // let tabs = g.querySelectorAll('.container-tab'); 12 let tabs = [...g.children]; 13 let removeBtn = null; 14 tabs.forEach((t) => { 15 let head = t.children[0]?.classList?.contains('container-tab-head') 16 ? t.children[0] 17 : null; 18 let body = t.children[1]?.classList?.contains('container-tab-body') 19 ? t.children[1] 20 : null; 21 if (head && body) { 22 groupHead.appendChild(head); 23 groupBody.appendChild(body); 24 head.setAttribute('title', head.innerText.trim()); 25 body.setAttribute('data-title', head.innerText.trim()); 26 head.addEventListener('click', () => { 27 [...head.parentElement.children].forEach((c) => 28 c.classList.remove('active'), 29 ); 30 [...body.parentElement.children].forEach((c) => 31 c.classList.remove('active'), 32 ); 33 head.classList.add('active'); 34 body.classList.add('active'); 35 }); 36 } 37 if (t.classList?.contains('page-widget-delete-button')) { 38 removeBtn = t; 39 } 40 t.remove(); 41 }); 42 g.appendChild(groupHead); 43 g.appendChild(groupBody); 44 if (removeBtn) g.appendChild(removeBtn); 45 groupHead.children[0]?.classList.add('active'); 46 groupBody.children[0]?.classList.add('active'); 47 }); 48 49 // Rich Text Renderer 50 const tinymceStyles = ` 51 /*@import url('https://fonts.googleapis.com/css2?family=Cabin&family=Dosis&family=Nunito&family=Raleway&family=Urbanist&display=swap'); 52 @font-face { 53 font-family: 'Hikou'; 54 font-style: normal; 55 font-weight: 400; 56 font-display: swap; 57 src: url(/fonts/Hikou_Regular.otf) format('opentype'); 58 } 59 body { font-family: Arial; }*/ 60 table { max-width: 100%; block-size: auto; border-collapse: collapse; } 61 img { max-width: 100%; block-size: auto; } 62 iframe { max-width: 100%; border: none; } 63 64 /******* base.css ********/ 65 .ulli li{ 66 list-style:inside none circle; 67 } 68 69 /* #Typography 70 ================================================== */ 71 h1, h2, h3, h4, h5, h6 { 72 color: #181818; 73 /*font-family: "Georgia", "Times New Roman", serif;*/ 74 font-weight: normal; 75 } 76 h3, h4, h5, h6 { 77 margin: 0; 78 } 79 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; } 80 h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;} 81 h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; } 82 h3 {font-size: 28px;line-height: 34px;margin-bottom: 8px;} 83 h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; } 84 h5 { font-size: 17px; line-height: 24px; } 85 h6 { font-size: 14px; line-height: 21px; } 86 .subheader { color: #777; } 87 88 p { margin: 0 0 20px 0; /*width:100%;*/ width:-webkit-fill-available; } 89 p img { margin: 0; } 90 p.lead { font-size: 21px; line-height: 27px; color: #777; } 91 92 em { font-style: italic; } 93 strong { font-weight: bold; /*color: #333;*/ } 94 small { font-size: 80%; } 95 96 /* Blockquotes */ 97 blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; } 98 blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; } 99 blockquote cite { display: block; font-size: 12px; color: #555; } 100 blockquote cite:before { content: "\\2014 \\0020"; } 101 blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; } 102 103 hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; } 104 105 /* #Links 106 ================================================== */ 107 a, a:visited { color: #333; text-decoration: none; outline: 0; } 108 a:hover, a:focus { color: #000; } 109 p a, p a:visited { line-height: inherit; } 110 111
112 /* #Lists 113 ================================================== */ 114 ul, ol { margin-bottom: 20px; } 115 ul { list-style: none; } 116 #left-content ul { list-style: disc; } 117 /*#left-content ul li{ margin-left: 20px }*/ 118 119 ol { list-style: decimal; } 120 ol, ul.square, ul.circle, ul.disc { margin-left: 30px; } 121 ul.square { list-style: square outside; } 122 ul.circle { list-style: circle outside; } 123 ul.disc { list-style: disc outside; } 124 /*ul ul, ul ol, ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }*/ 125 ul ul li, ul ol li, ol ol li, ol ul li { margin-bottom: 6px; } 126 li { line-height: 18px; margin-bottom: 12px; } 127 ul.large li { line-height: 21px; } 128 li p { line-height: 21px; } 129 130 /* #Images 131 ================================================== */ 132 img.scale-with-grid { 133 max-width: 100%; 134 height: auto; 135 } 136 `; 137 138 const ckEditorStyles = ` 139:root{ 140 --ck-color-mention-background:hsla(341, 100%, 30%, 0.1); 141 --ck-color-mention-text:hsl(341, 100%, 30%); 142} 143.ck-content .mention{ 144 background:var(--ck-color-mention-background); 145 color:var(--ck-color-mention-text); 146} 147 148.ck-content code{ 149 background-color:hsla(0, 0%, 78%, 0.3); 150 padding:.15em; 151 border-radius:2px; 152} 153 154.ck-content blockquote{ 155 overflow:hidden; 156 padding-right:1.5em; 157 padding-left:1.5em; 158 159 margin-left:0; 160 margin-right:0; 161 font-style:italic; 162 border-left:solid 5px hsl(0, 0%, 80%); 163} 164 165.ck-content[dir="rtl"] blockquote{ 166 border-left:0; 167 border-right:solid 5px hsl(0, 0%, 80%); 168} 169 170.ck-content pre{ 171 padding:1em; 172 color:hsl(0, 0%, 20.8%); 173 background:hsla(0, 0%, 78%, 0.3); 174 border:1px solid hsl(0, 0%, 77%); 175 border-radius:2px; 176 text-align:left; 177 direction:ltr; 178 tab-size:4; 179 white-space:pre-wrap; 180 font-style:normal;
181 min-width:200px; 182} 183 184.ck-content pre code{ 185 background:unset; 186 padding:0; 187 border-radius:0; 188} 189.ck-content .text-tiny{ 190 font-size:.7em; 191} 192.ck-content .text-small{ 193 font-size:.85em; 194} 195.ck-content .text-big{ 196 font-size:1.4em; 197} 198.ck-content .text-huge{ 199 font-size:1.8em; 200} 201 202:root{ 203 --ck-highlight-marker-yellow:hsl(60, 97%, 73%); 204 --ck-highlight-marker-green:hsl(120, 93%, 68%); 205 --ck-highlight-marker-pink:hsl(345, 96%, 73%); 206 --ck-highlight-marker-blue:hsl(201, 97%, 72%); 207 --ck-highlight-pen-red:hsl(0, 85%, 49%); 208 --ck-highlight-pen-green:hsl(112, 100%, 27%); 209} 210 211.ck-content .marker-yellow{ 212 background-color:var(--ck-highlight-marker-yellow); 213} 214.ck-content .marker-green{ 215 background-color:var(--ck-highlight-marker-green); 216} 217.ck-content .marker-pink{ 218 background-color:var(--ck-highlight-marker-pink); 219} 220.ck-content .marker-blue{ 221 background-color:var(--ck-highlight-marker-blue); 222} 223 224.ck-content .pen-red{ 225 color:var(--ck-highlight-pen-red); 226 background-color:transparent; 227} 228.ck-content .pen-green{ 229 color:var(--ck-highlight-pen-green); 230 background-color:transparent; 231} 232 233.ck-content hr{ 234 margin:15px 0; 235 height:4px; 236 background:hsl(0, 0%, 87%); 237 border:0; 238} 239 240:root{ 241 --ck-color-image-caption-background:hsl(0, 0%, 97%); 242 --ck-color-image-caption-text:hsl(0, 0%, 20%); 243} 244.ck-content .image > figcaption{ 245 display:table-caption; 246 caption-side:bottom; 247 word-break:break-word; 248 color:var(--ck-color-image-caption-text); 249 background-color:var(--ck-color-image-caption-background); 250 padding:.6em; 251 font-size:.75em; 252 outline-offset:-1px; 253} 254@media (forced-colors: active){ 255 .ck-content .image > figcaption{ 256 background-color:unset; 257 color:unset; 258 } 259} 260.ck-content img.image_resized{ 261 height:auto; 262} 263 264.ck-content .image.image_resized{ 265 max-width:100%; 266 display:block; 267 box-sizing:border-box; 268} 269 270.ck-content .image.image_resized img{ 271 width:100%; 272} 273 274.ck-content .image.image_resized > figcaption{ 275 display:block; 276} 277 278:root{ 279 --ck-image-style-spacing:1.5em; 280 --ck-inline-image-style-spacing:calc(var(--ck-image-style-spacing) / 2); 281} 282 283.ck-content .image.image-style-block-align-left, 284.ck-content .image.image-style-block-align-right{ 285 max-width:calc(100% - var(--ck-image-style-spacing)); 286} 287 288.ck-content .image.image-style-align-left, 289.ck-content .image.image-style-align-right{ 290 clear:none; 291} 292 293.ck-content .image.image-style-side{ 294 float:right; 295 margin-left:var(--ck-image-style-spacing); 296 max-width:50%; 297} 298 299.ck-content .image.image-style-align-left{ 300 float:left; 301 margin-right:var(--ck-image-style-spacing); 302} 303 304.ck-content .image.image-style-align-right{ 305 float:right; 306 margin-left:var(--ck-image-style-spacing); 307} 308 309.ck-content .image.image-style-block-align-right{ 310 margin-right:0; 311 margin-left:auto; 312} 313 314.ck-content .image.image-style-block-align-left{ 315 margin-left:0; 316 margin-right:auto; 317} 318 319.ck-content .image-style-align-center{ 320 margin-left:auto; 321 margin-right:auto; 322} 323 324.ck-content .image-style-align-left{ 325 float:left; 326 margin-right:var(--ck-image-style-spacing); 327} 328 329.ck-content .image-style-align-right{ 330 float:right; 331 margin-left:var(--ck-image-style-spacing); 332} 333 334.ck-content p + .image.image-style-align-left, 335.ck-content p + .image.image-style-align-right, 336.ck-content p + .image.image-style-side{ 337 margin-top:0; 338} 339 340.ck-content .image-inline.image-style-align-left, 341.ck-content .image-inline.image-style-align-right{ 342 margin-top:var(--ck-inline-image-style-spacing); 343 margin-bottom:var(--ck-inline-image-style-spacing); 344} 345 346.ck-content .image-inline.image-style-align-left{ 347 margin-right:var(--ck-inline-image-style-spacing); 348} 349 350.ck-content .image-inline.image-style-align-right{ 351 margin-left:var(--ck-inline-image-style-spacing); 352} 353 354.ck-content .image{ 355 display:table; 356 clear:both; 357 text-align:center; 358 margin:0.9em auto; 359 min-width:50px; 360} 361 362.ck-content .image img{ 363 display:block; 364 margin:0 auto; 365 max-width:100%; 366 min-width:100%; 367 height:auto; 368} 369 370.ck-content .image-inline{ 371 display:inline-flex; 372 max-width:100%; 373 align-items:flex-start; 374} 375 376.ck-content .image-inline picture{ 377 display:flex; 378} 379 380.ck-content .image-inline picture, 381.ck-content .image-inline img{ 382 flex-grow:1; 383 flex-shrink:1; 384 max-width:100%; 385} 386 387.ck-content ol{ 388 list-style-type:decimal; 389} 390 391.ck-content ol ol{ 392 list-style-type:lower-latin; 393} 394 395.ck-content ol ol ol{ 396 list-style-type:lower-roman; 397} 398 399.ck-content ol ol ol ol{ 400 list-style-type:upper-latin; 401} 402 403.ck-content ol ol ol ol ol{ 404 list-style-type:upper-roman; 405} 406 407.ck-content ul{ 408 list-style-type:disc; 409} 410 411.ck-content ul ul{ 412 list-style-type:circle; 413} 414 415.ck-content ul ul ul{ 416 list-style-type:square; 417} 418 419.ck-content ul ul ul ul{ 420 list-style-type:square; 421} 422 423:root{ 424 --ck-todo-list-checkmark-size:16px; 425} 426.ck-content .todo-list{ 427 list-style:none; 428} 429.ck-content .todo-list li{ 430 position:relative; 431 margin-bottom:5px; 432} 433.ck-content .todo-list li .todo-list{ 434 margin-top:5px; 435} 436.ck-content .todo-list .todo-list__label > input{ 437 -webkit-appearance:none; 438 display:inline-block; 439 position:relative; 440 width:var(--ck-todo-list-checkmark-size); 441 height:var(--ck-todo-list-checkmark-size); 442 vertical-align:middle; 443 border:0; 444 left:-25px; 445 margin-right:-15px; 446 right:0; 447 margin-left:0; 448} 449.ck-content[dir=rtl] .todo-list .todo-list__label > input{ 450 left:0; 451 margin-right:0; 452 right:-25px; 453 margin-left:-15px; 454} 455.ck-content .todo-list .todo-list__label > input::before{ 456 display:block; 457 position:absolute; 458 box-sizing:border-box; 459 content:''; 460 width:100%; 461 height:100%; 462 border:1px solid hsl(0, 0%, 20%); 463 border-radius:2px; 464 transition:250ms ease-in-out box-shadow; 465} 466@media (prefers-reduced-motion: reduce){ 467 .ck-content .todo-list .todo-list__label > input::before{ 468 transition:none; 469 } 470} 471.ck-content .todo-list .todo-list__label > input::after{ 472 display:block; 473 position:absolute; 474 box-sizing:content-box; 475 pointer-events:none; 476 content:''; 477 left:calc( var(--ck-todo-list-checkmark-size) / 3); 478 top:calc( var(--ck-todo-list-checkmark-size) / 5.3); 479 width:calc( var(--ck-todo-list-checkmark-size) / 5.3); 480 height:calc( var(--ck-todo-list-checkmark-size) / 2.6); 481 border-style:solid; 482 border-color:transparent; 483 border-width:0 calc( var(--ck-todo-list-checkmark-size) / 8) calc( var(--ck-todo-list-checkmark-size) / 8) 0; 484 transform:rotate(45deg); 485} 486.ck-content .todo-list .todo-list__label > input[checked]::before{ 487 background:hsl(126, 64%, 41%); 488 border-color:hsl(126, 64%, 41%); 489} 490.ck-content .todo-list .todo-list__label > input[checked]::after{ 491 border-color:hsl(0, 0%, 100%); 492} 493.ck-content .todo-list .todo-list__label .todo-list__label__description{ 494 vertical-align:middle; 495} 496.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox]{ 497 position:absolute; 498} 499 500.ck-content .media{ 501 clear:both; 502 margin:0.9em 0; 503 display:block; 504 min-width:15em; 505} 506 507.ck-content .page-break{ 508 position:relative; 509 clear:both; 510 padding:5px 0; 511 display:flex; 512 align-items:center; 513 justify-content:center; 514} 515 516.ck-content .page-break::after{ 517 content:''; 518 position:absolute; 519 border-bottom:2px dashed hsl(0, 0%, 77%); 520 width:100%; 521} 522 523.ck-content .page-break__label{ 524 position:relative; 525 z-index:1; 526 padding:.3em .6em; 527 display:block; 528 text-transform:uppercase; 529 border:1px solid hsl(0, 0%, 77%); 530 border-radius:2px; 531 font-family:Helvetica, Arial, Tahoma, Verdana, Sans-Serif; 532 font-size:0.75em; 533 font-weight:bold; 534 color:hsl(0, 0%, 20%); 535 background:hsl(0, 0%, 100%); 536 box-shadow:2px 2px 1px hsla(0, 0%, 0%, 0.15); 537 -webkit-user-select:none; 538 -moz-user-select:none; 539 -ms-user-select:none; 540 user-select:none; 541} 542@media print{ 543 .ck-content .page-break{ 544 padding:0; 545 } 546 .ck-content .page-break::after{ 547 display:none; 548 } 549 .ck-content *:has(+ .page-break){ 550 margin-bottom:0; 551 } 552} 553 554.ck-content .table{ 555 margin:0.9em auto; 556 display:table; 557} 558 559.ck-content .table table{ 560 border-collapse:collapse; 561 border-spacing:0; 562 width:100%; 563 height:100%; 564 border:1px double hsl(0, 0%, 70%); 565} 566 567.ck-content .table table td, 568.ck-content .table table th{ 569 min-width:2em; 570 padding:.4em; 571 border:1px solid hsl(0, 0%, 75%); 572} 573 574.ck-content .table table th{ 575 font-weight:bold; 576 background:hsla(0, 0%, 0%, 5%); 577} 578@media print{ 579 .ck-content .table table{ 580 height:initial; 581 } 582} 583.ck-content[dir="rtl"] .table th{ 584 text-align:right; 585} 586 587.ck-content[dir="ltr"] .table th{ 588 text-align:left; 589} 590 591:root{ 592 --ck-color-selector-caption-background:hsl(0, 0%, 97%); 593 --ck-color-selector-caption-text:hsl(0, 0%, 20%); 594} 595.ck-content .table > figcaption{ 596 display:table-caption; 597 caption-side:top; 598 word-break:break-word; 599 text-align:center; 600 color:var(--ck-color-selector-caption-text); 601 background-color:var(--ck-color-selector-caption-background); 602 padding:.6em; 603 font-size:.75em; 604 outline-offset:-1px; 605} 606@media (forced-colors: active){ 607 .ck-content .table > figcaption{ 608 background-color:unset; 609 color:unset; 610 } 611} 612 613.ck-content .table .ck-table-resized{ 614 table-layout:fixed; 615} 616 617.ck-content .table table{ 618 overflow:hidden; 619} 620 621.ck-content .table td, 622.ck-content .table th{ 623 overflow-wrap:break-word; 624 position:relative; 625} 626`; 627 628 const shadowDomStyles = ` 629 .wrapper { 630 font-family:var(--font-secondary-en);
631 overflow-wrap: anywhere; 632 background-color: #fff0; 633 overflow: auto;/* clear fix */ 634 /*overflow: initial;*/ 635 } 636 .wrapper::after {/* clear fix */ 637 content: ""; 638 clear: both; 639 display: table; 640 } 641 .wrapper.slim-width { 642 overflow: hidden;/* clear fix */ 643 } 644 /*.wrapper.slim-width img:not(table img)*/ 645 .wrapper.slim-width img:not(table img):not(.title img):first-child:last-child { 646 display: block; 647 box-sizing: border-box; 648 height: auto !important; 649 width: 100% !important; 650 max-height: 720px; 651 margin-left: 0 !important; 652 margin-right: 0 !important; 653 } 654 .wrapper.slim-width .__rt_only_nbsp:first-child { display: none; } 655 .wrapper.slim-width .__rt_only_nbsp+.__rt_only_nbsp { display: none; } 656 .wrapper ul li { 657 height: auto; 658 box-sizing: border-box; 659 } 660 .wrapper.slim-width ul li { 661 padding-top: 0px; 662 padding-bottom: 8px; 663 padding-left: 32px; 664 list-style-type: none; 665 margin-bottom: 5px; 666 background: url("/site-assets/images/right-tick.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0); 667 background-position: 0px 1px; 668 } 669 .wrapper p { 670 margin:0; 671 font-size:var(--typography-body-font-size) 672 } 673 .wrapper.slim-width ul { 674 padding:0;/**/ 675 /*list-style: none;*/ 676 list-style: circle; 677 list-style-position: inside; 678 } 679 .wrapper a{ 680 text-decoration:none; 681 color:var(--color-normal-text); 682 } 683 .wrapper a[href], .wrapper a[href]:visited { text-decoration: none; } 684 .wrapper a[href$=".pdf"], 685 .wrapper a[href$=".jpg"], 686 .wrapper a[href$=".jpeg"], 687 .wrapper a[href$=".png"], 688 .wrapper a[href$=".gif"], 689 .wrapper a[href$=".bmp"], 690 .wrapper a[href$=".webp"] { 691 /*text-decoration: underline;*/ 692 } 693 td { 694 box-sizing: border-box !important; 695 padding: 5px !important; 696 border: 1px solid #aaa !important; 697 overflow-wrap: break-word; 698 } 699 .wrapper iframe{ 700 box-sizing: border-box; 701 } 702 .wrapper>marquee{ 703 margin: 10px 0px; 704 } 705 table img { max-width: unset; } 706 `; 707 708 const modifyOldStyles = ` 709 .wrapper.slim-width p span strong > a { /* DIRTY FIX FOR: à¦à¦°à§à¦°à¦¿ হà§à¦²à§à¦ªà¦²à¦¾à¦à¦¨ নমà§à¦¬à¦° */ /* UPDATE: slim-width */ 710 /*text-decoration:underline;*/ 711 float:right; 712 } 713 h3.title, h4.title, h5.title, h6.title { 714 background-color: var(--color-primary-dark); 715 color: var(--color-secondary-text); 716 padding: var(--spacing-small); 717 font-size: var(--text-medium); 718 /*border-radius: var(--radius-small);*/ 719 font-weight: 600; 720 margin: var(--spacing-small) 0; 721 display: flex; 722 align-items: center 723 } 724 h3.title img, h4.title img, h5.title img, h6.title img { 725 height: 28px; 726 width: 28px; 727 margin-right: 8px; 728 } 729 `; 730 731 function urlContentToDataUri(url) { 732 return fetch(url) 733 .then((response) => response.blob()) 734 .then( 735 (blob) => 736 new Promise((callback) => { 737 let reader = new FileReader(); 738 reader.onload = function () { 739 callback(this.result); 740 }; 741 reader.readAsDataURL(blob); 742 }), 743 ); 744 } 745 746 const fileBaseUrl = '/'; 747 748 class RichTextRenderer extends HTMLElement { 749 initialHTML = ''; 750 751 constructor() { 752 // Always call super first in constructor 753 super(); 754 // console.log('CON >>', this); 755 // Element functionality written in here 756 } 757 758 connectedCallback() { 759 // console.log('Custom tinymce element added to page.', super.innerHTML); 760 this.initialHTML = super.innerHTML; 761 this.innerText = ''; 762 this.renderer(); 763 } 764 765 disconnectedCallback() { 766 // console.log('Custom tinymce element removed from page.'); 767 } 768 769 adoptedCallback() { 770 // console.log('Custom tinymce element moved to new page.'); 771 } 772 773 attributeChangedCallback(name, oldValue, newValue) { 774 // console.log('RTRenderer attributes >>', [name, oldValue, newValue]); 775 // updateStyle(this); 776 function isBase64(str) { 777 //TODO this is dirty fix 778 try { 779 return btoa(atob(str)) === str; 780 } catch { 781 return false;
782 } 783 } 784 785 if (name === 'slim-width') { 786 this.slimWidth = true; 787 this.renderer(); 788 } else if (name === 'encoded-content' && newValue !== '') { 789 this.encodedContent = newValue; 790 const chunks = newValue.split(';'); 791 const newHTML = chunks 792 .map((chunk) => { 793 if (isBase64(chunk)) { 794 return new TextDecoder().decode( 795 Uint8Array.from(atob(chunk), (c) => c.charCodeAt(0)), 796 ); 797 } else { 798 return chunk; //TODO fix me 799 } 800 }) 801 .join(''); 802 // console.log('RTRenderer attributeChangedCallback >>', newHTML); 803 this.initialHTML = newHTML; 804 this.renderer(); 805 } 806 } 807 808 static get observedAttributes() { 809 // console.log('RTRenderer observedAttributes >>'); 810 return ['c', 'l', 'slim-width', 'encoded-content']; 811 } 812 813 updateStyle(elem) { 814 const shadow = elem.shadowRoot; 815 shadow.querySelector('style').textContent = ` 816 div { 817 width: ${elem.getAttribute('l')}px; 818 height: ${elem.getAttribute('l')}px; 819 background-color: ${elem.getAttribute('c')}; 820 } 821 `; 822 } 823 824 renderer() { 825 // console.log('RENDERER >>', [this.wrapper, this.initialHTML]); 826 // Create a shadow root 827 if (!this.shadowRoot) { 828 this.attachShadow({mode: 'open'}); // sets and returns 'this.shadowRoot' 829 const wrapper = document.createElement('div'); 830 wrapper.setAttribute('class', 'wrapper ck-content'); 831 const style = document.createElement('style'); 832 style.textContent = this.innerStyles; 833 // CSS truncated for brevity 834 wrapper.textContent = ''; 835 // attach the created elements to the shadow DOM 836 this.shadowRoot.append(style, wrapper); 837 this.wrapper = wrapper; 838 } 839 if (this.innerHTML.length === 0) this.innerHTML = this.initialHTML; 840 if (this.slimWidth) this.wrapper.classList.add('slim-width'); 841 else this.wrapper.classList.remove('slim-width'); 842 } 843 844 set innerHTML(html) { 845 // console.log('HTML >>', [html, this.wrapper, this.initialHTML]); 846 if (this.wrapper) { 847 super.innerHTML = ''; 848 let renderHTML = this.initialHTML; 849 renderHTML = renderHTML.replaceAll( 850 `<div>Â </div>`, 851 `<div class="__rt_only_nbsp">Â </div>`, 852 ); 853 renderHTML = renderHTML.replaceAll( 854 `<p>Â </p>`, 855 `<p class="__rt_only_nbsp">Â </p>`, 856 ); 857 this.wrapper.innerHTML = renderHTML + `<p style="__rt_end"> </p>`; 858 this.runJS(); 859 } 860 } 861 862 get innerHTML() { 863 return this.wrapper ? this.wrapper.innerHTML : ''; 864 } 865 866 get innerText() { 867 return this.wrapper ? this.wrapper.innerText : ''; 868 } 869 870 set innerText(text) { 871 // do nothing 872 } 873 874 get innerStyles() { 875 return tinymceStyles + ckEditorStyles + shadowDomStyles + modifyOldStyles; 876 } 877 878 // js for the content behaviors 879 runJS() { 880 [...this.wrapper.querySelectorAll('img')].forEach((v) => { 881 var src = v.getAttribute('src'); 882 if (src.search(fileBaseUrl) === 0) 883 urlContentToDataUri(src).then((dataURI) => { 884 // console.log('dataURI >>', dataURI); 885 v.setAttribute('data-src', src); 886 v.setAttribute('src', dataURI); 887 }); 888 }); 889 // marquee play / pause 890 [...this.wrapper.querySelectorAll('marquee')].forEach((v) => { 891 v.setAttribute('onpointerleave', 'this.start()'); 892 v.setAttribute('onpointerenter', 'this.stop()'); 893 }); 894 } 895 } 896 897 customElements.define('rt-renderer', RichTextRenderer); 898 899 class PlainTextRenderer extends RichTextRenderer { 900 constructor() { 901 super(); 902 this.lineClamp = 0; 903 } 904 905 attributeChangedCallback(name, oldValue, newValue) { 906 if (name === 'line-clamp') { 907 this.lineClamp = parseInt(newValue) || 0; 908 this.renderer(); 909 } else { 910 super.attributeChangedCallback(name, oldValue, newValue); 911 } 912 } 913 914 static get observedAttributes() { 915 // console.log('RTRenderer observedAttributes >>'); 916 return ['c', 'l', 'slim-width', 'encoded-content', 'line-clamp']; 917 } 918 919 renderer() { 920 super.renderer(); 921 if (this.lineClamp > 0) { 922 this.wrapper.style.display = '-webkit-box'; 923 this.wrapper.style.webkitBoxOrient = 'vertical'; 924 this.wrapper.style.webkitLineClamp = `${this.lineClamp}`; 925 this.wrapper.style.lineClamp = `${this.lineClamp}`; 926 this.wrapper.style.overflow = 'hidden'; 927 this.wrapper.style.textOverflow = 'ellipsis'; 928 } else { 929 this.wrapper.removeAttribute('style'); 930 } 931 } 932 933 set innerHTML(html) { 934 // console.log('HTML >>', [html, this.wrapper, this.initialHTML]); 935 if (this.wrapper) { 936 super.innerHTML = ''; 937 let renderHTML = this.initialHTML; 938 renderHTML = renderHTML.replaceAll( 939 `<div>Â </div>`, 940 `<div class="__rt_only_nbsp">Â </div>`, 941 ); 942 renderHTML = renderHTML.replaceAll( 943 `<p>Â </p>`, 944 `<p class="__rt_only_nbsp">Â </p>`, 945 ); 946 const temp = document.createElement('div'); 947 temp.innerHTML = renderHTML.replaceAll('</', '\n</'); 948 this.wrapper.innerHTML = `<div>${temp.innerText.split(/\n[\n\s]*/).join('</div><div>')}</div>`; 949 this.runJS(); 950 } 951 } 952 953 get innerStyles() { 954 return ''; 955 } 956 957 get innerHTML() { 958 return this.wrapper ? this.wrapper.innerHTML : ''; 959 } 960 } 961 962 customElements.define('pt-renderer', PlainTextRenderer); 963 964 window.encodeRT = (txt) => { 965 let temp = '' + txt; 966 const chunks = [], 967 size = 10240; 968 while (temp.length > size) { 969 chunks.push(temp.substring(0, size)); 970 temp = temp.slice(size); 971 } 972 chunks.push(temp); 973 return chunks 974 .map((c) => btoa(String.fromCharCode(...new TextEncoder().encode(c)))) 975 .join(';'); 976 }; 977 978 let fontFaceStylesInjected = false;
979 window.injectFontFacesRT = () => { 980 if (fontFaceStylesInjected) return; 981 const styleTag = document.createElement('style'); 982 styleTag.innerHTML = ` 983 @font-face { 984 font-family: 'BenSenHandwriting'; 985 font-style: normal; 986 font-weight: 400; 987 src: url(/site-assets/fonts/BenSenHandwriting.ttf) format('truetype'); 988 } 989 @font-face { 990 font-family: 'Roboto-Regular'; 991 font-style: normal; 992 font-weight: 400; 993 src: url(/site-assets/fonts/Roboto-Regular.ttf) format('truetype'); 994 } 995 @font-face { 996 font-family: 'Kalpurush'; 997 font-style: normal; 998 font-weight: 400; 999 src: url(/site-assets/fonts/kalpurush.ttf) format('truetype'); 1000 } 1001 @font-face { 1002 font-family: 'kalpurushregular'; 1003 font-style: normal; 1004 font-weight: 400; 1005 src: url(/site-assets/fonts/kalpurush.ttf) format('truetype'); 1006 }`; 1007 document.head.appendChild(styleTag); 1008 fontFaceStylesInjected = true; 1009 }; 1010 1011 document 1012 .querySelectorAll( 1013 '[data-section_type="right"] rt-renderer, [data-section_type="left"] rt-renderer', 1014 ) 1015 .forEach((el) => { 1016 el.setAttribute('slim-width', ''); 1017 }); 1018 1019 document.querySelectorAll('img').forEach((el) => { 1020 el.classList.add('image-loading'); 1021 el.onload = () => { 1022 el.classList.remove('image-loading'); 1023 }; 1024 el.onerror = () => { 1025 el.classList.remove('image-loading'); 1026 el.classList.add('image-loading-error'); 1027 }; 1028 el.src = el.getAttribute('src'); 1029 }); 1030 1031 if (/npf.test$/.test(window.location.host) && false) { 1032 let tryCount = 0; 1033 let rel = false; 1034 setInterval(() => { 1035 fetch(`/ajax/get/division/list`) 1036 .then((result) => { 1037 tryCount = 0; 1038 }) 1039 .catch((err) => { 1040 if (!rel) rel = '-' + window.location.reload(); 1041 }); 1042 tryCount++; 1043 if (tryCount > 3 && !rel) rel = '-' + window.location.reload(); 1044 }, 50); 1045 } 1046})(); 1047 1048// Track all sticky widgets 1049const stickyWidgets = []; 1050let rafId = null; 1051 1052// Update sticky positions efficiently 1053function updateStickyPositions() { 1054 let currentTop = 0; 1055 stickyWidgets.forEach(function (item) { 1056 if (item.isSticky) { 1057 const height = item.widget.offsetHeight; 1058 item.widget.style.top = currentTop + 'px'; 1059 currentTop += height; 1060 } 1061 }); 1062} 1063 1064// Handle scroll with requestAnimationFrame for smooth performance 1065function handleScroll() { 1066 if (rafId) return; // Already scheduled 1067 1068 rafId = requestAnimationFrame(function () { 1069 rafId = null; 1070 const scrollY = window.pageYOffset || window.scrollY; 1071 1072 stickyWidgets.forEach(function (item) { 1073 const widget = item.widget; 1074 const shouldBeSticky = scrollY >= item.originalTop; 1075 1076 if (shouldBeSticky && !item.isSticky) { 1077 // Become sticky 1078 const rect = widget.getBoundingClientRect(); 1079 widget.style.position = 'fixed'; 1080 widget.style.width = rect.width + 'px'; 1081 widget.style.boxSizing = 'border-box'; 1082 widget.style.zIndex = '1000'; 1083 1084 item.isSticky = true; 1085 1086 if (!item.spacer) { 1087 const spacer = document.createElement('div'); 1088 spacer.className = 'sticky-spacer'; 1089 spacer.style.height = widget.offsetHeight + 'px'; 1090 widget.parentNode.insertBefore(spacer, widget.nextSibling); 1091 item.spacer = spacer; 1092 } 1093 } else if (!shouldBeSticky && item.isSticky) { 1094 // Remove sticky 1095 widget.style.position = ''; 1096 widget.style.top = ''; 1097 widget.style.width = ''; 1098 widget.style.boxSizing = ''; 1099 widget.style.zIndex = ''; 1100 1101 item.isSticky = false; 1102 1103 if (item.spacer && item.spacer.parentNode) { 1104 item.spacer.remove(); 1105 item.spacer = null; 1106 } 1107 } 1108 }); 1109 1110 // Update positions only if there are sticky items 1111 if ( 1112 stickyWidgets.some(function (item) { 1113 return item.isSticky; 1114 }) 1115 ) { 1116 updateStickyPositions(); 1117 } 1118 }); 1119} 1120 1121function initSticky(elements) { 1122 const markers = 1123 typeof elements === 'object' && elements?.length ? elements : []; 1124 1125 if (!markers.length) return; 1126 1127 // Capture all original positions in one pass
1128 markers.forEach(function (marker) { 1129 const rect = marker.getBoundingClientRect(); 1130 stickyWidgets.push({ 1131 widget: marker, 1132 originalTop: rect.top + window.pageYOffset, 1133 isSticky: false, 1134 spacer: null, 1135 }); 1136 }); 1137 1138 // Handle resize - recalculate positions for all states 1139 let resizeTimer; 1140 function handleResize() { 1141 clearTimeout(resizeTimer); 1142 resizeTimer = setTimeout(function () { 1143 // Cancel any pending scroll animation 1144 if (rafId) { 1145 cancelAnimationFrame(rafId); 1146 rafId = null; 1147 } 1148 1149 // First, remove all sticky states temporarily to get accurate positions 1150 stickyWidgets.forEach(function (item) { 1151 if (item.isSticky) { 1152 item.widget.style.position = ''; 1153 item.widget.style.top = ''; 1154 item.widget.style.width = ''; 1155 item.widget.style.boxSizing = ''; 1156 item.widget.style.zIndex = ''; 1157 1158 if (item.spacer && item.spacer.parentNode) { 1159 item.spacer.remove(); 1160 item.spacer = null; 1161 } 1162 1163 item.isSticky = false; 1164 } 1165 }); 1166 1167 // Use requestAnimationFrame to ensure browser has reflowed 1168 requestAnimationFrame(function () { 1169 // Recalculate all original positions 1170 stickyWidgets.forEach(function (item) { 1171 const rect = item.widget.getBoundingClientRect(); 1172 item.originalTop = rect.top + window.pageYOffset; 1173 }); 1174 1175 // Reapply sticky states based on current scroll position 1176 handleScroll(); 1177 }); 1178 }, 10); 1179 } 1180 1181 // Initial check 1182 handleScroll(); 1183 1184 // Event listeners 1185 window.addEventListener('scroll', handleScroll, {passive: true}); 1186 window.addEventListener('resize', handleResize, {passive: true}); 1187} 1188 1189window.createStickyElements = (elements) => { 1190 initSticky(elements); 1191};
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.