PageSourceSearch

https://www.heritagemuseum.gov.hk/assets/js/common.min.js

js heritagemuseum.gov.hk collected 2026-10-02 07:47:20 UTC 164,203 bytes, 3,390 lines download raw bytes

1
2
3    
4var ua = navigator.userAgent.toLowerCase(),
5    isChrome = ua.indexOf("chrome") > -1,
6    isSafari = /^((?!chrome|android).)*safari/i.test(ua),
7    isFirefox = "undefined" != typeof InstallTrigger,
8    isIE = detectIE(),
9    isTouch = $(".touchevents").length;
10
11function detectIE() {
12    var e = window.navigator.userAgent,
13        t = e.indexOf("MSIE ");
14    if (t > 0) return parseInt(e.substring(t + 5, e.indexOf(".", t)), 10);
15    if (e.indexOf("Trident/") > 0) {
16        var n = e.indexOf("rv:");
17        return parseInt(e.substring(n + 3, e.indexOf(".", n)), 10)
18    }
19    var i = e.indexOf("Edge/");
20    return i > 0 && parseInt(e.substring(i + 5, e.indexOf(".", i)), 10)
21}
22var prefix = function () {
23    var e = window.getComputedStyle(document.documentElement, ""),
24        t = (Array.prototype.slice.call(e).join("").match(/-(moz|webkit|ms)-/) || "" === e.OLink && ["", "o"])[1];
25    return {
26        dom: "WebKit|Moz|MS|O".match(new RegExp("(" + t + ")", "i"))[1],
27        lowercase: t,
28        css: "-" + t + "-",
29        js: t[0].toUpperCase() + t.substr(1)
30    }
31}();
32isChrome && $("html").addClass("chrome"), isSafari && $("html").addClass("safari"), isFirefox && $("html").addClass("firefox"), isIE && $("html").addClass("ie ie-" + isIE);
33var clickEvent = isTouch ? "touchend" : "click",
34    resizeEvent = "orientationchange" in window ? "orientationchange" : "resize",
35    animationEnd = function (e) {
36        var t = {
37            animation: "animationend",
38            OAnimation: "oAnimationEnd",
39            WebkitAnimation: "webkitAnimationEnd"
40        };
41        for (var n in t)
42            if (void 0 !== e.style[n]) return t[n]
43    }(document.createElement("div")),
44    transitionEnd = function (e) {
45        var t = {
46            transition: "transitionend",
47            OTransition: "oTransitionEnd",
48            WebkitTransition: "webkitTransitionEnd"
49        };
50        for (var n in t)
51            if (void 0 !== e.style[n]) return t[n]
52    }(document.createElement("div")),
53    $window = $(window),
54    $html = $("html"),
55    $body = $("body");
56
57function getLang() {
58    var e = $html.attr("lang");
59    return "en" == e ? "en" : "zh-hk" == e ? "zh-hk" : "zh-cn" == e ? "zh-cn" : "en"
60    // return "en" == e ? "en" : "tc" == e ? "zh-hk" : "sc" == e ? "zh-cn" : "en"
61}
62
63function langArg(e) {
64    return e[getLang()]
65}
66
67function ckSTab(e) {
68    return 9 == e.which && e.shiftKey
69}
70
71function ckTab(e) {
72    return 9 == e.which && !e.shiftKey
73}
74
75function ckEsc(e) {
76    return 27 == e.which && !e.shiftKey
77}
78
79function getUrlParams(e) {
80    var t = e ? e.split("?")[1] : window.location.search.slice(1),
81        n = decodeURIComponent(t),
82        i = {};
83    if (n)
84        for (var o = (n = n.split("#")[0]).split("&"), r = 0; r < o.length; r++) {
85            var s = o[r].split("="),
86                a = s[0],
87                l = void 0 === s[1] || s[1];
88            if (a.match(/\[(\d+)?\]$/)) {
89                var c = a.replace(/\[(\d+)?\]/, "");
90                if (i[c] || (i[c] = []), a.match(/\[\d+\]$/)) {
91                    var u = /\[(\d+)\]/.exec(a)[1];
92                    i[c][u] = l
93                } else i[c].push(l)
94            } else i[a] ? i[a] && "string" == typeof i[a] ? (i[a] = [i[a]], i[a].push(l)) : i[a].push(l) : i[a] = l
95        }
96    return i
97}
98
99function isRetinaDisplay() {
100    if (window.matchMedia) {
101        var e = window.matchMedia("only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 2.6/2), only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen  and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 1.3dppx)");
102        return e && e.matches || window.devicePixelRatio > 1
103    }
104}
105
106function throttle(e, t) {
107    var n = !0;
108    return function (i) {
109        n && (n = !1, setTimeout(function () {
110            n = !0
111        }, t), e(i))
112    }
113}
114
115function looseParse(e) {
116    return Function('"use strict";return (' + e + ")")()
117}
118
119jQuery.fn.outerHTML = function () {
120    return jQuery("<div />").append(this.eq(0).clone()).html()
121}, jQuery.fn.nextOrFirst = function (e) {
122    var t = this.next(e);
123    return t.length ? t : this.prevAll(e).last()
124}, jQuery.fn.prevOrLast = function (e) {
125    var t = this.prev(e);
126    return t.length ? t : this.nextAll(e).last()
127}, jQuery.fn.reverse = [].reverse, jQuery.fn.shuffle = function () {
128    for (var e, t = 0; t < this.length; t++) e = Math.floor(Math.random() * this.length), $(this[t]).before($(this[e]));
129    return this
130};
131
132function checkURLexist(e) {
133    return e = e.replace("#top", ""), window.XMLHttpRequest ? (xhttp = new XMLHttpRequest, xhttp.open("GET", e, !1), xhttp.send(null), 200 == xhttp.status) : (xhttp = new ActiveXObject("Microsoft.XMLHTTP"), xhttp.open("GET", e, !1), xhttp.send(null), 200 == xhttp.status)
134}
135
136function validateSwapLangURL(text) {
137	var tmpText = text.replace(/"/g, "′");
138	tmpText = tmpText.replace(/'/g, "′");
139	return tmpText;
140}
141
142function swapLang(e) {
143    var t = String(window.location.href),
144        n = "";
145    if (-1 != t.indexOf("/tc/") && (n = "zh-hk"), -1 != t.indexOf("/en/") && (n = "en"), -1 != t.indexOf("/sc/") && (n = "zh-cn"), "en" == e ? "zh-hk" == n ? t = t.replace("/tc/", "/en/") : "zh-cn" == n && (t = t.replace("/sc/", "/en/")) : "zh-hk" == e ? "en" == n ? t = t.replace("/en/", "/tc/") : "zh-cn" == n && (t = t.replace("/sc/", "/tc/")) : "zh-cn" == e && ("en" == n ? t = t.replace("/en/", "/sc/") : "zh-hk" == n ? t = t.replace("/tc/", "/sc/") : "zh-cn" == n && (t = t.replace("/sc/", "/tc/"))), checkURLexist(t)) {
146        // Remarked by Calvin 21122020
147        // Original window.top.location.href = t;
148        window.location.href = validateSwapLangURL(t);
149        var i = new Date;
150        i.setTime(i.getTime() + 31536e6), SetCookie("language", n, i, "/", null, !1)
151    } else {
152        // Remarked by Calvin 21122020
153        // Original var o = window.top.location.href;
154        var o = window.location.href;
155        if(!notFound){
156            o.indexOf("/en/") >= 0 ? alert("English Version Only\n只有英文版") : (o.indexOf("/tc/"), alert("只有中文版\nChinese Version Only"));
157        }else{
158            window.location.href = validateSwapLangURL(t);
159        }
160    }
161}
162
163// Cookies
164function initialCookie() {
165    var e = window.location.toString().split("//")[1].split("/"),
166        t = e[1].split("/"),
167        n = (e[0], t[0]);
168    "" == window.name && (window.name = "isdWin");
169    var i = location.domain ? location.domain : null,
170        o = new Date;
171    o.setTime(o.getTime() + 31536e6), "" == n || "en" != n && "zh-hk" != n && "zh-cn" != n ? (null != GetCookie("language") ? SetCookie("language", GetCookie("language"), o, "/", i) : SetCookie("language", "en", o, "/", i), window.location.href = "/" + GetCookie("language") + "/index.html") : SetCookie("language", n, o, "/", i)
172}
173function GetCookie(e) {
174    if ("font-size" == e) {
175        if (document.cookie.indexOf(e) < 0) return null;
176        var t = document.cookie.indexOf(e) + e.length + 1,
177            n = document.cookie.indexOf(";", t);
178        return -1 == n && (n = document.cookie.length), decodeURI(document.cookie.substring(t, n))
179    }
180    var i = document.cookie.match("(^|;)?" + e + "=([^;]*)(;|$)");
181    return i ? unescape(i[2]) : null
182}
183function SetCookie(e, t, n, i, o, r) {
184    var s = e + "=" + escape(t);
185    s += "; expires=" + n.toGMTString(), i && (s += "; path=" + escape(i)), o && (s += "; domain=" + escape(o)), r && (s += "; secure"), document.cookie = s
186    s += "; sameSite=Lax;";
187    var getCookie = document.cookie;
188    getCookie = s;
189    document.cookie = getCookie;
190}
191if (document.cookie !== null) {
192    document.cookie += "; sameSite=Lax;"
193}
194
195// get current lang
196// console.log(phpLang);
197var phpLang = "";
198if(phpLang != null){
199    langSplit = phpLang.split('-');
200    if(langSplit[2]){
201        var currentLang = langSplit[1]+'-'+langSplit[2];
202    }else{
203        var currentLang = langSplit[1];
204    }
205    // console.log(currentLang);
206}else{
207    var currentLang = getLang();
208    // console.log(currentLang);
209}
210$(document).mouseup(function (e) {
211    var container = $(".modal-content");
212})
213
214// header click icon show dropdown modal
215$(document).on("click", function (e) {
216    var curUrl = window.location.href;
217    // var urlParams = new URLSearchParams(window.location.search);
218    var paramCalendar = urlParams.get('calendar');
219    var paramNotices = urlParams.get('notices');
220    // var paramSearch = urlParams.get('search');
221    var id = e.target.id.split("-");
222    // console.log(e.target.id);
223    if($(e.target).is(".btn-close-black")){
224        $("#li-search").css("background-image", "none");
225        $("#icon-search").css("display", "block");
226        $("#close-search").hide();
227        $("#li-calendar").css("background-image", "none");
228        // if(curUrl.indexOf("?") != -1) {
229        //     curUrl = removeURLParameter(curUrl,"calendar");
230        //     curUrl = removeURLParameter(curUrl,"search");
231        //     window.history.pushState({ path: curUrl }, '', curUrl);
232        // }
233    }
234    if($(e.target).not(".headerModal *")) {
235        // console.log(e.target.id);
236        // if(!$(".headerModal").is(".show")) {
237        //     if(!$(e.target).is(".icon-nav")){
238        //     if(!$(e.target).is(".icon-nav-mobi")){
239
240        //     if(!$(e.target).is(".icon-search-mobi")){
241        //     }
242
243        //     }
244        //     }
245        // }
246        // if($(e.target).is(".icon-search")){
247        //     $("#close-search").show();
248        //     // $("#icon-search").hide();
249        //     $("#close-nav").hide();
250        //     $("#li-nav").css("background-image", "none");
251        //     $("#icon-nav").show();
252        //     $("#header-nav").modal('hide');
253        //     if(paramNotices) {
254        //         curUrl = removeURLParameter(curUrl,"notices");
255        //         window.history.pushState({ path: curUrl }, '', curUrl);
256        //     }
257        //     if(curUrl.includes('?')){
258        //         var curUrl = curUrl+'&search=y';
259        //     }else{
260        //         var curUrl = curUrl+'?search=y';
261        //     }
262        //     if(!paramSearch){
263        //         window.history.pushState({ path: curUrl }, '', curUrl);
264        //     }
265        // }else 
266            if($(e.target).is(".icon-nav")){
267            $("#close-search").hide();
268            $("#li-search").css("background-image", "none");
269            $("#icon-search").show();
270            $("#header-search").modal('hide');
271
272        }else if($(e.target).is(".icon-nav-mobi")){
273            $("#header-search").modal('hide');
274            $(window).resize(function() {
275                if ($(window).width() > 991) {
276                    $("#header-nav").modal('hide');
277                    setTimeout(function() {
278                        $(window).off('resize');
279                    }, 0);
280                }
281            });
282        }else if($(e.target).is(".icon-search-mobi")){
283            $("#icon-search").hide();
284            $("#close-search").show();
285            $("#header-nav").modal('hide');
286
287
288            // if(curUrl.includes('?')){
289            //     var curUrl = curUrl+'&search=y';
290            // }else{
291            //     var curUrl = curUrl+'?search=y';
292            // }
293            // if(!paramSearch){
294            //     window.history.pushState({ path: curUrl }, '', curUrl);
295            // }
296            // if(paramSearch){
297            //     curUrl = removeURLParameter(curUrl,"search");
298            //     window.history.pushState({ path: curUrl }, '', curUrl);
299            // }
300            // setTimeout(()=>{
301            //     $('.header-effect-calendar .day-event').hide();
302            //     $('.header-effect-calendar .calendar>.calendar-top').show();
303            //     $('.header-effect-calendar .calendar>.weekdays').show();
304            //     $('.header-effect-calendar .calendar>.calendar-mobi-2-days').show();
305            // }, 200);
306        }else if($(e.target).is(".header-mobi-notice-title .btn-close-black")){
307            $("#li-search").css("background-image", "none");
308        }else if($(e.target).is(".header-mobi-search-title .btn-close-black")){
309            $("#li-notice").css("background-image", "none");
310        }
311        if($('.language-switcher').hasClass('active')&&($('.language-switcher').hasClass('hover')||$('.language-switcher').hasClass('active'))&&!document.querySelector('.language-switcher').contains(e.target)){
312            hideLangSwitchContent()
313        }
314        if($(".sub-menu").hasClass("active")&&!document.querySelector('.sub-menu.active').contains(e.target)){
315            $(".sub-menu").removeClass("active");
316        }
317    }
318})
319// header icons (calendar/notice/search) display link
320var curUrl = window.location.href;
321var urlParams = new URLSearchParams(window.location.search);
322
323var paramNotices = urlParams.get('notices');
324var paramSearch = urlParams.get('search');
325if(paramSearch=="y"){
326    $("#icon-search").click();
327    $("#close-search").show();
328    $("#icon-search").hide();
329    $("#close-nav").hide();
330    $("#li-nav").css("background-image", "none");
331    $("#icon-nav").show();
332    $("#header-notice").modal('hide');
333    $("#header-nav").modal('hide');
334}
335// function removeURLParameter(url, parameter) {
336//     //prefer to use l.search if you have a location/link object
337//     var urlparts = url.split('?');   
338//     if (urlparts.length >= 2) {
339
340//         var prefix = encodeURIComponent(parameter) + '=';
341//         var pars = urlparts[1].split(/[&;]/g);
342
343//         //reverse iteration as may be destructive
344//         for (var i = pars.length; i-- > 0;) {    
345//             //idiom for string.startsWith
346//             if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
347//                 pars.splice(i, 1);
348//             }
349//         }
350
351//         return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
352//     }
353//     return url;
354// }
355// $("#close-calendar").click(function() {
356//     if(paramCalendar) {
357//         curUrl = removeURLParameter(curUrl,"calendar");
358//         window.history.pushState({ path: curUrl }, '', curUrl);
359//     }
360//     if(paramNotices) {
361//         curUrl = removeURLParameter(curUrl,"notices");
362//         window.history.pushState({ path: curUrl }, '', curUrl);
363//     }
364//     if(paramSearch) {
365//         curUrl = removeURLParameter(curUrl,"search");
366//         window.history.pushState({ path: curUrl }, '', curUrl);
367//     }
368// });
369
370$("#close-search").click(function() {
371
372    if(paramSearch) {
373        // curUrl = removeURLParameter(curUrl,"search");
374        window.history.pushState({ path: curUrl }, '', curUrl);
375    }
376});
377// Detect Pressed Esc Key
378document.onkeydown = function(evt) {
379    evt = evt || window.event;
380    // if (evt.keyCode == 13) {
381    //     // $(".filter-options").css("display", "block");
382        
383    // }
384    if (evt.keyCode == 27) {
385        $('html').removeAttr('style');
386        $("#close-search").hide();
387        $("#li-search").css("background-image", "none");
388        $(".language-switcher-content").removeClass("show");
389        $(".language-switcher>button.langbtn").attr('aria-expanded',false)
390        $(".sub-menu").removeClass("active");
391        let navLink=$('ul.navbar-nav>li>a.nav-link');
392        navLink.each(function() {
393            if($(this).parent().find('.sub-menu').length>0){
394                console.log($(this).parent().find('.sub-menu'))
395                $(this).attr('aria-expanded','false');
396            }
397        });
398
399
400        $('.language-switcher').removeClass('active');
401        $('.language-switcher').removeClass('hover');
402        $(".navbar-nav>li").removeClass('hover')
403
404        // $(".filter-options").css("display", "none");
405        $("#icon-search").show();
406        if(paramSearch) {
407            curUrl = removeURLParameter(curUrl,"search");
408            window.history.pushState({ path: curUrl }, '', curUrl);
409        }
410    }
411};
412
413
414// scroll to show back to top btn
415$(window).scroll(function (event) {
416    var scroll = $(window).scrollTop();
417    if(scroll > 73) {
418        document.querySelector(".btn-top").style.display = "block";
419    }else {
420        document.querySelector(".btn-top").style.display = "none";
421    }
422});
423// tooltip
424if($('[data-toggle="tooltip"]').length>0){
425 $('[data-toggle="tooltip"]').tooltip();
426}
427
428
429$(".copyright-year").html(new Date().getFullYear());
430$('.current-floor-image').click(function(){
431    // console.log($(this).children().attr('src'));
432    $(".popup-image-container").html('<img class="popup-floor-image" src="'+$(this).children().attr('src')+'">');
433});
434// 20220905 click close btn to reset iframe
435$('.btn-close').click(function(){      
436    $('iframe').attr('src', $('iframe').attr('src'));
437});
438
439
440
441
442$(document).ready(function() {
443
444        $('#filter-accordion input[type="checkbox"]').keypress(function (event) {
445            var keycode = (event.keyCode ? event.keyCode : event.which);
446            if (keycode == 13) {
447                $(this).trigger('click');
448                event.stopPropagation();
449            }
450        });
451  
452  $('.mobile-top-block').find('button.btn-header-nav-back').remove();
453
454    var urlParams = new URLSearchParams(window.location.search);
455    // console.log(urlParams);
456
457    // 20221118 show that floor if url contain parameter
458    var paramFloor = urlParams.get('floor');
459    if(paramFloor){
460        handleFloorSelectorClick(paramFloor.toUpperCase()+"-floor");
461    }
462
463    $( ".navbar-nav>li>a" ).on("focus", function(e) {
464        $('.sub-menu').removeClass('active');
465        $('ul.navbar-nav>li>a.nav-link').attr('aria-expanded','false')
466        let navlink=$('ul.navbar-nav>li>a.nav-link');
467        navlink.each((index)=>{
468            if($(navlink[index]).parent().find('.sub-menu').length===0){
469                $(navlink[index]).removeAttr('aria-expanded')
470            }
471        })
472        if($(this).parent().find('.sub-menu').length>0){
473            $(this).parent().find('.sub-menu').addClass('active');
474            $(this).parent().find('>a.nav-link').attr('aria-expanded','true')
475        }
476    });
477    if($('ul.navbar-nav>li:last>.sub-menu').length===0){
478        $( ".navbar-nav>li:last>a" ).on("blur", function(e) {
479            $('.sub-menu').removeClass('active');
480            $('ul.navbar-nav>li>a.nav-link').attr('aria-expanded','false')
481            let navlink=$('ul.navbar-nav>li>a.nav-link');
482            navlink.each((index)=>{
483                if($(navlink[index]).parent().find('.sub-menu').length===0){
484                    $(navlink[index]).removeAttr('aria-expanded')
485                }
486            })
487        })
488    }else{
489        $('ul.navbar-nav>li:last>.sub-menu a:last').on("blur", function(e) {
490            setTimeout(() => {
491                if(!document.querySelector('ul.navbar-nav > li:last-child > .sub-menu').contains(document.activeElement)&&!$('ul.navbar-nav>li:last').is(":focus")){
492                    $('.sub-menu').removeClass('active');
493                    $('ul.navbar-nav>li>a.nav-link').attr('aria-expanded','false')
494                    let navlink=$('ul.navbar-nav>li>a.nav-link');
495                    navlink.each((index)=>{
496                        if($(navlink[index]).parent().find('.sub-menu').length===0){
497                            $(navlink[index]).removeAttr('aria-expanded')
498                        }
499                    })   
500                }
501            }, 0);
502            
503        })
504    }
505    $( ".navbar-nav>li>a:first" ).on("blur", function(e) {
506        setTimeout(() => {
507            if (!$("ul.navbar-nav>li:first>.sub-menu")[0].contains(document.activeElement)) {
508                $('.sub-menu').removeClass('active');
509                $('ul.navbar-nav>li>a.nav-link').attr('aria-expanded','false')
510                let navlink=$('ul.navbar-nav>li>a.nav-link');
511                navlink.each((index)=>{
512                    if($(navlink[index]).parent().find('.sub-menu').length===0){
513                        $(navlink[index]).removeAttr('aria-expanded')
514                    }
515                })   
516            }
517        }, 0);
518        
519    })
520    $(".navbar-nav>li").on("mouseenter",function () {
521        $(this).addClass("hover")
522    }).on("mouseleave",function () {
523        $(this).removeClass("hover")
524    })
525    
526    let menuLinks = document.querySelectorAll('.navbar-nav>li');
527    menuLinks.forEach(function(link,index) {
528        if(link.querySelectorAll('.sub-menu').length>0){
529            link.querySelector('a.nav-link').setAttribute('aria-expanded','false');
530        }
531        link.onmouseenter = function(){
532            if(link.querySelectorAll('.sub-menu').length>0){
533                link.querySelector('a.nav-link').setAttribute('aria-expanded','true')
534            }
535        }
536        link.onmouseleave = function(e){
537            if(link.querySelectorAll('.sub-menu').length>0){
538                link.querySelector('a.nav-link').setAttribute('aria-expanded','false')
539            }
540        }
541    });
542
543    $('.pagination-container').attr('aria-label', currentPageLang=='zh-hk'?'分頁':'Pagination');
544
545    //header active link
546
547    if($('.aboutus-content').length>0||$('.aboutus-nearby').length>0||$('.explorer-section').length>0||$('.trip-details').length>0||location.pathname.includes('/visit/')){
548        $('.navbar-nav>li')[0].classList.add('active');
549    }
550    if($('.main-exhitibions').length>0||$('.exhibition-details').length>0){
551        $('.navbar-nav>li')[1].classList.add('active');
552    }
553    if($('.activities-search').length>0||$('.activities-details-block').length>0){
554        $('.navbar-nav>li')[2].classList.add('active');
555    }
556    if($('.collection-details-info').length>0||$('.collection-details-block').length>0||$('.collection-items').length>0||location.pathname.includes('/collections/')){
557        $('.navbar-nav>li')[3].classList.add('active');
558    }
559    if($('.publication-details-popup').length>0||
560        $('.publications-listing').length>0||
561        $('.pastevents-listing').length>0||
562        $('.pastevent-details-block').length>0||
563        $('.travelling-listing').length>0||
564        $('.e-materials-listing').length>0||
565        $('.e-materials-details-block').length>0||
566        $('.servicekits-listing').length>0||location.pathname.includes('/resources/')
567    )
568    {
569        $('.navbar-nav>li')[4].classList.add('active');
570    }
571    if($('.railway-museum').length>0||$('.sheungyiufolk-museum').length>0){
572        $('.navbar-nav>li')[5].classList.add('active');
573    }
574
575    $('.gallery-btn').on('click',function(){
576        $('html').css('overflow-y', 'hidden');
577    });
578    $('.btn-close').on('click',function(){
579        $('html').css('overflow-y', 'auto');
580    });
581    
582    
583});
584
585// 20230718 add floor current svg class
586function addFloorCurrentSvgClass(){
587$(".main-floor-plan-graphic .floor-svg-container").each(function() {
588    $(this).removeClass("floor-current-svg");
589    // $(this).attr('id', 'floor-current-svg');
590    if($(this).children("svg").is(":visible")){
591        $(this).addClass("floor-current-svg");
592        // $(this).removeAttr('id');
593    }
594});
595}
596
597// 20230720 each click in floor current svg
598function getCenterPointAndScaleSVG(id,translateW,translateH){
599    $(".floor-current-svg #icons > g#"+id).show();
600    var elem = document.getElementById(id);
601    // var bBox = elem.getBBox();
602    var bBox = document.querySelector(".floor-current-svg svg").getBBox();
603    var scaleX = 2;
604    var scaleY = 2;
605    // console.log(elem);
606    // var translateW = parseInt(-bBox.width/3.5);
607    // var translateH = parseInt(-bBox.height/3.5);
608    var transform = "scale("+scaleX+","+scaleY+") translate("+parseInt(translateW)+"px,"+parseInt(translateH)+"px)";
609    // var transform = "scale(1.1,1.1)";
610    // console.log(transform);
611    $(".floor-current-svg #icons > g#"+id).css("transform", transform);
612}
613
614function clickFloorCurrentSvg(){
615    $(".floor-current-svg .floor-svg-click").each(function() {
616        $(this).on( "mouseover", function() {
617            $(this).find("path").not('.svg-gradient').addClass("floor-svg-fill");
618            $(this).find("polygon").addClass("floor-svg-fill");
619            $(this).find("rect").addClass("floor-svg-fill");
620        });
621        $(this).on( "click", function() {
622            $(".floor-current-svg #icons > g").css("transform", "initial");
623            $(".floor-current-svg #icons > g").show();
624            $(".floor-current-svg .floor-svg-click").removeClass("floor-svg-fill").removeClass("floor-svg-clicked");
625            $(this).addClass("floor-svg-fill").addClass("floor-svg-clicked");
626            var svgPopup="",svgTour,svgName,svgDetails,svgDetailsUrl,svgEvent,svgLeft,svgTop;
627            // console.log(floorPlanDetails);
628            $.each(floorPlanDetails, function( key, value ) {
629                // console.log($(this));
630                if($(".floor-svg-clicked").hasClass(key)){
631                    if(currentLang == "en"){
632                        svgName=value.nameEng;
633                        svgDetails=value.detailsEng;
634                        svgDetailsUrl=value.detailsLinkEng;
635                        svgTour=value.tourEng;
636                        svgTourUrl=value.tourlinkEng;
637                    }else if(currentLang == "zh-cn"){
638                        svgName=value.nameChs;
639                        svgDetails=value.detailsChs;
640                        svgDetailsUrl=value.detailsLinkChs;
641                        svgTour=value.tourChs;
642                        svgTourUrl=value.tourlinkChs;
643                    }else if(currentLang == "zh-hk"){
644                        svgName=value.nameCht;
645                        svgDetails=value.detailsCht;
646                        svgDetailsUrl=value.detailsLinkCht;
647                        svgTour=value.tourCht;
648                        svgTourUrl=value.tourlinkCht;
649                    }
650                }
651
652            });
653            // if($window <= 1087){
654                // if($(this).attr("id") == "f1-restaurant"){
655                //     svgLeft="11vw";
656                //     svgTop="4vw";
657                // }
658            // }else{
659                // if($(this).attr("id") == "f1-restaurant"){
660                    // svgLeft="177px";
661                    // svgTop="50px";
662                // }else if($(this).attr("id") == "f1-hall"){
663                    // svgLeft="295px";
664                    // svgLeft="370px";
665                    // svgTop="125px";
666                // }else if($(this).attr("id") == "f1-spot"){
667                    // svgLeft="630px";
668                    // svgTop="250px";
669                // }else if($(this).attr("id") == "f1-theatre"){
670                    // svgLeft="710px";
671                    // svgTop="95px";
672                // }
673            // }
674            $(".floor-svg-popup").remove();
675            svgPopup += `<div class="floor-svg-popup">
676            <div class="floor-svg-popup-name">${svgName}</div>`;
677            if(svgTour){
678                svgPopup += `<div class="floor-svg-popup-details" data-tour="${svgTour}">
679                <a href="#" target="_self" class="floor-video-link" data-bs-toggle="modal" data-bs-target="#floor-plan-image">
680                360° Photo
681                </a></div>`;
682            }
683            svgPopup += `
684                <div class="floor-svg-popup-details"><a href="${svgDetailsUrl}" target="_self">${svgDetails}</a></div>
685            </div>`;
686
687            // $(".floor-current-svg").append(svgPopup);
688            $(".svg-popup").append(svgPopup);
689
690            $(".floor-svg-popup").css("left",svgLeft).css("top",svgTop);
691            // $(".floor-svg-popup").css("transform","translate3d(625px, 249px, 0px)");
692            $(".floor-video-link").click(function() {
693                // console.log($(this).parent().data("tour"));
694                var item;
695                var iframeClass;
696                if($(this).parent().data("video")){
697                    item = $(this).parent().data("video");
698                    iframeClass = "iframe-video";
699                }else if($(this).parent().data("tour")){
700                    item = $(this).parent().data("tour");
701                    iframeClass = "iframe-tour";
702                }
703                // console.log(item);
704                $(".modal-popup .popup-box").html('<iframe class="'+iframeClass+'" src="'+item+'" title="video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>');
705            });
706        });
707    });
708    // svg icon click to enlarge scale
709    $(".floor-svg-icon-click").each(function() {
710        $(this).click(function(){
711            $(".floor-svg-popup").remove();
712            $(".floor-current-svg #icons > g").hide();
713            // console.log($(this).find("img").attr("src"));
714            if($(this).find("img").attr("src").indexOf("icon-new_the_spot.png") >= 0){
715                // getCenterPointAndScaleSVG("f1-icon-artwork-1",-627,-427);
716                // getCenterPointAndScaleSVG("f1-icon-artwork-2",-756,-415);
717                getCenterPointAndScaleSVG("f1-icon-spot-1",-834,-423);
718            }else if($(this).find("img").attr("src").indexOf("icon-new_baby_caring_room.png") >= 0){
719                getCenterPointAndScaleSVG("f1-icon-baby-1",-335,-166);
720            }else if($(this).find("img").attr("src").indexOf("icon-new_the_spot.png") >= 0){
721                getCenterPointAndScaleSVG("f1-icon-spot-1",-335,-166);
722            }else if($(this).find("img").attr("src").indexOf("icon-new_cloak_room.png") >= 0){
723                getCenterPointAndScaleSVG("f1-icon-cloakroom-1",-589,-159);
724            }else if($(this).find("img").attr("src").indexOf("icon-new_the_mart.png") >= 0){
725                getCenterPointAndScaleSVG("f1-icon-mart-1",-503,-159);
726                getCenterPointAndScaleSVG("f1-icon-mart-2",-540,-159);
727            }else if($(this).find("img").attr("src").indexOf("icon-new_ticketing_machines.png") >= 0){
728                getCenterPointAndScaleSVG("f1-icon-ticketing-1",-719,-165);
729            }
730        });
731    });
732}
733
734//const govSearchURL="https://gov-dev.suntek.com.hk/jsresult?";
735function submitSearch(locale, input, event) { 
736	var tmp = document.getElementById(input).value;
737	tmp = $.trim(tmp);
738	var len = tmp.length;
739	var legalChars = /^[\w -]+$/;
740	var illegalChars2 = /[\W_]/;
741	var illegalChars1 = /[\~\`\@\#\$\%\^\&\*\(\)\_\+\=\|\\\}\{\]\[\'\"\;\:\?\>\<\/]/;
742
743	if (len == 0) {
744		if (locale == "zh_TW") alert("您的搜索輸入不正確。");
745		else if (locale == "zh_CN") alert("您的搜索输入不正确。");
746		else alert("The searching input you entered is not valid.");
747		return false;
748	} else if (illegalChars1.test(tmp)) {
749		if (locale == "zh_TW") alert("您的搜索輸入包含了非法字符。");
750		else if (locale == "zh_CN") alert("您的搜索输入包含了非法字符。");
751		else alert("The searching input contains illegal characters.");
752        event?.preventDefault();
753		return false;
754	} else {
755		
756		if (locale == "zh_TW") {
757			window.location.href =  window.location.origin + "/tc/search-result.html?query=" + tmp;
758		} else if (locale == "zh_CN") {
759			window.location.href =  window.location.origin + "/sc/search-result.html?query=" + tmp;
760        } else {
761            window.location.href =  window.location.origin + "/en/search-result.html?query=" + tmp;
762        }
763		document.charset = "utf-8";
764		//document.frmSearch.submit();
765	}
766}
767
768function hideLangSwitchContent(params) {
769    $('.language-switcher').removeClass('active');
770    $('.language-switcher').removeClass('hover');
771    $(".language-switcher>button.langbtn").attr('aria-expanded',false)
772    $('.language-switcher-content').removeClass('show');
773}
774
775$( document ).ready(function() {
776    var lastScrollTop = 0, delta = 15;
777    $(window).scroll(function(event){
778      var st = $(this).scrollTop();
779      
780      if($('body').hasClass('home')&&($('body').hasClass('monochrome')||$('html').hasClass('monochrome'))){
781        delta=60;
782      }
783
784      if(Math.abs(lastScrollTop - st) <= delta)
785          return;
786      
787        if ((st > lastScrollTop) && (lastScrollTop>0)) {
788            $(".page-head__bottom").addClass("header-hidden");
789            $('.inner-page header').css('border-bottom', 'none');
790            //   $('header .navbar>div>ul>li>.sub-menu').hide();
791        } else {
792            $(".page-head__bottom").removeClass("header-hidden");
793            $('.inner-page header').css('border-bottom', '1px solid');
794        }
795      lastScrollTop = st;
796    });
797  // Select all h2 elements
798    
799    if ($('.accordion-content').find('h3').length === 0) {
800  $(".content-accordion h2.accordionHead").replaceWith(function() {
801    return $("<h3>", {
802      class: this.className, // Keep existing classes
803      id: this.id,           // Keep existing ID
804      html: $(this).html()   // Keep the inner HTML content
805    });
806  });      
807    }
808  $(".content-accordion h2.accordionHead").replaceWith(function() {
809    return $("<h4>", {
810      class: this.className, // Keep existing classes
811      id: this.id,           // Keep existing ID
812      html: $(this).html()   // Keep the inner HTML content
813    });
814  });
815  $(".center-content .accordion-content .content-title").replaceWith(function() {
816    return $("<h3>", {
817      class: this.className, // Keep existing classes
818      id: this.id,           // Keep existing ID
819      html: $(this).html()   // Keep the inner HTML content
820    });
821  });  
822  $(".exhibition-details .page-title-block p.section-title").replaceWith(function() {
823    return $("<h2>", {
824      class: this.className, // Keep existing classes
825      html: $(this).html()   // Keep the inner HTML content
826    })
827  });
828  $(".activities-section .page-title-block p.section-title").replaceWith(function() {
829    return $("<h2>", {
830      class: this.className, // Keep existing classes
831      html: $(this).html()   // Keep the inner HTML content
832    })
833  });  
834
835  $(".activities-section .page-title-block p.section-title").replaceWith(function() {
836    return $("<h2>", {
837      class: this.className, // Keep existing classes
838      html: $(this).html()   // Keep the inner HTML content
839    })
840  });  
841
842  $(".collection-details-head .page-title-block p.section-title").replaceWith(function() {
843    return $("<h2>", {
844      class: this.className, // Keep existing classes
845      html: $(this).html()   // Keep the inner HTML content
846    })
847  });   
848  
849  $(".generic-content.sectionTitle .page-title-block p.section-title").replaceWith(function() {
850    return $("<h2>", {
851      class: this.className, // Keep existing classes
852      html: $(this).html()   // Keep the inner HTML content
853    })
854  });  
855  
856  $(".trip-details .page-title-block p.section-title").replaceWith(function() {
857    return $("<h2>", {
858      class: this.className, // Keep existing classes
859      html: $(this).html()   // Keep the inner HTML content
860    })
861  });   
862  $(".collection-detailspage .page-title-block p.section-title").replaceWith(function() {
863    return $("<h2>", {
864      class: this.className, // Keep existing classes
865      html: $(this).html()   // Keep the inner HTML content
866    })
867  });   
868  $(".page-title-block p.section-title").replaceWith(function() {
869    return $("<h2>", {
870      class: this.className, // Keep existing classes
871      html: $(this).html()   // Keep the inner HTML content
872    })
873  });   
874  
875  if($('header button.langbtn').length>0){
876    $('header button.langbtn').attr('title', currentPageLang === 'zh-hk'?'選擇語言':currentPageLang === 'zh-cn'?'选择语言':'Select Language');
877  }
878
879  $('.language-switcher').on( "click", function(e) {
880    e.stopPropagation();
881
882    //for activities filter
883    if(typeof hideAllFilterOptions!=="undefined"){
884        hideAllFilterOptions();
885    }
886
887    //for resource page listing-filter
888    if(typeof yearBtn!=="undefined"&&typeof yearMenu!=="undefined"&&yearMenu?.classList?.contains('show')){
889        toggleDropdown(yearBtn, yearMenu)(e);
890    }
891    if(typeof categoryBtn!=="undefined"&&typeof categoryMenu!=="undefined"&&categoryMenu?.classList?.contains('show')){
892        toggleDropdown(categoryBtn, categoryMenu)(e);
893    }
894
895    //self
896    $(this).toggleClass("active");
897    $('.language-switcher-content').toggleClass('show');
898    if($(this).hasClass('active')){
899        $(this).find('button.langbtn').attr('aria-expanded',true);
900    }else if(!$(this).hasClass('hover')){
901        $(this).find('button.langbtn').attr('aria-expanded',false);
902    }
903  });
904  $('.language-switcher').on("mouseenter",function(){
905    $(this).find('button.langbtn').attr('aria-expanded',true);
906    $(this).addClass('hover');
907  }).on("mouseleave",function(){
908    if($(this).hasClass('active')){
909      $(this).find('button.langbtn').attr('aria-expanded',true);
910    }else{
911      $(this).find('button.langbtn').attr('aria-expanded',false);
912      $(this).removeClass('hover');
913    }
914  })
915  $('.language-switcher-content>a:last').on("keydown",function (e) {
916    if (e.key === 'Tab') {
917        hideLangSwitchContent();
918    }
919  })
920
921    if ($( "body" ).hasClass( "home" )) {
922        $('header').on( "mouseover", function() {
923            //$('header').css('background', 'rgb(255,255,255)');
924            //$('.main-nav a').css('color', '#000');
925            //$('header a').css('color', '#000');
926            //$('header p').css('color', '#000');       
927            //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
928            //$('.langbtn').css('color', '#000');
929            //$('.opening-hour').removeClass('open').addClass('opened-white');
930            //$('.page-head__top').addClass('head-border');
931            // $('.page-head__top').addClass('scrolling-head');
932        } );
933        $('header').on( "mouseout", function() {
934            //$('header').css('background', 'rgb(0,0,0,0.8)');
935                // $('.page-head__top').css('background', 'rgb(0,0,0,.8)');
936                // $('.page-head__bottom').css('background', 'rgb(0,0,0,.8)');        
937            //$('.main-nav a').css('color', '#fff');
938            //$('header a').css('color', '#fff');   
939            //$('header p').css('color', '#fff');   
940            //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%)');
941            //$('.opening-hour').removeClass('opened-white').addClass('open');
942            //$('.langbtn').removeAttr('style');
943            //$('.page-head__top').removeClass('head-border');
944            // $('.page-head__top').removeClass('scrolling-head');
945            // $('header .navbar .sub-menu a').css('color', '#000');
946            // $('header .navbar .sub-menu p').css('color', '#000');
947        } );
948    } else {
949    $('header').on( "mouseover", function() {
950        //$('header').css('background', 'rgb(255,255,255)');
951        // $('.page-head__bottom').removeClass('header-hidden');     
952        //$('.main-nav a').css('color', '#000');
953        //$('header a').css('color', '#000');
954        //$('header p').css('color', '#000');    
955    //   $('.page-head__top').addClass('scrolling-head');
956        //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
957    } );
958    $('header').on( "mouseout", function() {
959        //$('header').css('background', 'rgb(255,255,255)');   
960            // $('.page-head__bottom').addClass('header-hidden');     
961        //$('.main-nav a').css('color', '#000');
962        //$('header a').css('color', '#000');   
963        //$('header p').css('color', '#000');   
964    //   $('.page-head__top').removeClass('scrolling-head');
965        //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
966        // $('header .navbar .sub-menu a').css('color', '#000');
967        // $('header .navbar .sub-menu p').css('color', '#000');
968    } );        
969    }
970    //$('header .navbar .sub-menu a').css('color', '#000');
971    //$('header .navbar .sub-menu p').css('color', '#000');
972    $('header .navbar>div>ul>li').css('cursor','pointer');
973
974    // const isTablet = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))
974/.test(navigator.userAgent.toLowerCase());
975    // Check if the primary input mechanism is touch (mobile/tablet)
976    const isTouchDevice = () => {return window.matchMedia("(any-pointer:coarse)").matches;};
977
978    if(isTouchDevice()){
979        $('.circle').addClass('scale1Important');
980    }
981
982    $('.circle').on("mouseover touchstart",function(event){
983        if(isTouchDevice()){
984            $('.circle').addClass('scale1Important');
985        }else{
986             $('.circle').removeClass('scale1Important');
987        }
988        if(event.type === "mouseover" && window.innerWidth > 768&&!isTouchDevice()){
989            $(this).addClass('active')
990            $('.circle:not(.active)').css('transform', 'scale(0.5)')
991        }
992        if(event.type === "touchstart" && window.innerWidth > 768&&!isTouchDevice()){
993            $(this).addClass('active')
994            $('.circle:not(.active)').css('transform', 'scale(0.5)')
995        }
996    })
997    $('.circle').on("mouseout touchend",function(){
998        $(this).removeClass('active')
999        if(!isTouchDevice()){
1000            $('.circle:not(.active)').css('transform', '')
1001        }
1002    })
1003});
1004
1005
1006
1007
1008$(document).on('scroll', function(){
1009    if ( $(window).scrollTop() > 0) {
1010        if ($( "body" ).hasClass( "home" )) {
1011            //$('header').css('background', 'none');
1012            //$('.page-head__top').css('background', 'rgb(255,255,255)');
1013            //$('.page-head__bottom').css('background', 'rgb(255,255,255)');
1014            //$('.main-nav a').css('color', '#000');
1015            //$('header a').css('color', '#000');
1016            //$('header p').css('color', '#000');
1017            //$('.opening-hour').removeClass('open').addClass('opened-white');
1018            //$('.langbtn').css('color', '#000');
1019            //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1020            //$('.page-head__top').addClass('head-border');
1021            $('.page-head__top').addClass('scrolling-head');
1022            //$('.icon-search').css('filter','revert');
1023            $('header')
1024            .on( "mouseover", function() {
1025                // $('header').css('background', 'rgb(255,255,255)');
1026                $('.page-head__bottom').removeClass('header-hidden');
1027            //$('.page-head__top').css('background', 'rgb(255,255,255)');
1028            //$('.page-head__bottom').css('background', 'rgb(255,255,255)');                
1029                //$('.main-nav a').css('color', '#000');
1030                //$('header a').css('color', '#000'); 
1031                //$('header p').css('color', '#000');      
1032                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)'); 
1033                //$('.opening-hour').removeClass('open').addClass('opened-white');
1034                //$('.langbtn').css('color', '#000');
1035            } );
1036            $('header')
1037            .on( "mouseout", function() {
1038                //$('header').css('background', 'none');
1039                //$('.page-head__top').css('background', 'rgb(255,255,255)'); 
1040                $('.page-head__bottom').addClass('header-hidden');   
1041                //$('.page-head__bottom').css('background', 'none');            
1042                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1043                //$('.opening-hour').removeClass('open').addClass('opened-white');
1044                //$('.main-nav a').css('color', '#000');
1045                //$('header a').css('color', '#000');   
1046                //$('header p').css('color', '#000');   
1047                //$('.langbtn').css('color', '#000');
1048                //$('.page-head__top').addClass('head-border');
1049            } );    
1050        } else {
1051            //$('header').css('background', 'none');
1052            //$('.page-head__top').css('background', 'rgb(255,255,255)');
1053            //$('.page-head__bottom').css('background', 'rgb(255,255,255)');
1054          $('.page-head__top').addClass('scrolling-head');
1055            $('header').on( "mouseover", function() {
1056                //$('header').css('background', 'rgb(255,255,255)');
1057                //$('header').css('border-bottom', '1px solid');
1058                $('.page-head__bottom').removeClass('header-hidden');     
1059                //$('.main-nav a').css('color', '#000');
1060                //$('header a').css('color', '#000');
1061                //$('header p').css('color', '#000');   
1062              
1063                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1064            } );
1065            $('header').on( "mouseout", function() {
1066                //$('header').css('background', 'transparent');   
1067                //$('header').css('border-bottom', 'none');
1068                    $('.page-head__bottom').addClass('header-hidden');     
1069                //$('.main-nav a').css('color', '#000');
1070                //$('header a').css('color', '#000');   
1071                //$('header p').css('color', '#000');   
1072                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1073            } );              
1074        }
1075
1076    } else {
1077        if ($( "body" ).hasClass( "home" )) {
1078            //$('header').css('background', 'rgb(0,0,0,0.8)');
1079            //$('.page-head__top').css('background', 'transparent');
1080            //$('.page-head__bottom').css('background', 'transparent');               
1081            //$('.main-nav a').css('color', '#fff');
1082            //$('header a').css('color', '#fff');
1083            //$('header p').css('color', '#fff');        
1084            //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%)');        
1085            //$('.opening-hour').removeClass('opened-white').addClass('open');
1086            //$('.langbtn').css('color', '#fff');
1087            //$('.page-head__top').removeClass('head-border');
1088            $('.page-head__top').removeClass('scrolling-head');
1089            $('.icon-search').removeAttr('style');
1090            $('header')
1091            .on( "mouseover", function() {
1092              //$('header').css('background', 'rgb(255,255,255)');
1093              //$('.main-nav a').css('color', '#000');
1094              //$('header a').css('color', '#000');
1095              //$('header p').css('color', '#000');
1096              //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1097              //$('.opening-hour').removeClass('opened').addClass('opened-white');
1098              //$('.langbtn').css('color', '#000');
1099              //$('.page-head__top').addClass('head-border');
1100              $('.page-head__top').addClass('scrolling-head');
1101            } );
1102            $('header')
1103            .on( "mouseout", function() {
1104              //$('header').css('background', 'rgb(0,0,0,0.8)');
1105            //$('.page-head__top').css('background', 'transparent'); 
1106            $('.page-head__bottom').removeClass('header-hidden');            
1107            //$('.page-head__bottom').css('background', 'transparent');               
1108              //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%)');
1109              //$('.opening-hour').removeClass('opened-white').addClass('open');
1110              //$('.main-nav a').css('color', '#fff');
1111              //$('header a').css('color', '#fff');
1112              //$('header p').css('color', '#fff');
1113              //$('.langbtn').css('color', '#fff');
1114              //$('.page-head__top').removeClass('head-border');
1115              $('.page-head__top').removeClass('scrolling-head');
1116            } ); 
1117        } else {
1118            //$('header').css('background', 'none');
1119            //$('.page-head__top').css('background', 'rgb(255,255,255)');
1120            //$('.page-head__bottom').css('background', 'rgb(255,255,255)');
1121            $('.page-head__bottom').removeClass('header-hidden');  
1122            //$('header').css('border-bottom', '1px solid');   
1123          $('.page-head__top').removeClass('scrolling-head');
1124            $('header').on( "mouseover", function() {
1125                //$('header').css('background', 'rgb(255,255,255)');
1126                //$('header').css('border-bottom', '1px solid');
1127                // $('.page-head__bottom').removeClass('header-hidden');     
1128                //$('.main-nav a').css('color', '#000');
1129                //$('header a').css('color', '#000');
1130                //$('header p').css('color', '#000');       
1131                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1132            } );
1133            $('header').on( "mouseout", function() {
1134                //$('header').css('background', 'transparent');   
1135                //$('header').css('border-bottom', '1px solid');
1136                // $('header').css('border-bottom', 'none');   
1137                    $('.page-head__bottom').removeClass('header-hidden');    
1138                //$('.main-nav a').css('color', '#000');
1139                //$('header a').css('color', '#000');   
1140                //$('header p').css('color', '#000');   
1141                //$('.header-logo').css('filter', 'invert(0%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(0%) contrast(100%)');
1142            } );               
1143        }
1144    }
1145});
1146$(document).ready(function(){
1147    // $('#dropdown-nav').on('click', function(e) {
1148    //     e.preventDefault();  // Blocks href="#" jump/scroll-to-top
1149    //     e.stopPropagation(); // Optional: Prevents bubbling if nested in dropdowns
1150
1151    //     // Bootstrap will still handle the modal via data attributes—no need to manually trigger
1152    // });
1153
1154    // // Optional: Preserve/restore scroll position explicitly (if the above isn't enough)
1155    // $('#header-nav').on('show.bs.modal', function() {
1156    //     $(this).data('scrollTop', $(window).scrollTop());  // Store current scroll
1157    // });
1158    $('.floor-plan-popup').on('show.bs.modal', function() {
1159        $('html').css('overflow-y','hidden');
1160    });
1161
1162    $('#header-nav').on('hidden.bs.modal', function() {
1163    //     const scrollTop = $(this).data('scrollTop') || 0;
1164    //     $(window).scrollTop(scrollTop);  // Restore scroll on close
1165        $(window).off('resize');
1166    });  
1167    vtmLinkConfig();
1168    // $('.gallery-btn')startsWith('zh')?(currentPageLang==='zh-hk'?'今天閉館':'今天闭馆'):'Closed today';
1169    // $('.listing-page .page-title-block').removeClass('d-none');
1170    // $('.listing-page .page-title-block .page-title').removeClass('sr-only');
1171    $(".gallery-btn .sr-only").text(currentPageLang.startsWith('zh-hk')?'開啟相簿':currentPageLang.startsWith('zh')?"开启相簿":'Open Gallery');
1172    $(".gallery-btn").attr('aria-label',currentPageLang.startsWith('zh-hk')?'開啟相簿':currentPageLang.startsWith('zh')?"开启相簿":'Open Gallery');
1173    $(".btn-close").attr('aria-label', currentPageLang.startsWith('zh-hk')?'關閉':currentPageLang.startsWith('zh')?'关闭':'Close');
1174  	$(".vtm-link").attr("data-bs-target", "#vtm-popup");
1175    
1176    const vtmText = currentPageLang.startsWith('zh')?(currentPageLang==='zh-hk'?'最新入場狀態':'最新入场状态'):'Latest Admission Status';
1177    $(".page-head__right .vtm-link").hover(
1178        function() {
1179            $(this).addClass('dim');
1180            $(this).html('<p>'+vtmText+'</p>');
1181        },
1182        function() {
1183            $(this).removeClass('dim');
1184            $(this).html('<img src="/assets/img/icon/vtm-black.png" alt="'+vtmText+'">');
1185        }
1186    );    
1187 
1188    $(".gallery-btn .sr-only").text(currentPageLang.startsWith('zh')?'開啟相簿':'Open Gallery');
1189    $(".gallery-btn").attr('aria-label',currentPageLang.startsWith('zh')?'開啟相簿':'Open Gallery');
1190    $(".btn-close").attr('aria-label', currentPageLang.startsWith('zh')?'關閉':'Close');
1191  	$(".vtm-link").attr("data-bs-target", "#vtm-popup");
1192    
1193    $('.anchor-btn').click(function(){
1194        const accordBarId = $(this).attr("data-id");
1195        $('#'+accordBarId+' .accordion-button').removeClass('collapsed');
1196        $('#'+accordBarId+' .accordion-button').attr('aria-expanded', 'true');
1197        $('[aria-labelledby="'+accordBarId+'"]').addClass('show');
1198
1199    });
1200
1201    $('.navbar-toggler').click(function(){
1202        $('.navbar-collapse').slideToggle(300);
1203    });
1204    
1205    // smallScreenMenu();
1206    let temp;
1207    // function resizeEnd(){
1208    //     smallScreenMenu();
1209    // }
1210  
1211    // $(window).resize(function(){
1212    //     clearTimeout(temp);
1213    //     temp = setTimeout(resizeEnd, 100);
1214    //     resetMenu();
1215    // });  
1216    // $('#tag-options label').click(function() {
1217    //     $(this).addClass("active");
1218    //   }) 
1219
1220  });
1221  
1222  
1223//   const subMenus = $('.sub-menu');
1224//   const menuLinks = $('.nav-link');
1225  
1226//   function smallScreenMenu(){
1227//     if($(window).innerWidth() <= 992){
1228//         menuLinks.each(function(item){
1229//             $(this).click(function(){
1230//                 $(this).next().slideToggle();
1231//             });
1232//         });
1233//     } else {
1234//         menuLinks.each(function(item){
1235//             $(this).off('click');
1236//         });
1237//     }
1238//   }
1239  
1240//   function resetMenu(){
1241//     if($(window).innerWidth() > 992){
1242//         subMenus.each(function(item){
1243//             $(this).css('display', 'none');
1244//         });
1245//     }
1246//   }
1247
1248  var footerswiper = new Swiper(".footslide", {
1249    slidesPerView: 3,
1250    centeredSlides: false,
1251    slidesPerGroupSkip: 3,
1252    grabCursor: true,
1253    spaceBetween : 0,
1254    keyboard: {
1255      enabled: true,
1256    },
1257    breakpoints: {
1258      769: {
1259        slidesPerView: 8,
1260        slidesPerGroup: 8,
1261      },
1262    },
1263    navigation: {
1264      nextEl: ".foot-button-next",
1265      prevEl: ".foot-button-prev",
1266    },
1267  });
1268  
1269$(".image-video-link").click(function() {
1270    // console.log($(this).parent().data("video"));
1271    $(".modal-popup .popup-box").html('<iframe class="image-video" src="'+$(this).parent().data("video")+'" title="video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>');
1272    $("#btn-close-slider-video").on("click", function() {
1273        // Code to execute when the element is clicked
1274        $(".modal-popup .popup-box").html('');
1275        $("#btn-close-slider-video").off("click");
1276    });
1277});
1278
1279$(".popup-content-link").click(function() {
1280    // console.log($(this).parent().data("video"));
1281    $(".modal-popup .popup-box").html('<iframe class="image-video" src="'+$(this).parent().data("video")+'" title="video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>');
1282});
1283
1284// VTM Section
1285function vtmLinkConfig() {
1286  let currentLang = getLang();
1287  if(currentLang == "en"){
1288  $(".vtm-lightbox").attr('data-video', '/vtm.html');
1289}else if(currentLang == "zh-hk"){
1290  $(".vtm-lightbox").attr('data-video', '/vtm.html?lang=tc');
1291}else if(currentLang == "zh-cn"){
1292  $(".vtm-lightbox").attr('data-video', '/vtm.html?lang=sc');
1293} else {
1294  $(".vtm-lightbox").attr('data-video', '/vtm.html?lang=tc');
1295}
1296
1297
1298
1299$(".vtm-link").click(function() {
1300    let currentLang = getLang();
1301    let closeAriaLabel= currentLang == "zh-hk" ? '關閉' : currentLang == "zh-cn" ? '关闭' : 'Close'
1302
1303    // console.log($(this).parent().data("video"));
1304    $("#vtm-popup.modal-popup .popup-box").html('<button type="button" id="btn-close-slider-video" class="btn-close" data-bs-dismiss="modal" aria-label="'+closeAriaLabel+'"></button><iframe class="image-video vtm-popup" src="'+$(this).parent().data("video")+'" title="video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>');
1305    $("#btn-close-slider-video").on("click", function() {
1306        // Code to execute when the element is clicked
1307        $(".modal-popup .popup-box").html('');
1308        $("#btn-close-slider-video").off("click");
1309    });
1310});
1311}
1312
1313
1314// Function to set active class based on current page
1315function setActiveNavLink() {
1316    // Get the current page's filename (e.g., 'publicationsouvenir_details.html')
1317    const currentPage = window.location.pathname.split('/').pop() || 'index.html';
1318    
1319    // Select all nav links (desktop and mobile)
1320    const navLinks = document.querySelectorAll('.nav-link, .dropdown-item');
1321    
1322    // Remove active class from all links
1323    navLinks.forEach(link => link.classList.remove('active'));
1324    
1325    // Add active class to the matching link
1326    navLinks.forEach(link => {
1327        const href = link.getAttribute('href');
1328        if (href && (href === currentPage || href.endsWith('/' + currentPage))) {
1329            link.classList.add('active');
1330        }
1331    });
1332}
1333
1334// Run on page load
1335document.addEventListener('DOMContentLoaded', setActiveNavLink);
1336
1337// Opening Hour
1338// ------------------------------------------------------------
1339        // 1. Language detection
1340        // ------------------------------------------------------------
1341        const currentPageLang = document.querySelector('html').getAttribute('lang') || 'en';
1342
1343        // ------------------------------------------------------------
1344        // 2. Current HKT date / time
1345        // ------------------------------------------------------------
1346        function getCurrentHKT(){
1347            const now = new Date();
1348            const utc = now.getTime() + now.getTimezoneOffset()*60000;
1349            const hkt = new Date(utc + 8*60*60000);
1350            return {
1351                date: hkt.toISOString().split('T')[0],
1352                dayOfWeek: hkt.getDay(),
1353                hours: hkt.getHours(),
1354                minutes: hkt.getMinutes()
1355            };
1356        }
1357
1358        // ------------------------------------------------------------
1359        // 3. Parse “10:10 AM” → minutes since midnight
1360        // ------------------------------------------------------------
1361        function parseTime(str){
1362            if(!str||str.trim()==='Closed') return null;
1363            try{
1364                const [t,p]=str.trim().split(' ');
1365                const [h,m]=t.split(':').map(Number);
1366                let hh=h;
1367                if(p==='PM'&&h!==12) hh+=12;
1368                if(p==='AM'&&h===12) hh=0;
1369                return hh*60+(m||0);
1370            }catch(e){console.warn('Bad time:',str);return null;}
1371        }
1372
1373        // ------------------------------------------------------------
1374        // 4. Format a single time
1375        // ------------------------------------------------------------
1376        function formatTime(str,loc){
1377            if(str==='Closed') return loc.startsWith('zh')?(currentPageLang==='zh-hk'?'ä
1377»Šå¤©é–‰é¤¨':'今天闭馆'):'Closed today';
1378            try{
1379                const [t,p]=str.split(' ');
1380                const [h,m]=t.split(':').map(Number);
1381                if(loc.startsWith('zh')){
1382                    const pMap={AM:'上午',PM:'下午'};
1383                    const pStr=pMap[p];
1384                  	const hourText=(loc==='zh-hk')?'時':'时';
1385                    return m===0? `${pStr} ${h} ${hourText}` : `${pStr} ${h} ${hourText} ${m} 分`;
1386                }
1387                const min=m===0?'':`:${m.toString().padStart(2,'0')}`;
1388                return `${h}${min}${p==='AM'?'am':'pm'}`;
1389            }catch(e){return loc.startsWith('zh')?(currentPageLang==='zh-hk'?'今天閉館':'今天闭馆'):'Closed today';}
1390        }
1391
1392        // ------------------------------------------------------------
1393        // 5. Format whole range
1394        // ------------------------------------------------------------
1395        function formatHours(range,loc){
1396            if(range==='Closed') return loc.startsWith('zh')?(currentPageLang==='zh-hk'?'今天閉館':'今天闭馆'):'Closed today';
1397            try{
1398                const [o,c]=range.split('-').map(s=>s.trim());
1399                return `${formatTime(o,loc)}${currentPageLang.startsWith('zh') ? '至' : ' - '}${formatTime(c,loc)}${currentPageLang.startsWith('zh')?(currentPageLang==='zh-hk'?'開館':'开馆'):''}`;
1400            }catch(e){return loc.startsWith('zh')?(currentPageLang==='zh-hk'?'今天閉館':'今天闭馆'):'Closed today';}
1401        }
1402
1403        // ------------------------------------------------------------
1404        // 6. Is the venue open right now?
1405        // ------------------------------------------------------------
1406        function isBusinessOpen(range,curH,curM){
1407            if(range==='Closed') return false;
1408            try{
1409                const [o,c]=range.split('-').map(s=>s.trim());
1410                const open=parseTime(o), close=parseTime(c);
1411                if(open===null||close===null) return false;
1412                const now=curH*60+curM;
1413                return now>=open && now<=close;
1414            }catch(e){return false;}
1415        }
1416
1417        // ------------------------------------------------------------
1418        // 7. Fetch the JSON
1419        // ------------------------------------------------------------
1420        fetch('/include/json/opening_hours.json')
1421            .then(r=>{if(!r.ok) throw new Error('Network'); return r.json();})
1422            .then(data=>{
1423
1424                const groups          = data.groups          || [];
1425                const specialDates    = data.specialDates    || {};
1426                const publicHolidays  = data.publicHolidays  || [];
1427
1428                const {date:todayDate, dayOfWeek, hours:curH, minutes:curM}=getCurrentHKT();
1429
1430                // ------------------------------------------------------------
1431                // 8. Determine which group applies today (priority order)
1432                // ------------------------------------------------------------
1433                let todayGroup = null;
1434                let todayHours = null;
1435                let todayDisplayTime = null;     // formatted: "上午10:10至下午8:00"
1436
1437                // 1. Urgent closure – highest priority
1438                const urgentGroup = groups.find(g=>g.applicableDays.type==='special_close_dates');
1439
1440                if(urgentGroup && urgentGroup.applicableDays.dates){
1441
1442                    const idx = urgentGroup.applicableDays.dates.indexOf(todayDate);
1443
1444                    if(idx !== -1){
1445
1446                        todayGroup = urgentGroup;
1447
1448                        todayHours = urgentGroup.applicableDays.times?.[idx] || 'Closed';
1449
1450                        todayDisplayTime = formatHours(todayHours, currentPageLang);
1451
1452                    }
1453
1454                }
1455                // 2. Special dates
1456                if(!todayGroup && specialDates[todayDate]){
1457                    todayGroup = groups.find(g=>g.applicableDays.type==='special_dates');
1458                    todayHours = specialDates[todayDate];
1459                }
1460                // 3. Public holiday
1461                if(!todayGroup && publicHolidays.includes(todayDate)){
1462                    todayGroup = groups.find(g=>g.applicableDays.type==='weekend_and_holidays');
1463                    todayHours = todayGroup ? todayGroup.time : 'Closed';
1464                }
1465                // 4. Weekday / weekend / Tuesday
1466                if(!todayGroup) {
1467                    for(const g of groups){
1468                        const days = g.applicableDays.days;
1469                        const type = g.applicableDays.type;
1470                        if(type==='weekdays' && days.includes(dayOfWeek)){
1471                            todayGroup=g; todayHours=g.time; break;
1472                        }
1473                        if(type==='weekend_and_holidays' && days.includes(dayOfWeek)){
1474                            todayGroup=g; todayHours=g.time; break;
1475                        }
1476                        if(type==='specific_day' && g.applicableDays.day===dayOfWeek){
1477                            todayGroup=g; todayHours=g.time; break;
1478                        }
1479                    }
1480                }
1481
1482                // fallback
1483                if(!todayGroup) todayGroup = groups[0] || {};
1484                if(!todayHours) todayHours = 'Closed';
1485                // if(!todayTimeLabel) todayTimeLabel = todayGroup.timeLabel?.[currentPageLang] || todayGroup.timeLabel?.en || formatHours(todayHours, currentPageLang);
1486                if(!todayDisplayTime) todayDisplayTime = formatHours(todayHours, currentPageLang);
1487
1488                // ------------------------------------------------------------
1489                // 9. #opening-hours – use timeLabel from the active group
1490                // ------------------------------------------------------------
1491                const ohDiv=document.getElementById('opening-hours');
1492                if(ohDiv){
1493                    // const timeLabel = todayGroup.timeLabel?.[currentPageLang] || todayGroup.timeLabel?.en || formatHours(todayHours, currentPageLang);
1494                    // const open = isBusinessOpen(todayHours, curH, curM);
1495                    // const prefix = currentPageLang.startsWith('zh') ? '今天' : 'Open today ';
1496                    // ohDiv.textContent = open ? `${prefix}${todayDisplayTime}` : todayDisplayTime;
1497                    // ohDiv.className = open ? 'open' : 'closed';
1498const open = todayHours !== 'Closed';
1499                    const prefix = currentPageLang.startsWith('zh') ? '今天' : 'Open today: ';
1500                    ohDiv.textContent = open ? `${prefix}${todayDisplayTime}` : todayDisplayTime;
1501                    ohDiv.className = open ? 'open' : 'closed';                    
1502                }
1503
1504                // ------------------------------------------------------------
1505                // 10. Page title
1506                // ------------------------------------------------------------
1507                const title=document.getElementById('open-today-title');
1508                if(title) title.textContent=currentPageLang.startsWith('zh')?'今天開放時間':'Open today';
1509
1510                // ------------------------------------------------------------
1511                // 11. Full schedule (optional)
1512                // ------------------------------------------------------------
1513                const list=document.getElementById('grouped-hours-list');
1514                if(!list) return;
1515
1516                let html='';
1517
1518                groups.forEach(g=>{
1519
1520                    const label = g.dateLabel[currentPageLang] || g.dateLabel.en || '—';
1521                    const baseTimeLabel = g.timeLabel?.[currentPageLang] || g.timeLabel?.en || '—';
1522
1523                    // ----- skip empty urgent closure -----
1524                    // if(g.applicableDays.type==='special_close_dates' && (!g.applicableDays.dates || g.applicableDays.dates.length===0)){
1525                    //     return;
1526                    // }
1527
1528                    // ----- URGENT CLOSURE -----
1529                    if(g.applicableDays.type==='special_close_dates' && g.applicableDays.dates && g.applicableDays.dates.length>0){
1530                        return;
1531                    }
1532
1533                    // ----- SPECIAL DATES -----
1534                    if(g.applicableDays.type==='special_dates'){
1535                        const uniq=[...new Set(Object.values(specialDates))];
1536                        uniq.forEach(t=>{
1537                            const isToday = specialDates[todayDate]===t;
1538                            html+=`<li>
1539                                      <div class="label">${label}</div>
1540                                      <div class="time">
1541                                      ${baseTimeLabel}
1542                                          ${isToday ? `<span class="today-tag">${currentPageLang.startsWith('zh') ? '今天' : 'Today'}</span>` : ''}
1543                                      </div>
1544                                    </li>`;
1545                        });
1546                        return;
1547                    }
1548
1549                    // ----- ALL OTHER GROUPS -----
1550                    const isToday = g===todayGroup;
1551                    html+=`<li>
1552                              <div class="label">${label}</div>
1553                              <div class="time">
1554                                  ${baseTimeLabel}
1555                                  ${isToday ? `<span class="today-tag">${currentPageLang.startsWith('zh') ? '今天' : 'Today'}</span>` : ''}
1556                              </div>
1557                            </li>`;
1558                });
1559
1560                list.innerHTML=html;
1561            })
1562            .catch(err=>{
1563                console.error('Opening-hours JSON error:',err);
1564                const oh=document.getElementById('opening-hours');
1565                if(oh){
1566                    oh.textContent=currentPageLang.startsWith('zh')?'無法載入開放時間':'Error loading opening hours.';
1567                    oh.className='closed';
1568                }
1569            });
1570	
1571//start of floor plan js
1572let floorInt=0;
1573let zoomScale=1;//zoomScale increase when zoomin, zoomScale decrease when zoomout
1574let svgPanZoom;
1575let floorPlanData;
1576let isFirstZoomIn=true;
1577let floorObj={
1578    en:[{label:"2/F",value:2},{label:"1/F",value:1},{label:"G/F",value:0}],
1579    tc:[{label:"2樓",value:2},{label:"1樓",value:1},{label:"地下",value:0}],
1580    sc:[{label:"2楼",value:2},{label:"1楼",value:1},{label:"地下",value:0}]
1581}
1582$(".floor-plan-link").on("click",function(){
1583    let currentLang = getLang();
1584    floorInt=0;
1585    zoomScale=1
1586    //clear
1587    $(".floor-plan-popup .HM-logo").html('');
1588    $(".floor-plan-popup .top-transprant-background").html('');
1589    $(".floor-plan-popup .Back").html('');
1590    $(".floor-plan-popup .map").html('');
1591    $(".floor-plan-popup .left-transprant-background").html('');
1592    $(".floor-plan-popup .left-floor-button-group").html('');
1593    $(".floor-plan-popup .pan-button-group").html('');
1594    $(".floor-plan-popup .zoom-button-group").html('');
1595    $(".floor-plan-popup .floor-plan-menu").html('');
1596    $(".floor-plan-popup .floor-plan-detail-sidebar").remove()
1597    //add
1598    setTimeout(() => {
1599        let HMLogo=$(".modal-popup .popup-box .floor-plan-container .floor-plan .HM-logo");
1600        HMLogo.html(`<picture>
1601            <source srcset="/assets/img/svg/mobile/HM-logo.svg" media="(max-width: 768px)" />
1602            <img src="/assets/img/svg/desktop/HM-logo.svg" alt="HM-logo"/>
1603            </picture>`);
1604        // $.get("/assets/img/svg/Back.svg",(data)=>{
1605        //     let Back=$(".modal-popup .popup-box .floor-plan-container .floor-plan .Back");
1606        //     Back.html(new XMLSerializer().serializeToString(data));
1607        //    
1608        // });
1609        let backToSiteButtonText="Back to site";
1610        if(currentLang==="zh-hk"){
1611            backToSiteButtonText="返回網站";
1612        }else if(currentLang==="zh-cn"){
1613            backToSiteButtonText="返回网站";
1614        }
1615        $(".modal-popup .popup-box .floor-plan-container .floor-plan .Back").html(`<button onclick='closeFloorPlanPopup()'>${backToSiteButtonText}</button>`);
1616        // $.get("/assets/img/svg/English.svg",(data)=>{
1617        //     let English=$(".modal-popup .popup-box .floor-plan-container .floor-plan .English");
1618        //     English.html(new XMLSerializer().serializeToString(data));
1619        // });
1620        floorInt=0;
1621        loadFloorButton();
1622        loadZoomInOutButton();
1623        loadPanButton();
1624        oldWindowWidth=window.innerWidth
1625        floorInt=0;
1626        loadSvgFloorPlan(0)
1627    }, 500);
1628})
1629const closeFloorPlanPopup=()=>{
1630    $('.floor-plan-popup').modal('toggle');
1631    $('html').css('overflow-y', 'auto');
1632}
1633const loadFloorButton=()=>{
1634    //left floor button
1635    let currentLang = getLang();
1636    const leftFloorButtonGroup=$(".modal-popup .popup-box .floor-plan-container .floor-plan .left-floor-button-group");
1637    leftFloorButtonGroup.html('');
1638    let langKey=currentLang;
1639    if(langKey==="zh-cn"){
1640        langKey="sc";
1641    }
1642    if(langKey==="zh-hk"){
1643        langKey="tc";
1644    }
1645    floorObj[langKey].map(({value,label},index)=>{
1646        let buttonHtml='';      
1647        buttonHtml=`<button style='top: calc(50% - ${(value-1)*70}px);'`
1648        if(window.innerWidth<=768||window.innerHeight<528){
1649             buttonHtml=`<button style='top: calc(50% - ${(value-1)*52}px);'`
1650        }
1651        buttonHtml+=` onclick="closeViewDetailSidebar();zoomScale=1;floorInt=${value};loadZoomInOutButton();loadSvgFloorPlan(${value});leftFloorButtonActive(${value},this);">${label}</button>`;
1652        leftFloorButtonGroup.append(buttonHtml);
1653    })
1654    leftFloorButtonActive(floorInt,$(".modal-popup .popup-box .floor-plan-container .floor-plan .left-floor-button-group>button")[2-floorInt]);
1655}
1656const zoomInFunc=()=>{
1657    let isMobile=(window.innerWidth<=768||window.innerHeight<528)?true:false;
1658    if(isMobile){
1659        if(zoomScale>=0.55) return;
1660    }else{
1661        if(zoomScale>1.25) return;
1662    }
1663    if(svgPanZoom){
1664        if(isMobile){
1665            zoomScale+=0.45;
1666        }else{
1667            zoomScale+=0.25;
1668        }
1669        zoomScale=parseInt(zoomScale*100)/100;
1670        if(isMobile){
1671            if(zoomScale===1||zoomScale===0.55){
1672                // $('g#icon-zoom-in>line').attr('stroke','#d4d4d4');
1673                $('.zoom-in').css('color','#d4d4d4');
1674                $('.zoom-in').attr('disabled',true);
1675            }
1676        }else{
1677            if(zoomScale===1.5){
1678                // $('g#icon-zoom-in>line').attr('stroke','#d4d4d4');
1679                $('.zoom-in').css('color','#d4d4d4');
1680                $('.zoom-in').attr('disabled',true);
1681            }
1682        }
1683        // $('g#icon-zoom-out>line').attr('stroke','#000000');
1684        $('.zoom-out').css('color','#000000');
1685        $('.zoom-out').attr('disabled',false);
1686        // const {x,y}=svgPanZoom.getViewBox();
1687        let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
1688        const width=floorPlanMap.width();
1689        const height=floorPlanMap.height();
1690        let times=(100-Math.sqrt(zoomScale*100)+Math.sqrt(1*100))/100;
1691        if(isMobile){
1692            if(zoomScale===0.1){
1693            }
1694            if(zoomScale===0.55){
1695                // svgPanZoom.setViewBox(svgPanZoom.getViewBox().x*1.45,svgPanZoom.getViewBox().y
1695*1.45,1725,1150,100)
1696                svgPanZoom.setViewBox(svgPanZoom.getViewBox().x*1.625,svgPanZoom.getViewBox().y*1.625,1200,800,100)
1697            if(width>=668){
1698                //default +230px limit width
1699                // svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+230
1700                svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+520
1701            }else{
1702                //default +230px limit width plus
1703                //every 50px width decrease, every 70px limit width increase
1704                // svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+230+(668-width)*70/50
1705                svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+520+(668-width)*50/50
1706            }
1707            if((height*2)>=900){
1708                //default +150px limit height
1709                // svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+150
1710                svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+350
1711            }
1712}
1713        }else{
1714            svgPanZoom.zoomIn();
1715            if(zoomScale===1){
1716                svgPanZoom.limits.x2=(1200+(1200-width))+(isFirstZoomIn===true?0:-20)
1717                svgPanZoom.limits.y2=(800+(800-height))
1718            }
1719            if(zoomScale===1.25){
1720                if(width>=1000){
1721                    svgPanZoom.limits.x2=(1200+(1200-width))*times-40
1722                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1723                }else if(width>=800){
1724                    svgPanZoom.limits.x2=(1200+(1200-width))*times-55
1725                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1726                }else{
1727                    svgPanZoom.limits.x2=(1200+(1200-width))*times-130
1728                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1729                }
1730                if(height<600){
1731                    svgPanZoom.limits.y2=(800+(800-height))*times-30
1732                }
1733            }
1734            if(zoomScale===1.5){
1735                if(width>=1000){
1736                    svgPanZoom.limits.x2=(1200+(1200-width))*times-80
1737                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1738                }else if(width>=800){
1739                    svgPanZoom.limits.x2=(1200+(1200-width))*times-95
1740                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1741                }else{
1742                    svgPanZoom.limits.x2=(1200+(1200-width))*times-190
1743                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1744                }
1745                if(height<600){
1746                    svgPanZoom.limits.y2=(800+(800-height))*times-70
1747                }
1748            }
1749        }
1750        //prevent over limit x when zoom in
1751        let svgPanZoomViewBox=svgPanZoom.getViewBox();
1752        if((svgPanZoomViewBox.x+svgPanZoomViewBox.width)>svgPanZoom.limits.x2){
1753            setTimeout(()=>svgPanZoom.panRight((svgPanZoomViewBox.x+svgPanZoomViewBox.width)-svgPanZoom.limits.x2, 100),300)
1754        }
1755        if(svgPanZoomViewBox.x===0){
1756            setTimeout(()=>{svgPanZoom.panLeft(0,100),300});
1757        }
1758    }
1759}
1760const loadZoomInOutButton=()=>{
1761    isFirstZoomIn=true;
1762    // let svgPath="/assets/img/svg/desktop/button-zoom-in-or-out.svg";
1763    if (window.innerWidth<=768||window.innerHeight<528){
1764        // svgPath="/assets/img/svg/mobile/buttons-zoom-in-or-out(mobile).svg";
1765        // svgPath="/assets/img/svg/desktop/button-zoom-in-or-out.svg";
1766    }
1767
1768    const zoomInAriaLabel=currentPageLang === 'zh-hk' ? '放大' : currentPageLang === 'zh-cn' ? '放大' : 'Zoom In';
1769    const zoomOutAriaLabel=currentPageLang === 'zh-hk' ? '縮小' : currentPageLang === 'zh-cn' ? '缩小' : 'Zoom Out';
1770    let zoomButton="<button class='zoom-in' aria-label='"+zoomInAriaLabel+"'>+</button><button class='zoom-out' aria-label='"+zoomOutAriaLabel+"'>-</button>"
1771    let zoomButtonGroup=$(".modal-popup .popup-box .floor-plan-container .floor-plan .zoom-button-group");
1772    // zoomButtonGroup.html(new XMLSerializer().serializeToString(data));
1773    zoomButtonGroup.html(zoomButton)
1774    if(zoomScale===1){
1775        // $('g#icon-zoom-out>line').attr('stroke','#d4d4d4');
1776        $('.zoom-out').css('color','#d4d4d4');
1777        $('.zoom-out').attr('disabled',true);
1778        // $('g#icon-zoom-in>line').attr('stroke','#000000');
1779        $('.zoom-in').css('color','#000000');
1780        $('.zoom-in').attr('disabled',false);
1781    }else{
1782        // $('g#icon-zoom-in>line').attr('stroke','#d4d4d4');
1783        $('.zoom-in').css('color','#d4d4d4');
1784        $('.zoom-in').attr('disabled',true);
1785        // $('g#icon-zoom-out>line').attr('stroke','#000000');
1786        $('.zoom-out').css('color','#000000');
1787        $('.zoom-out').attr('disabled',false);
1788    }
1789    // x2:isMobile?(1200+(1200-width)):(1200+(1200-width)),//isMobile?(675+(675-width)):(1200+(1200-width)),
1790    // y2:isMobile?(800+(800-height)):(800+(800-height))//isMobile?(450+(450-height)):(800+(800-height))
1791    //let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
1792    // const width=floorPlanMap.width();
1793    // const height=floorPlanMap.height();
1794    //svgPanZoom.setViewBox(x, y, width, height, animationTime)
1795    
1796    $(".zoom-in").off("click");
1797    $(".zoom-in").on("click",zoomInFunc);
1798    $(".zoom-out").off("click");
1799    $(".zoom-out").on("click",zoomOutFunc);
1800}
1801const zoomOutFunc=(isUnSelectItem=false)=>{
1802    isFirstZoomIn=false;
1803    let isMobile=(window.innerWidth<=768||window.innerHeight<528)?true:false;
1804    if(isMobile){
1805        if(zoomScale===0.1) return;
1806    }else{
1807        if(zoomScale===1) return;
1808    }
1809    if(svgPanZoom){
1810        if(isMobile){
1811            zoomScale-=0.45;    
1812        }else{
1813            zoomScale-=0.25;
1814        }
1815        zoomScale=parseInt(zoomScale*100)/100;
1816        
1817        if(isMobile){
1818            if(zoomScale===0.1){
1819                // $('g#icon-zoom-out>line').attr('stroke','#d4d4d4');
1820                $('.zoom-out').css('color','#d4d4d4');
1821                $('.zoom-out').attr('disabled',true);
1822            }
1823        }else{
1824            if(zoomScale===1){
1825                // $('g#icon-zoom-out>line').attr('stroke','#d4d4d4');
1826                $('.zoom-out').css('color','#d4d4d4');
1827                $('.zoom-out').attr('disabled',true);
1828            }
1829        }
1830        // $('g#icon-zoom-in>line').attr('stroke','#000000');
1831        $('.zoom-in').css('color','#000000');
1832        $('.zoom-in').attr('disabled',false);
1833        let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
1834        const width=floorPlanMap.width();
1835        const height=floorPlanMap.height();
1836        let times=(100-Math.sqrt(zoomScale*100)+Math.sqrt(1*100))/100;
1837        if(isMobile){
1838            if(zoomScale===0.1){
1839                //this row could make setViewBox height set correctly
1840                if(width>436){
1841                    svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+1300
1842                    svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+1950
1843                }else{
1844                    svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+500
1845                }
1846                
1847                let x=svgPanZoom.getViewBox().x;
1848                // svgPanZoom.setViewBox(svgPanZoom.getViewBox().x/1.45,svgPanZoom.getViewBox().y/1.45,1950,1300,100)
1849                svgPanZoom.setViewBox(x,svgPanZoom.getViewBox().y/1.625,1950,1300,100)
1850                // if(width>436) svgPanZoom.setViewBox(svgPanZoom.getViewBox().x,svgPanZoom.getViewBox().y,1950,1300,100)
1851                if(isUnSelectItem){
1852                    setTimeout(()=>svgPanZoom.setCenter(x*1.65+width,svgPanZoom.getViewBox().y,100),0)
1853                }
1854                
1855            }
1856            if(zoomScale===0.55){
1857            }
1858            if(width>=668){
1859                //default +60px limit width
1860                svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+60
1861            }else{
1862                //default +60px limit width plus
1863                //every 50px width decrease, every 80px limit width increase
1864                svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+60+((668-width)*80/50)
1865            }
1866
1867            if((height*2)>=900){
1868                //default +70px limit height
1869                svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+70
1870            }
1871        }else{
1872            svgPanZoom.zoomOut();
1873            if(zoomScale===1){
1874                svgPanZoom.limits.x2=(1200+(1200-width))+(isFirstZoomIn===true?0:-20)
1875                svgPanZoom.limits.y2=(800+(800-height))
1876            }
1877            if(zoomScale===1.25){
1878                if(width>=1000){
1879                    svgPanZoom.limits.x2=(1200+(1200-width))*times-40
1880                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1881                }else if(width>=800){
1882                    svgPanZoom.limits.x2=(1200+(1200-width))*times-55
1883                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1884                }else{
1885                    svgPanZoom.limits.x2=(1200+(1200-width))*times-130
1886                    svgPanZoom.limits.y2=(800+(800-height))*times-20
1887                }
1888                if(height<600){
1889                    svgPanZoom.limits.y2=(800+(800-height))*times-30
1890                }
1891            }
1892            if(zoomScale===1.5){
1893                if(width>=1000){
1894                    svgPanZoom.limits.x2=(1200+(1200-width))*times-80
1895                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1896                }else if(width>=800){
1897                    svgPanZoom.limits.x2=(1200+(1200-width))*times-95
1898                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1899                }else{
1900                    svgPanZoom.limits.x2=(1200+(1200-width))*times-190
1901                    svgPanZoom.limits.y2=(800+(800-height))*times-15
1902                }
1903                if(height<600){
1904                    svgPanZoom.limits.y2=(800+(800-height))*times-70
1905                }
1906            }
1907        }
1908
1909        //prevent over limit y when zoom in
1910        setTimeout(()=>{
1911            let svgPanZoomViewBox=svgPanZoom.getViewBox();
1912            if(svgPanZoomViewBox.y===0){
1913                svgPanZoom.panUp(0,100);
1914            }
1915        },700)
1916    }
1917}
1918const loadPanButton=()=>{
1919    let panButtonGroup=$(".modal-popup .popup-box .floor-plan-container .floor-plan .pan-button-group");
1920    const panUpAriaLabel=currentPageLang === 'zh-hk' ? '向上' : currentPageLang === 'zh-cn' ? '向上' : 'Up';
1921    const panDownAriaLabel=currentPageLang === 'zh-hk' ? '向下' : currentPageLang === 'zh-cn' ? '向下' : 'Down';
1922    const panLeftAriaLabel=currentPageLang === 'zh-hk' ? '向左' : currentPageLang === 'zh-cn' ? '向左' : 'Left';
1923    const panRightAriaLabel=currentPageLang === 'zh-hk' ? '向右' : currentPageLang === 'zh-cn' ? '向右' : 'Right';
1924    const panCenterAriaLabel=currentPageLang === 'zh-hk' ? '置中' : currentPageLang === 'zh-cn' ? '置中' : 'Center';
1925    let panButton=`<div><button class='pan-up' onclick='svgPan("up")' aria-label="${panUpAriaLabel}">&#8593;</button><button class='pan-center' onclick='svgPan("center")' aria-label="${panCenterAriaLabel}">&#8857;</button><button class='pan-left' onclick='svgPan("left")' aria-label="${panLeftAriaLabel}">&#8592;</button><button class='pan-down' onclick='svgPan("down")' aria-label="${panDownAriaLabel}">&#8595;</button><button class='pan-right' onclick='svgPan("right")' aria-label="${panRightAriaLabel}">&#8594;</button></div>`;
1926    panButtonGroup.html(panButton)
1927}
1928const svgPan=(direction)=>{
1929    if(direction==="left") return svgPanZoom.panLeft(30, 300)
1930    if(direction==="right") return svgPanZoom.panRight(30, 300)
1931    if(direction==="up") return svgPanZoom.panUp(30, 300)
1932    if(direction==="down") return svgPanZoom.panDown(30, 300)
1933    let isMobile=(window.innerWidth<=768||window.innerHeight<528)?true:false;
1934    let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
1935    const width=floorPlanMap.width();
1936    const height=floorPlanMap.height();
1937    if(isMobile){
1938        if(zoomScale===1){
1939            zoomOutFunc()
1940        }
1941        if(zoomScale===0.55){
1942            zoomOutFunc()
1943        }
1944        zoomScale=0.1;
1945    }
1946    setTimeout(() => {
1947        if(direction==="center"){
1948            if(isMobile){
1949                let extraRightPan=40
1950                if(width>=430&&width<=460){
1951                    extraRightPan=0
1952                }else if(width>=460&&width<=480){
1953                    extraRightPan=-40
1954                }else if(width>=480&&width<=509){
1955                    extraRightPan=-80
1956                }else if(width>=509&&width<=529){
1957                    extraRightPan=-120
1958                }else if(width>=529&&width<=558){
1959                    extraRightPan=-160
1960                }else if(width>=558&&width<=588){
1961                    extraRightPan=-200
1962                }else if(width>=588&&width<=617){
1963                    extraRightPan=-240
1964                }else if(width>=617&&width<=647){
1965                    extraRightPan=-280
1966                }else if(width>=647&&width<=768){
1967                    extraRightPan=-320
1968                }
1969                return svgPanZoom.setCenter(svgPanZoom.getViewBox().width/2+width/2+extraRightPan,svgPanZoom.getViewBox().height/2+height/2,100);
1970            }else{
1971                return svgPanZoom.setCenter((1200+(1200-width))/2, (800+(800-height))/2, 0)
1972            }
1973        }
1974    }, (isMobile?300:0));
1975}
1976const leftFloorButtonActive=(floorInt,leftFloorButton)=>{
1977    $(".modal-popup .popup-box .floor-plan-container .floor-plan .left-floor-button-group>button").css("background","white");
1978    $(".modal-popup .popup-box .floor-plan-container .floor-plan .left-floor-button-group>button").css("color","black");
1979    $(".modal-popup .popup-box .floor-plan-container .floor-plan .left-floor-button-group>button").removeAttr("aria-current");
1980    $(leftFloorButton).attr("aria-current",true);
1981    leftFloorButton.style.background="#EA7119";
1982}
1983const floorplanItemTooltipTitleCountText=(text)=>{
1984 return `<div class='count-text' style='opacity:0;color:white;display:inline-block;font-size:1rem;font-family: "NotoSans-Regular";white-space: pre-line;line-height:16px;'>${text}</div>`;
1985}
1986const loadSvgFloorPlan=(floorInt)=>{
1987    let langKey="en";
1988    let currentLang = getLang();
1989    if(currentLang==="zh-hk"){
1990        langKey="tc";
1991    }else if(currentLang==="zh-cn"){
1992        langKey="sc";
1993    }
1994    let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
1995    floorPlanMap.css("opacity",0);
1996    let floorPlanAssetName="desktop/floorplan-gf-desktop";
1997    if(floorInt===0&&(langKey==="tc"||langKey==="sc")){
1998            floorPlanAssetName+="-"+langKey;
1999    }
2000    let floorStr='G/F';
2001    if(floorInt===1){
2002        floorPlanAssetName="desktop/floorplan-1f-new";
2003        floorStr='1/F'
2004    }else if(floorInt===2){
2005        floorPlanAssetName="desktop/floorplan-2f-new";
2006        floorStr='2/F'
2007    }
2008    if(window.innerWidth<=768||window.innerHeight<528){
2009        // floorPlanAssetName="mobile/floorplan-gf-mobile";
2010        floorPlanAssetName="desktop/floorplan-gf-desktop";
2011        if(floorInt===0&&(langKey==="tc"||langKey==="sc")){
2012            floorPlanAssetName+="-"+langKey;
2013        }
2014        if(floorInt===1){
2015            // floorPlanAssetName="mobile/floorplan-1f-mobile";
2016            floorPlanAssetName="desktop/floorplan-1f-new";
2017        }else if(floorInt===2){
2018            // floorPlanAssetName="mobile/floorplan-2f-mobile";
2019            floorPlanAssetName="desktop/floorplan-2f-new";
2020        }
2021    }
2022    let floorPlanAssetPath=`/assets/img/svg/${floorPlanAssetName}.svg`;
2023    floorPlanMap.load(floorPlanAssetPath,()=>{
2024        $.get('/include/json/floorPlan.json?'+new Date().getTime(),(data)=>{
2025            floorPlanData=data;
2026            const floorPlanDescription=data.floorPlanList.filter(item=>item.floor===floorStr);
2027            const categoryList=data.categoryList
2028            let currentLang = getLang();
2029            let langKey="en";
2030            if(currentLang==="zh-hk"){
2031                langKey="tc";
2032            }else if(currentLang==="zh-cn"){
2033                langKey="sc";
2034            }
2035            //build tooltip
2036            $("svg>g[id^=facility-],svg>g[id^=gallery-],svg>g[id^=display-],svg>g[id$=-entrance]").each(function(index){
2037                let text="";
2038                let buttonText="";
2039                const floorPlanDataItem=floorPlanDescription.find((row)=>{return row.id===$(this).attr('id')});
2040                if(floorPlanDataItem){
2041                    if(floorPlanDataItem['show']===false){
2042                        $(this).hide();
2043                        return true;
2044                    }
2045                    text=floorPlanDataItem?.name?.[langKey]||'';
2046                    buttonText=floorPlanDataItem?.details?.[langKey]||'';
2047                    if(currentLang==="zh-hk"){
2048                        text=floorPlanDataItem?.name?.[langKey]||'';
2049                        buttonText=floorPlanDataItem?.details?.[langKey]||'';
2050                    }else if(currentLang==="zh-cn"){
2051                        text=floorPlanDataItem?.name?.[langKey]||'';
2052                        buttonText=floorPlanDataItem?.details?.[langKey]||'';
2053                    }
2054                }else{
2055                    return true;
2056                }
2057                let buttonHeight=buttonText.length>0?40:0;
2058                let buttonWidth=0;
2059                $(".map").append(floorplanItemTooltipTitleCountText(text));
2060                let textWidth = $('.count-text').width();
2061                let textHeight = $('.count-text').height();
2062                $('.count-text').remove();
2063
2064                if(buttonText.length>0){
2065                    $(".map").append(`<div class='count-text' style='opacity:0;color:white;display:inline-block;font-size:12px;font-family: "NotoSans-Regular";white-space: pre-line;line-height:12px;'>${buttonText}</div>`);
2066                    buttonWidth =$('.count-text').width();
2067                    $('.count-text').remove();
2068                }
2069                
2070                const {width: gWidth,height: gHeight}=this.getBoundingClientRect();
2071                //add a g tag first, then add rect,text,circle,poly inside it
2072                var svgns = "http://www.w3.org/2000/svg";
2073                var gEle = document.createElementNS(svgns, 'g');
2074                gEle.setAttribute('id',$(this).attr('id')+'-popover')
2075                gEle.setAttribute("transform",$(this).attr('transform'));
2076                gEle.setAttribute("style","display:none;");
2077                const translate=$(this).attr('transform').replace("translate(","").replace(")","").split(" ");
2078                let yTranslate=parseFloat(translate[1])
2079                if(yTranslate<100){
2080                    gEle.setAttribute("transform","translate("+translate[0]+","+(yTranslate+140)+")");
2081                }
2082                this.appendChild(gEle);
2083                //rectMaxWidth for View Details button width large than name text width
2084                let rectMaxWidth=textWidth+32;
2085                if(rectMaxWidth<(buttonWidth+32)){
2086                    rectMaxWidth=buttonWidth+32;
2087                }
2088                let rect = document.createElementNS(svgns, 'rect');
2089                rect.setAttribute('x', -(rectMaxWidth)/2+gWidth/2);
2090                rect.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2-30);
2091                if(yTranslate<100&&buttonText.length===0){
2092                    rect.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2-70);
2093                }
2094                
2095                rect.setAttribute('width', rectMaxWidth);
2096                rect.setAttribute('height', textHeight+32+buttonHeight);
2097                rect.setAttribute('style', 'fill:rgba(0,0,0,0.7);z-index:9;');
2098                rect.setAttribute('class', 'rect');
2099                gEle.appendChild(rect);
2100                //text
2101                const textSplit=text.replaceAll("<br />","*@|*").replaceAll("\n","*@|*").split("*@|*");
2102                let isAutoSplitText=false;
2103
2104                let maxWidth=0;
2105                for(let index=0; index<textSplit.length; index++){
2106                    let splitedText = textSplit[index];
2107                    $(".map").append(floorplanItemTooltipTitleCountText(splitedText));
2108                    let subTextWidth = $('.count-text').width()+32;
2109                    $('.count-text').remove();
2110                    if(subTextWidth>300){
2111                        isAutoSplitText=true;
2112                        let splitedTextArray=langKey==="en"?splitedText.split(" "):splitedText.split("");
2113                        let subTextSplit=[];
2114                        let leftPointer = 0, rightPointer = splitedTextArray.length - 1;
2115                        while (leftPointer <= rightPointer) {
2116                            let subText = langKey==="en"?splitedTextArray.slice(leftPointer, rightPointer + 1).join(' '):splitedTextArray.slice(leftPointer, rightPointer + 1).join('');
2117                            $(".map").append(floorplanItemTooltipTitleCountText(subText));
2118                            let subTextWidth = $('.count-text').width();
2119                            $('.count-text').remove();
2120                            if (subTextWidth >= 300) {
2121                                rightPointer--;
2122                            } else {
2123                                maxWidth=subTextWidth>maxWidth?subTextWidth:maxWidth;
2124                                subTextSplit.push(subText);
2125                                leftPointer = rightPointer + 1;
2126                                rightPointer=splitedTextArray.length - 1;
2127                            }
2128                        }
2129                        textSplit.splice(index,1,...subTextSplit);
2130                    }
2131                }
2132                if(isAutoSplitText){
2133                    textWidth=maxWidth;
2134                    textHeight=16*textSplit.length;
2135                    rectMaxWidth=textWidth+32;
2136                    rect.setAttribute('x', -(rectMaxWidth)/2+gWidth/2);
2137                    rect.setAttribute('width', rectMaxWidth);
2138                    rect.setAttribute('y', -(16*textSplit.length+32+buttonHeight)+gHeight/2-30);
2139                    rect.setAttribute('height', textHeight+32+buttonHeight);
2140                }
2141                
2142                textSplit.forEach((splitedText,index)=>{
2143                    $(".map").append(floorplanItemTooltipTitleCountText(splitedText));
2144                    let subTextWidth= $('.count-text').width();
2145                    $('.count-text').remove();
2146                    let textEle= document.createElementNS(svgns, 'text');
2147                    textEle.setAttribute('x',-(rectMaxWidth)/2+gWidth/2+16+((textWidth>buttonWidth?textWidth:buttonWidth)-subTextWidth)/2+(rectMaxWidth-32-(textWidth>buttonWidth?textWidth:buttonWidth)));
2148                    textEle.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2+index*19);
2149                    if(yTranslate<100&&buttonText.length===0){
2150                        textEle.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2+index*19-40);
2151                    }
2152                    textEle.setAttribute('style', 'fill:#fff;font-size:1rem;font-family:"NotoSans-Regular";user-select: none;white-space: pre-line;line-height:16px;');
2153                    textEle.textContent = splitedText;
2154                    gEle.appendChild(textEle);
2155                })
2156                //close button
2157                const closeButton=document.createElementNS(svgns,'g');
2158                closeButton.setAttribute('class','btn-close-popover');
2159                closeButton.setAttribute('x',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-20);
2160                closeButton.setAttribute('y',-(textHeight+32+buttonHeight)+gHeight/2-30);
2161                closeButton.setAttribute('width',20);
2162                closeButton.setAttribute('height',20);
2163                closeButton.setAttribute('style','cursor:pointer');
2164                closeButton.setAttribute('onclick','closeViewDetailSidebar();inactiveFloorPlanItem();');
2165                closeButton.setAttribute('ontouchstart','let isMobile=(window.innerWidth<=768||window.innerHeight<=528)?true:false;inactiveFloorPlanItem();if(isMobile){if(zoomScale===1){zoomOutFunc(true);}setTimeout(()=>{if(zoomScale===0.55){zoomOutFunc();}},100);setTimeout(()=>{svgPan("center");},300)}')
2166                closeButton.setAttribute('onkeydown','if(event.key==="Enter"){document.querySelector(".'+$(this).attr('id')+'").focus();closeViewDetailSidebar();inactiveFloorPlanItem();}')
2167                closeButton.setAttribute('tabindex',0)
2168                closeButton.setAttribute('focusable',"true")
2169                //add rect to help onclick larger box
2170                let rect1=document.createElementNS(svgns,'rect');
2171                rect1.setAttribute('x',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-20);
2172                rect1.setAttribute('y',-(textHeight+32+buttonHeight)+gHeight/2-30);
2173                rect1.setAttribute('width',20);
2174                rect1.setAttribute('height',20);
2175                rect1.setAttribute('style','fill:transparent;');
2176                closeButton.appendChild(rect1);
2177                //add two line to make cross icon
2178                let line1=document.createElementNS(svgns,'line');
2179                line1.setAttribute('x1',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-14);
2180                line1.setAttribute('y1',-(textHeight+32+buttonHeight)+gHeight/2-24);
2181                line1.setAttribute('x2',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-6);
2182                line1.setAttribute('y2',-(textHeight+32+buttonHeight)+gHeight/2-16);
2183                line1.setAttribute('stroke','#b5b5b5');
2184                line1.setAttribute('stroke-width',"1");
2185                closeButton.appendChild(line1);
2186                let line2=document.createElementNS(svgns,'line');
2187                line2.setAttribute('x1',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-6);
2188                line2.setAttribute('y1',-(textHeight+32+buttonHeight)+gHeight/2-24);
2189                line2.setAttribute('x2',-(rectMaxWidth)/2+gWidth/2+rectMaxWidth-14);
2190                line2.setAttribute('y2',-(textHeight+32+buttonHeight)+gHeight/2-16);
2191                line2.setAttribute('stroke','#b5b5b5');
2192                line2.setAttribute('stroke-width',"1");
2193                closeButton.appendChild(line2);
2194                gEle.appendChild(closeButton);
2195                //triangle
2196                let polygonEle=document.createElementNS(svgns,'polygon');
2197                polygonEle.setAttribute('points',`${gWidth/2-10},${gHeight/2-30.15} ${gWidth/2+10},${gHeight/2-30.15} ${gWidth/2},${gHeight/2-20.15}`)
2198                // rectMaxWidth
2199                if(yTranslate<100){
2200                    polygonEle.setAttribute('points',`${gWidth/2-10},${-gHeight/2-15} ${gWidth/2+10},${-gHeight/2-15} ${gWidth/2},${-gHeight/2-25}`)
2201                }
2202                polygonEle.setAttribute('style', 'fill:rgba(0,0,0,0.7);');
2203                gEle.appendChild(polygonEle);
2204                //button on tooltip (View Details)
2205                if(buttonText.length>0){
2206                    let viewDetailEventString='if(document.querySelector("#'+$(this).attr('id')+'")?.classList.contains("active")===false){simClickEvent("#'+$(this).attr('id')+'")};viewDetailsSidebar("'+$(this).attr('id')+'")'
2207                    //make g tag
2208                    let gEle2=document.createElementNS(svgns,'g');
2209                    gEle2.setAttribute('id',$(this).attr('id')+'-view-details');
2210                    gEle2.setAttribute('x', -(rectMaxWidth)/2+gWidth/2+(rectMaxWidth)/2-buttonWidth/2-8+(rectMaxWidth-32-(textWidth>buttonWidth?textWidth:buttonWidth))/2);
2211                    gEle2.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2+(textSplit.length-1)*17.6+18);
2212                    gEle2.setAttribute('width', buttonWidth+16);
2213                    gEle2.setAttribute('height', buttonHeight-16);
2214                    gEle2.setAttribute('style', 'cursor:pointer');
2215                    gEle2.setAttribute('onclick',viewDetailEventString)
2216                    gEle2.setAttribute('ontouchstart',viewDetailEventString)
2217                    gEle2.setAttribute('onkeydown','if(event.key==="Enter"){'+viewDetailEventString+'}')
2218                    gEle2.setAttribute('tabindex',0);
2219                    gEle2.setAttribute("focusable", "true");
2220                    gEle.appendChild(gEle2);
2221                    let viewDetailsEle = document.createElementNS(svgns, 'rect');
2222                    viewDetailsEle.setAttribute('x', -(rectMaxWidth)/2+gWidth/2+(rectMaxWidth)/2-buttonWidth/2-8+(rectMaxWidth-32-(textWidth>buttonWidth?textWidth:buttonWidth))/2);
2223                    viewDetailsEle.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2+(textSplit.length-1)*17.6+18);
2224                    viewDetailsEle.setAttribute('width', buttonWidth+16);
2225                    viewDetailsEle.setAttribute('height', buttonHeight-16);
2226                    viewDetailsEle.setAttribute('style', 'fill:white;z-index:9;');
2227                    viewDetailsEle.setAttribute('rx', 14);
2228                    viewDetailsEle.setAttribute('class', 'rect');
2229                    gEle2.appendChild(viewDetailsEle);
2230                    let viewDetailsTextEle = document.createElementNS(svgns, 'text');
2231                    viewDetailsTextEle.setAttribute('x', gWidth/2-buttonWidth/2+buttonWidth/2+(rectMaxWidth-32-(textWidth>buttonWidth?textWidth:buttonWidth))/2);
2232                    viewDetailsTextEle.setAttribute('y', -(textHeight+32+buttonHeight)+gHeight/2+(textSplit.length-1)*17.6+32);
2233                    viewDetailsTextEle.setAttribute('dominant-baseline', 'middle');
2234                    viewDetailsTextEle.setAttribute('text-anchor', 'middle');
2235                    viewDetailsTextEle.setAttribute('style', 'fill:black;font-size:12px;font-family:"NotoSans-Regular";user-select: none;white-space: pre-line;line-height:12px');
2236                    viewDetailsTextEle.textContent = buttonText;
2237                    gEle2.appendChild(viewDetailsTextEle);
2238                }
2239                
2240                $(".map>svg").append(gEle);
2241            })
2242            loadSvgPanZoom(floorInt);
2243            setTimeout(() => {
2244                floorPlanMap.css("opacity",1)
2245            }, 600);
2246            $("svg>g[id^=facility-],svg>g[id^=gallery-],svg>g[id^=display-],svg>g[id$=-entrance]").off("mouseenter mouseleave click");
2247            $("svg>g[id^=facility-],svg>g[id^=gallery-],svg>g[id^=display-],svg>g[id$=-entrance]").on( "mouseenter", function (event){
2248                let isMobile=(window.innerWidth<=768||window.innerHeight<528)?true:false;
2249                if(isMobile){return;}
2250                $(this).css('position','relative');
2251                if(!$(this).hasClass("active")){
2252                    let findEle='path:first';
2253                    if($(this).attr("id").includes("entrance")){
2254                        findEle='path';
2255                    }
2256                    $(this).find(findEle).attr("old-fill",$(this).find(findEle).attr("fill"));
2257                    $(this).find(findEle).attr("fill","#dedede");
2258                    $("#"+$(this).attr('id')+'-popover').show();
2259                    $("#"+$(this).attr('id')+'-popover').off("mouseleave")
2260                    $("#"+$(this).attr('id')+'-popover').on("mouseleave",function(){
2261                        if(!$(this).hasClass("active")){
2262                            $(this).hide();
2263                            $(this).removeClass("active");
2264                            $("#"+$(this).attr('id').replace("-popover","")).find(findEle).attr("fill",$("#"+$(this).attr('id').replace("-popover","")).find(findEle).attr("old-fill"));
2265                            $("#"+$(this).attr('id').replace("-popover","")).find(findEle).attr("old-fill","");
2266                            $(this).off("mouseleave");
2267                        }
2268                    })
2269                }
2270            }).on( "mouseleave", function (event){
2271                //if statement is checking mouseover form g tag move to its popup 
2272                if($("#"+$(this).attr('id')+'-popover:hover').length===0){
2273                    if(!$(this).hasClass("active")){
2274                        let findEle='path:first';
2275                        if($(this).attr("id").includes("entrance")){
2276                            findEle='path';
2277                        }
2278                        $(this).find(findEle).attr("fill",$(this).find(findEle).attr("old-fill"));
2279                        $(this).find(findEle).attr("old-fill","");
2280                        $("#"+$(this).attr('id')+'-popover').hide();
2281                        $("#"+$(this).attr('id')+'-popover').off("mouseleave");
2282                    }
2283                }
2284            })
2285//fp-icon-lift,fp-icon-lift-2,fp-icon-locker,fp-first-aid-babycare,fp-icon-AED,fp-icon-URBTIX
2286            //click
2287            let clickEleSelector=`svg>g[id^=facility-]:not([id$=-popover]),svg>g[id^=gallery-]:not([id$=-popover]),svg>g[id^=display-]:not([id$=-popover]),svg>g[id$=-entrance]:not([id$=-popover]),
2288                svg>g[id^=fp-icon-]:not([id$=-popover]),svg>g[id=fp-first-aid-babycare]:not([id$=-popover])`;
2289            $(clickEleSelector).css('cursor','pointer')
2290            $(clickEleSelector).on("click touchstart",function(event){
2291                let activeId=[]
2292                document.querySelectorAll("svg>g.active").forEach(function(ele){
2293                    activeId.push(ele.id)
2294                })
2295                if($("svg>g.active").length>0){
2296                    inactiveFloorPlanItem()
2297                }
2298                let floorStr='G/F';
2299                if(floorInt===1){
2300                    floorPlanAssetName="desktop/floorplan-1f-new";
2301                    floorStr='1/F'
2302                }else if(floorInt===2){
2303                    floorPlanAssetName="desktop/floorplan-2f-new";
2304                    floorStr='2/F'
2305                }
2306                let floorPlanItemCategory=(floorPlanData.floorPlanList.filter(item=>item.floor===floorStr).find(row=>row.id===$(this).attr("id"))?.category||"Facilities")?.replaceAll(" ","-")
2307                if(!activeId.includes($(this).attr("id"))){
2308                    if(["fp-icon-toilet","fp-icon-toilet-2","fp-icon-toilet-accessibility"].includes($(this).attr("id"))){
2309                        if(!document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory+".active")){
2310                            toggleFloorPlanMenuCategory(document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory))
2311                        }
2312                        if(document.querySelector('.floor-plan-menu-item-list-content.fp-icon-toilet-accessibility')){
2313                            activeFloorPlanItem(this.id,document.querySelector('.floor-plan-menu-item-list-content.fp-icon-toilet-accessibility'));
2314                        }else{
2315                            activeFloorPlanItem(this.id,document.querySelector('.floor-plan-menu-item-list-content.fp-icon-toilet'));
2316                        }
2317                        return;
2318                    }
2319                    if(["fp-icon-lift","fp-icon-lift-2"].includes($(this).attr("id"))){
2320                        if(!document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory+".active")){
2321                            toggleFloorPlanMenuCategory(document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory))
2322                        }
2323                        activeFloorPlanItem(this.id,document.querySelector('.floor-plan-menu-item-list-content.fp-icon-lift'));
2324                        return;
2325                    }
2326                    if(!document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory+".active")){
2327                        toggleFloorPlanMenuCategory(document.querySelector(".floor-plan-menu-category-name."+floorPlanItemCategory))
2328                    }
2329                    activeFloorPlanItem(this.id,document.querySelector('.floor-plan-menu-item-list-content.'+$(this).attr("id")));
2330                    // zoomToSelectSvgItem(this);
2331                }
2332            });
2333            //menu
2334            loadFloorPlanMenu(floorInt,floorPlanDescription,categoryList);
2335            //switch mobile view or desktop view
2336            window.removeEventListener('resize', debounceLoadSvgPanZoom);
2337            window.addEventListener('resize', debounceLoadSvgPanZoom);
2338
2339            // $('#fp-icon-toilet,#fp-icon-toilet-2,#fp-icon-toilet-accessibility').css('cursor','pointer')
2340            // $('#fp-icon-toilet,#fp-icon-toilet-2,#fp-icon-toilet-accessibility').on("click",function(){
2341                
2342            // });
2343        })
2344    });
2345}
2346function simClickEvent(selectorString){
2347    const event = new MouseEvent('click', {
2348        view: window,
2349        bubbles: true,   // Event will bubble up the DOM tree
2350        cancelable: true // Event can be cancelled
2351    });
2352    document.querySelector(selectorString).dispatchEvent(event);
2353}
2354function zoomToSelectSvgItem(that){
2355    let isMobile=(window.innerWidth<=768||window.innerHeight<528)?true:false;
2356    if(isMobile){
2357        // let gEleWidthHeight=this.getBBox()
2358        // let gEleTransform=this.getAttribute('transform').replace('translate(','').replace(')','').split(" ")
2359        // let gEleX=parseFloat(gEleTransform[0])
2360        // let gEleY=parseFloat(gEleTransform[1])
2361        // let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
2362        // let width=floorPlanMap.width();
2363        // let height=floorPlanMap.height();
2364        // svgPanZoom.setCenter((1200+(1200-width))/2+gEleX-650+gEleWidthHeight.width/2,(800+(800-height))/2+gEleY-450+gEleWidthHeight.height/2, 0)
2365        if(zoomScale===0.1){
2366            zoomInFunc()
2367        }
2368        // if(zoomScale===0.55){
2369        //     zoomInFunc()
2370        // }
2371        
2372        let gEleWidthHeight=that.getBBox()
2373        let gEleTransform=that.getAttribute('transform').replace('translate(','').replace(')','').split(" ")
2374        let gEleX=parseFloat(gEleTransform[0])
2375        let gEleY=parseFloat(gEleTransform[1])
2376        let floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
2377        let width=floorPlanMap.width();
2378        let height=floorPlanMap.height();
2379        let widthPan=410+(width>400?-50:0)
2380        // svgPanZoom.setCenter((1200+(1200-width))/2+gEleX-570+gEleWidthHeight.width/2,(800+(800-height))/2+gEleY-450+gEleWidthHeight.height/2, 500)
2381        svgPanZoom.setCenter(gEleX+gEleWidthHeight.width/2+widthPan,gEleY+gEleWidthHeight.height/2+height/2-50, 100)
2382    }else{
2383        if(that){
2384            let itemY=that.transform.baseVal[0].matrix.f;
2385            if(itemY<200){
2386                let svgPanZoomViewBox=svgPanZoom.getViewBox();
2387                svgPanZoom.setViewBox(svgPanZoomViewBox.x, 0, svgPanZoomViewBox.width, svgPanZoomViewBox.height, 300)
2388            }
2389        }
2390    }
2391}
2392function viewDetailsSidebar(text){
2393    let currentLang = getLang();
2394    let detailSidebar='';
2395    detailSidebar+="<div class='floor-plan-detail-sidebar'>";
2396    detailSidebar+="<div class='sidebar-close-button' onclick='closeViewDetailSidebar()' onkeydown='if(event.key===\"Enter\")closeViewDetailSidebar()' ontouchstart='closeViewDetailSidebar()' role='button' tabindex='0'>";
2397    detailSidebar+="<span>";
2398    let closeButtonText="Close";
2399    if(currentLang==="zh-cn"){
2400        closeButtonText="关闭";
2401    }else if(currentLang==="zh-hk"){
2402        closeButtonText="關閉";
2403    }
2404    detailSidebar+=closeButtonText;
2405    detailSidebar+="</span>";
2406    detailSidebar+=`<svg xmlns="http://www.w3.org/2000/svg" width="11.314" height="11.314" viewBox="0 0 11.314 11.314">
2407    <g id="Group_673" data-name="Group 673" transform="translate(-541.559 -1099.282) rotate(45)">
2408        <line id="Line_978" data-name="Line 978" x2="15" transform="translate(1160.75 394.37)" fill="none" stroke="#000" stroke-width="1"/>
2409        <line id="Line_979" data-name="Line 979" x2="15" transform="translate(1168.25 386.87) rotate(90)" fill="none" stroke="#000" stroke-width="1"/>
2410    </g>
2411    </svg>
2412    `;
2413    detailSidebar+="</div>";
2414    
2415    let floorStr='G/F';
2416    if(floorInt===1){
2417        floorStr='1/F'
2418    }else if(floorInt===2){
2419        floorStr='2/F'
2420    }
2421    let floorPlanDataItem=floorPlanData.floorPlanList.find((row)=>{return row.id===text&&row.floor===floorStr});
2422    if(floorPlanDataItem){
2423        detailSidebar+="<div class='sidebar-content'>";
2424        let langKey="en";
2425        if(currentLang==="zh-hk"){
2426            langKey="tc";
2427        }else if(currentLang==="zh-cn"){
2428            langKey="sc";
2429        }
2430        if(floorPlanDataItem.sidebar.imagePath){
2431            detailSidebar+="<img class='sidebar-image' src='"+floorPlanDataItem.sidebar.imagePath+"' alt='"+floorPlanDataItem.name?.[langKey]+"'>"
2432        }
2433        detailSidebar+="<div class='sidebar-content-2'>";
2434        if(floorPlanDataItem.sidebar.artwork.key?.[langKey]){
2435            detailSidebar+="<div class='sidebar-content-key sidebar-content-artwork'>";
2436            detailSidebar+=floorPlanDataItem.sidebar.artwork.key?.[langKey]
2437            detailSidebar+="</div>";
2438            detailSidebar+="<div class='sidebar-content-value sidebar-content-artwork'>";
2439            detailSidebar+=floorPlanDataItem.sidebar.artwork.value?.[langKey]
2440            detailSidebar+="</div>";
2441        }
2442        
2443        if(floorPlanDataItem.sidebar.description.key?.[langKey]){
2444            detailSidebar+="<div class='sidebar-content-key sidebar-content-description'>";
2445            detailSidebar+=floorPlanDataItem.sidebar.description.key?.[langKey]
2446            detailSidebar+="</div>";
2447            detailSidebar+="<div class='sidebar-content-value sidebar-content-description'>";
2448            detailSidebar+=floorPlanDataItem.sidebar.description.value?.[langKey]
2449            detailSidebar+="</div>";
2450        }
2451        
2452        if(floorPlanDataItem.sidebar.link.key?.[langKey]){
2453            detailSidebar+="<div class='sidebar-content-key'>";
2454            detailSidebar+=floorPlanDataItem.sidebar.link.key?.[langKey]
2455            detailSidebar+="</div>";
2456            detailSidebar+="<div class='sidebar-content-value sidebar-content-link'>";
2457            // detailSidebar+="<a href='"+floorPlanDataItem.sidebar.link.href?.[langKey]+"' title='"+floorPlanDataItem.sidebar.link.value?.[langKey]+"' target='_blank'>";
2458            detailSidebar+=floorPlanDataItem.sidebar.link.value?.[langKey]
2459            // detailSidebar+="</a>";
2460            detailSidebar+="</div>";
2461        }
2462        
2463        detailSidebar+="</div>";
2464        detailSidebar+="</div>";
2465    }
2466    detailSidebar+="</div>";
2467    if($(".floor-plan-detail-sidebar").length>0){
2468        $(".floor-plan-detail-sidebar").remove();
2469    }
2470    $(".floor-plan-container").append(detailSidebar);
2471    setTimeout(function(){
2472        $(".floor-plan-detail-sidebar").css("transform","translateX(0%)")
2473    },0)
2474    $(".floor-plan-menu-category-name").attr("tabindex","-1");
2475    $(".floor-plan-menu-item-list-content").attr("tabindex","-1");
2476    $('.floor-plan-menu').attr("aria-hidden","true");
2477    if(window.innerHeight<528){
2478        $('.sidebar-close-button').focus();
2479        document.querySelector('.floor-plan-container').style.overflowY="hidden";
2480    }
2481}
2482function closeViewDetailSidebar(){
2483    $(".floor-plan-detail-sidebar").css("transform","translateX(100%)")
2484    setTimeout(() => {
2485        $(".floor-plan-detail-sidebar").remove();
2486    }, 300);
2487    $(".floor-plan-menu-category-name").attr("tabindex","0");
2488    $(".floor-plan-menu-item-list-content").attr("tabindex","0");
2489    $('.floor-plan-menu').attr("aria-hidden","false");
2490    if(window.innerHeight<528){
2491        document.querySelector('.floor-plan-container').style.overflowY="auto";
2492    }
2493}
2494// Store the debounced function outside to maintain the same reference
2495let debouncedLoadSvgPanZoomHandler;
2496let oldWindowWidth=0,oldWindowHeight=0;
2497function debounceLoadSvgPanZoom() {
2498    // Only create the debounced function once
2499    if (!debouncedLoadSvgPanZoomHandler) {
2500        debouncedLoadSvgPanZoomHandler = debounce(() => {
2501            //trigger mobile to desktop or desktop to mobile
2502            if((oldWindowWidth<=768&&window.innerWidth>768)||(oldWindowWidth>768&&window.innerWidth<=768)||oldWindowHeight>528&&window.innerHeight<=528){
2503                zoomScale=1
2504                loadFloorButton()
2505                loadZoomInOutButton()
2506                loadSvgFloorPlan(floorInt)
2507            }else{
2508                zoomScale=1
2509                loadZoomInOutButton()
2510                loadSvgPanZoom(floorInt);
2511            }
2512            oldWindowWidth=window.innerWidth;
2513            oldWindowHeight=window.innerHeight;
2514        }, 500);
2515    }
2516    
2517    // Execute the debounced function
2518    debouncedLoadSvgPanZoomHandler();
2519}
2520let floorPlanMap
2521function loadSvgPanZoom(floorInt){
2522    let isMobile=window.innerWidth<=768||window.innerHeight<528?true:false;
2523    floorPlanMap=$(".modal-popup .popup-box .floor-plan-container .floor-plan .map");
2524    if(floorPlanMap.length>0){
2525        let floorPlanAssetName="floorplan-gf-desktop";
2526        if(floorInt===1){
2527            floorPlanAssetName="floorplan-1f-new";
2528        }else if(floorInt===2){
2529            floorPlanAssetName="floorplan-2f-new";
2530        }
2531        if(isMobile){
2532            // floorPlanAssetName="floorplan-gf-mobile";
2533            floorPlanAssetName="floorplan-gf-desktop";
2534            if(floorInt===1){
2535                // floorPlanAssetName="floorplan-1f-mobile";
2536                floorPlanAssetName="floorplan-1f-new";
2537            }else if(floorInt===2){
2538                // floorPlanAssetName="floorplan-2f-mobile";
2539                floorPlanAssetName="floorplan-2f-new";
2540            }
2541        }
2542        const width=floorPlanMap.width();
2543        const height=floorPlanMap.height();
2544        svgPanZoom = $(`.modal-popup .popup-box .floor-plan-container .floor-plan .map svg#${floorPlanAssetName}`).svgPanZoom({
2545            zoomFactor: (isMobile?0.625:0.25),
2546            maxZoom: 1.5,
2547            events: {
2548                mouseWheel: true, // enables mouse wheel zooming events
2549                doubleClick: false, // enables double-click to zoom-in events
2550                drag: true, // enables drag and drop to move the SVG events
2551                dragCursor: "move" // cursor to use while dragging the SVG
2552            },
2553            initialViewBox:{
2554                x:isMobile?0:29.7,//center
2555                y:isMobile?0:100,//center
2556                width:isMobile?1200:1200,//isMobile?675:1200,
2557                height:isMobile?800:800,//isMobile?450:800,
2558            },
2559            limits:{
2560                x:0,
2561                y:0,
2562                x2:isMobile?(1200+(1200-width)):(1200+(1200-width)),//isMobile?(675+(675-width)):(1200+(1200-width)),
2563                y2:isMobile?(800+(800-height)):(800+(800-height))//isMobile?(450+(450-height)):(800+(800-height))
2564            }
2565        });
2566        if(isMobile){
2567            //first zoomout, after first zoomout, width=1725,height=1150
2568            svgPanZoom.zoomOut(100);
2569            // svgPanZoom.limits.x2=(1200*1.45+(1200-width))
2570            
2571            // zoomScale=0.55
2572            // svgPanZoom.limits.x2=1940+768-width
2573            // svgPanZoom.limits.x2=1200*1.45+
2574            
2575            // svgPanZoom.limits.x2=2700-width
2576            // svgPanZoom.limits.y2=1910-height*1.4
2577            // svgPanZoom.setCenter((1200+(1200-width))/2+200,(800+(800-height))/2+50);
2578
2579            //first step limit for zoomScale 0.55
2580            setTimeout(() => {
2581                if(width>=668){
2582                    //default +230px limit width
2583                    svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+230
2584                }else{
2585                    //default +230px limit width plus
2586                    //every 50px width decrease, every 70px limit width increase
2587                    svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+230+(668-width)*70/50
2588                }
2589                if((height*2)>=900){
2590                    //default +150px limit height
2591                    svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+150
2592                }
2593                // else{
2594                //     //after fixed map height, follow not use
2595                //     //default +150px limit width plus
2596                //     //every 100px height decrease, every 70px limit width increase
2597                //     svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+150+(900-(height*2))*70/100
2598                // }
2599            },200);
2600            //second zoomout, after second zoomout, width=1950, height=1300
2601            setTimeout(()=>{
2602                svgPanZoom.zoomOut(100)
2603                zoomScale=0.1
2604            },300);
2605            setTimeout(() => {
2606                if(width>=668){
2607                    //default +60px limit width
2608                    svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+60
2609                }else{
2610                    //default +60px limit width plus
2611                    //every 50px width decrease, every 80px limit width increase
2612                    svgPanZoom.limits.x2=svgPanZoom.getViewBox().width+60+((668-width)*80/50)
2613                }
2614
2615                if((height*2)>=900){
2616                    //default +70px limit height
2617                    svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+70
2618                }
2619                // else{
2620                        //after fixed map height, follow not use
2621                //     //default +70px limit width plus
2622                //     //every 100px height decrease, every 80px limit width increase
2623                //     svgPanZoom.limits.y2=svgPanZoom.getViewBox().height+70+(900-(height*2))*80/100
2624                // }
2625                // svgPanZoom.limits.x2=3850-width*3.48
2626                // svgPanZoom.limits.y2=2430-height*2.4
2627                // svgPanZoom.setCenter((1200+(1200-width))/2+250,(800+(800-height))/2+125);
2628
2629                let extraRightPan=40
2630                if(width>=430&&width<=460){
2631                    extraRightPan=0
2632                }else if(width>=460&&width<=480){
2633                    extraRightPan=-40
2634                }else if(width>=480&&width<=509){
2635                    extraRightPan=-80
2636                }else if(width>=509&&width<=529){
2637                    extraRightPan=-120
2638                }else if(width>=529&&width<=558){
2639                    extraRightPan=-160
2640                }else if(width>=558&&width<=588){
2641                    extraRightPan=-200
2642                }else if(width>=588&&width<=617){
2643                    extraRightPan=-240
2644                }else if(width>=617&&width<=647){
2645                    extraRightPan=-280
2646                }else if(width>=647&&width<=768){
2647                    extraRightPan=-320
2648                }
2649                svgPanZoom.setCenter(svgPanZoom.getViewBox().width/2+width/2+extraRightPan,svgPanZoom.getViewBox().height/2+height/2,100);
2650            }, 500);
2651        }else{
2652            svgPanZoom.setCenter((1200+(1200-width))/2,(800+(800-height))/2);
2653        }
2654        // svgPanZoom.setCenter(isMobile?(1200+(1200-width))/2:(1200+(1200-width))/2, isMobile?(800+(800-height))/2:(800+(800-height))/2, 0)
2655        try{
2656            svgPanZoom.events.mouseWheel= false;
2657        }catch(e){
2658            console.log(e);
2659        }
2660    }
2661}
2662function loadFloorPlanMenu(floorInt,floorPlanDescription,categoryList) {
2663    let currentLang = getLang();
2664    let langKey="en";
2665    if(currentLang==="zh-hk"){
2666        langKey="tc";
2667    }else if(currentLang==="zh-cn"){
2668        langKey="sc";
2669    }
2670    let floorName="";
2671    if(floorInt===0){
2672        floorName=floorObj[langKey].find((row)=>row.value===floorInt)?.label||'';
2673    }else if(floorInt===1){
2674        floorName=floorObj[langKey].find((row)=>row.value===floorInt)?.label||'';
2675    }else if(floorInt===2){
2676        floorName=floorObj[langKey].find((row)=>row.value===floorInt)?.label||'';
2677    }
2678    const category=[]
2679    floorPlanDescription.filter((row)=>row.show===true).forEach((row)=>{
2680        if(!category.includes(row.category)){
2681            category.push(row.category);
2682        }
2683    })
2684    category.sort((a,b)=>{
2685        const categoryListObj = categoryList.reduce((obj,row)=>{
2686            obj[row.category]=row.order;
2687            return obj;
2688        },{})
2689        return categoryListObj[a]-categoryListObj[b];
2690    });
2691    let menuHtml = `
2692    <div class="floor-plan-menu-title">${floorName}</div>
2693    <div class="floor-plan-menu-content">
2694        ${category.map((row,index)=>{
2695            const categoryObj=categoryList.find((row2)=>{return row2.category===row})
2696            return `
2697            <div class="floor-plan-menu-category">
2698                <div class="floor-plan-menu-category-name ${row.replaceAll(" ","-")}" onclick="toggleFloorPlanMenuCategory(this)" onkeydown="if(event.key==='Enter'){toggleFloorPlanMenuCategory(this)}" tabIndex=0 role="button" aria-expanded="false" aria-controls="floor-plan-menu-item-list-${row.replaceAll(" ","-")}">
2699                    <div>${categoryObj?.name?.[langKey]||""}</div>
2700                    <div>
2701                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-up" viewB
2701ox="0 0 16 16">
2702                            <path fill-rule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5"/>
2703                        </svg>
2704                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
2705                            <path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1"/>
2706                        </svg>
2707                    </div>
2708                </div>
2709                <div class="floor-plan-menu-item-list" id="floor-plan-menu-item-list-${row.replaceAll(' ','-')}" aria-hidden="true">
2710                    ${floorPlanDescription.filter((item)=>item.category===row).sort((a,b)=>{return a.order-b.order}).map((item,index)=>{
2711                        if(item.show===false){
2712                            return '';
2713                        }
2714                        let html= 
2715                        `<div class="floor-plan-menu-item-list-content ${item?.id||""}" onclick="activeFloorPlanItem('${item?.id||""}',this,true)" onkeydown="if(event.key==='Enter'){activeFloorPlanItem('${item?.id||""}',this,true)}" tabIndex=0 role="button">`
2716                        +(item.category==="Facilities"?`<div class="floor-plan-menu-item-content-item-icon"><img src="/assets/img/svg/icon/${item?.iconName||""}.svg"/></div>`:``)
2717                        +`<div class="floor-plan-menu-item-content-item-title">${item?.name?.[langKey]?.replace("<br />"," ")||""}</div>`
2718                        +`</div>`;
2719                        return html;
2720                    }).join('')}
2721                </div>
2722            </div>
2723            `
2724        }).join('')}
2725    </div>
2726    `;
2727    $('.floor-plan-menu').html(menuHtml);
2728}
2729function toggleFloorPlanMenuCategory(self){
2730    $(".floor-plan-popup .floor-plan-menu-item-list").slideUp();
2731    $(".floor-plan-popup .floor-plan-menu-category-name.active").attr("aria-expanded",false);
2732    $(".floor-plan-popup .floor-plan-menu-category-name").removeClass("active");
2733    $(".floor-plan-popup .bi-arrow-up").hide()
2734    $(".floor-plan-popup .bi-arrow-down").show()
2735    $(".floor-plan-popup .floor-plan-menu-item-list").attr('aria-hidden',true)
2736    const listEle=self.parentNode.querySelector(".floor-plan-menu-item-list");
2737    if(listEle.style.display==='none'||listEle.style.display===''){
2738        $(self).addClass("active");
2739        $(self).find(".bi-arrow-up").show();
2740        $(self).find(".bi-arrow-down").hide()
2741        $(listEle).slideDown();
2742        $(listEle).attr('aria-hidden',false)
2743        $(self).attr("aria-expanded",true);
2744    }else{
2745        $(listEle).slideUp();
2746        // $(self).attr("aria-expanded",false);
2747    }
2748}
2749function activeFloorPlanItem(id,self,isKeyBoard=false){
2750    //hide old active and update menu background
2751    inactiveFloorPlanItem()
2752
2753    //show new active
2754    if(id.includes("fp-icon")||id==="fp-first-aid-babycare"){ //icon
2755        if(id==='fp-icon-toilet-accessibility'||id==="fp-icon-toilet"||id==="fp-icon-toilet-2"){
2756            idList=["fp-icon-toilet","fp-icon-toilet-2","fp-icon-toilet-accessibility"];
2757        }else if(id==='fp-icon-lift'||id==="fp-icon-lift-2"){
2758            idList=["fp-icon-lift","fp-icon-lift-2"];
2759        }else{
2760            idList=[id];
2761        }
2762        idList.forEach((row)=>{
2763            $('#'+row).addClass('active');
2764            if($('#'+row).find('circle:first').length>0){
2765                if(!$('#'+row).find('circle:first').attr("old-fill")){
2766                    $('#'+row).find('circle:first').attr("old-fill",$('#'+row).find('circle:first').attr("fill"));
2767                }
2768                $('#'+row).find('circle:first').attr("fill","#EA7119");
2769            }else{
2770                if(!$('#'+row).find('ellipse:first').attr("old-fill")){
2771                    $('#'+row).find('ellipse:first').attr("old-fill",$('#'+row).find('ellipse:first').attr("fill"));
2772                }
2773                $('#'+row).find('ellipse:first').attr("fill","#EA7119");
2774            }
2775            
2776            $(`#${row}>g>g:nth-of-type(2) path,#${row}>g>g:nth-of-type(2) rect,#${row}>g>g:nth-of-type(2) circle,#${row}>g>g:nth-of-type(2) ellipse`).each(function(){
2777                if(!$(this).attr("old-fill")){
2778                    $(this).attr("old-fill",$(this).attr("fill"));
2779                }
2780            });
2781            
2782            $(`#${row}>g>g:nth-of-type(2) path,#${row}>g>g:nth-of-type(2) rect,#${row}>g>g:nth-of-type(2) circle,#${row}>g>g:nth-of-type(2) ellipse`).attr("fill","#fff")
2783        })
2784    }else{
2785        $('#'+id).addClass('active');
2786        let findEle='path:first';
2787        if(id.includes("entrance")){
2788            findEle='path';
2789        }
2790        if(!$('#'+id).find(findEle).attr("old-fill")){
2791            $('#'+id).find(findEle).attr("old-fill",$('#'+id).find(findEle).attr("fill"));
2792        }
2793        $('#'+id).find(findEle).attr("fill","#EA7119");
2794    }
2795    $('#'+id+"-popover").addClass('active');
2796    $('#'+id+"-popover").show()
2797    if(isKeyBoard===true){
2798        if($('#'+id+"-popover>"+"#"+id+"-view-details").length>0){
2799            setTimeout(() => {
2800                $('#'+id+"-popover>"+"#"+id+"-view-details").focus()
2801            }, 300);
2802        }
2803        if(window.innerHeight<528){//if browser zoom
2804            document.querySelector('.floor-plan-container').scroll(0,0)
2805        }
2806    }
2807    zoomToSelectSvgItem(document.getElementById(id));
2808    //menu
2809    if(self){
2810        $(self).addClass("active");
2811        $(self).css("background","#EA7119")
2812        setTimeout(() => {
2813            if(window.innerHeight>527){//if not browser zoom
2814                self.scrollIntoView({
2815                    behavior: "smooth",
2816                    block: "nearest"
2817                });
2818            }
2819        }, 500);
2820    }
2821}
2822function inactiveFloorPlanItem(){
2823    $(".map>svg>g[id$=-popover].active").hide();
2824    $(".map>svg>g[id$=-popover].active").removeClass("active")
2825    if($(".map>svg>g.active").length>0){
2826        if($(".map>svg>g.active").attr("id").includes("fp-icon")||$(".map>svg>g.active").attr("id")=="fp-first-aid-babycare"){
2827            // if($(".map>svg>g.active").find('circle:first').length>0){
2828                $(".map>svg>g.active").find('circle:first').attr('fill',$(".map>svg>g.active").find('circle:first').attr("old-fill"))
2829            // }else{
2830                $(".map>svg>g.active").find('ellipse:first').attr('fill',$(".map>svg>g.active").find('ellipse:first').attr("old-fill"))
2831            // }
2832            $(`.map>svg>g.active>g>g:nth-of-type(2) path,.map>svg>g.active>g>g:nth-of-type(2) rect,.map>svg>g.active>g>g:nth-of-type(2) circle,.map>svg>g.active>g>g:nth-of-type(2) ellipse`).each(function(){
2833                $(this).attr("fill",$(this).attr("old-fill"));
2834            });
2835        }else{
2836            if($(".map>svg>g.active").attr("id").includes("entrance")){
2837                $(".map>svg>g.active").find('path').attr('fill',$(".map>svg>g.active").find('path').attr("old-fill"))
2838            }else{
2839                $(".map>svg>g.active").find('path:first').attr('fill',$(".map>svg>g.active").find('path:first').attr("old-fill"))
2840            }
2841        }
2842    }
2843    $(".map>svg>g.active").removeClass("active")
2844    $(".floor-plan-menu .floor-plan-menu-item-list-content.active").css("background","#EAEAEA")
2845    $(".floor-plan-menu .floor-plan-menu-item-list-content.active").css("color","#000")
2846    $(".floor-plan-menu .floor-plan-menu-item-list-content.active").removeClass("active")
2847    $(".floor-plan-detail-sidebar").remove();
2848}
2849const debounce = (func, wait, immediate = false) => {
2850    let timeout;
2851    return function() {
2852        const context = this;
2853        const args = arguments;
2854        
2855        const later = function() {
2856            timeout = null;
2857            if (!immediate) func.apply(context, args);
2858        };
2859        
2860        const callNow = immediate && !timeout;
2861        clearTimeout(timeout);
2862        timeout = setTimeout(later, wait);
2863        
2864        if (callNow) {
2865            func.apply(context, args);
2866        }
2867    };
2868};	
2869$(document).ready(function() {
2870    /*mediaelement js for audio*/
2871    (function($) {
2872        let currentLang=getLang();
2873        let mejs_i18n_zh_cn={
2874            'mejs.plural-form': 0,			
2875			'mejs.download-file': '下载文件',			
2876			'mejs.fullscreen': '全屏',			
2877			'mejs.play': '播放',
2878			'mejs.pause': '暂停',			
2879			'mejs.time-slider': '时间滑动棒',
2880			'mejs.time-help-text': '使用作/右箭头快进1秒,使用上/下箭头快进10秒。',
2881			'mejs.live-broadcast' : '现场直播',			
2882			'mejs.current': '当前时间',
2883			'mejs.duration': '总时长',			
2884			'mejs.volume-help-text': '使用上/下箭头提高或降低音量。',
2885			'mejs.unmute': '取消静音',
2886			'mejs.mute': '静音',
2887			'mejs.volume-slider': '音量选择键',			
2888			'mejs.video-player': '视频播放器',
2889			'mejs.audio-player': '音频播放器',			
2890			'mejs.captions-subtitles': '字幕/标题',
2891			'mejs.captions-chapters': 'ç« ',
2892			'mejs.none': '无',
2893			'mejs.afrikaans': '南非荷兰语',
2894			'mejs.albanian': '阿尔巴尼亚人',
2895			'mejs.arabic': '阿拉伯语',
2896			'mejs.belarusian': '白俄罗斯',
2897			'mejs.bulgarian': '保加利亚语',
2898			'mejs.catalan': '加泰罗尼亚语',
2899			'mejs.chinese': '中国',
2900			'mejs.chinese-simplified': '中文(简体)',
2901			'mejs.chinese-traditional': '中国(传统)',
2902			'mejs.croatian': '克罗地亚语',
2903			'mejs.czech': '捷克',
2904			'mejs.danish': '丹麦语',
2905			'mejs.dutch': '荷兰人',
2906			'mejs.english': '英语',
2907			'mejs.estonian': '爱沙尼亚语',
2908			'mejs.filipino': '菲律宾',
2909			'mejs.finnish': '芬兰语',
2910			'mejs.french': '法语',
2911			'mejs.galician': '加利西亚',
2912			'mejs.german': '德语',
2913			'mejs.greek': '希腊语',
2914			'mejs.haitian-creole': '海地克里奥尔人',
2915			'mejs.hebrew': '希伯来语',
2916			'mejs.hindi': '印地语',
2917			'mejs.hungarian': '匈牙利',
2918			'mejs.icelandic': '冰岛',
2919			'mejs.indonesian': '印尼语',
2920			'mejs.irish': '爱尔兰',
2921			'mejs.italian': '意大利语',
2922			'mejs.japanese': '日本',
2923			'mejs.korean': '韩国人',
2924			'mejs.latvian': '拉脱维亚人',
2925			'mejs.lithuanian': '立陶宛语',
2926			'mejs.macedonian': '马其顿',
2927			'mejs.malay': '马来语',
2928			'mejs.maltese': '马耳他',
2929			'mejs.norwegian': '挪威语',
2930			'mejs.persian': '波斯人',
2931			'mejs.polish': '波兰语',
2932			'mejs.portuguese': '葡萄牙语',
2933			'mejs.romanian': '罗马尼亚语',
2934			'mejs.russian': '俄罗斯',
2935			'mejs.serbian': '塞尔维亚人',
2936			'mejs.slovak': '斯洛伐克语',
2937			'mejs.slovenian': '斯洛文尼亚语',
2938			'mejs.spanish': '西班牙语',
2939			'mejs.swahili': '斯瓦希里语',
2940			'mejs.swedish': '瑞典语',
2941			'mejs.tagalog': '他加禄语',
2942			'mejs.thai': '泰国',
2943			'mejs.turkish': '土耳其语',
2944			'mejs.ukrainian': '乌克兰',
2945			'mejs.vietnamese': '越南人',
2946			'mejs.welsh': '威尔士',
2947			'mejs.yiddish': '意第绪语'
2948        };
2949        mejs.i18n["zh-cn"]={...mejs.i18n["zh-cn"],...mejs_i18n_zh_cn};
2950        let mejs_i18n_zh={
2951			'mejs.plural-form': 0,			
2952			'mejs.download-file': '下載檔案',			
2953			'mejs.fullscreen': '全螢幕',			
2954			'mejs.play': '播放',
2955			'mejs.pause': '暫停',			
2956			'mejs.time-slider': '時間軸',
2957			'mejs.time-help-text': '使用左/右箭頭快轉1秒,上/下箭頭快轉10秒。',
2958			'mejs.live-broadcast' : '現場直播',			
2959			'mejs.current': '當前時間',
2960			'mejs.duration': '總時長',			
2961			'mejs.volume-help-text': '使用上/下箭頭提高或降低音量。',
2962			'mejs.unmute': '取消靜音',
2963			'mejs.mute': '靜音',
2964			'mejs.volume-slider': '音量控制鍵',			
2965			'mejs.video-player': '影片播放器',
2966			'mejs.audio-player': '音樂播放器',			
2967			'mejs.captions-subtitles': '字幕/標題',
2968			'mejs.captions-chapters': '章節',
2969			'mejs.none': '無',
2970			'mejs.afrikaans': '南非荷蘭語',
2971			'mejs.albanian': '阿爾巴尼亞人',
2972			'mejs.arabic': '阿拉伯語',
2973			'mejs.belarusian': '白俄羅斯',
2974			'mejs.bulgarian': '保加利亞語',
2975			'mejs.catalan': '加泰羅尼亞語',
2976			'mejs.chinese': '中文',
2977			'mejs.chinese-simplified': '简体中文',
2978			'mejs.chinese-traditional': '正體中文',
2979			'mejs.croatian': '克羅地亞語',
2980			'mejs.czech': '捷克',
2981			'mejs.danish': '丹麥語',
2982			'mejs.dutch': '荷蘭人',
2983			'mejs.english': '英語',
2984			'mejs.estonian': '愛沙尼亞語',
2985			'mejs.filipino': '菲律賓',
2986			'mejs.finnish': '芬蘭語',
2987			'mejs.french': '法語',
2988			'mejs.galician': '加利西亞',
2989			'mejs.german': '德語',
2990			'mejs.greek': '希臘語',
2991			'mejs.haitian-creole': '海地克里奧爾人',
2992			'mejs.hebrew': '希伯來語',
2993			'mejs.hindi': '印地語',
2994			'mejs.hungarian': '匈牙利',
2995			'mejs.icelandic': '冰島',
2996			'mejs.indonesian': '印尼語',
2997			'mejs.irish': '愛爾蘭',
2998			'mejs.italian': '意大利語',
2999			'mejs.japanese': '日本',
3000			'mejs.korean': '韓國人',
3001			'mejs.latvian': '拉脫維亞人',
3002			'mejs.lithuanian': '立陶宛語',
3003			'mejs.macedonian': '馬其頓',
3004			'mejs.malay': '馬來語',
3005			'mejs.maltese': '馬耳他',
3006			'mejs.norwegian': '挪威語',
3007			'mejs.persian': '波斯人',
3008			'mejs.polish': '波蘭語',
3009			'mejs.portuguese': '葡萄牙語',
3010			'mejs.romanian': '羅馬尼亞語',
3011			'mejs.russian': '俄羅斯',
3012			'mejs.serbian': '塞爾維亞人',
3013			'mejs.slovak': '斯洛伐克語',
3014			'mejs.slovenian': '斯洛文尼亞語',
3015			'mejs.spanish': '西班牙語',
3016			'mejs.swahili': '斯瓦希里語',
3017			'mejs.swedish': '瑞典語',
3018			'mejs.tagalog': '他加祿語',
3019			'mejs.thai': '泰國',
3020			'mejs.turkish': '土耳其語',
3021			'mejs.ukrainian': '烏克蘭',
3022			'mejs.vietnamese': '越南人',
3023			'mejs.welsh': '威爾士',
3024			'mejs.yiddish': '意第緒語'
3025		}
3026        mejs.i18n["zh"]={...mejs.i18n["zh"],...mejs_i18n_zh};
3027        $.extend(mejs.MepDefaults, {
3028            fasterslowerText: 'Faster/Slower',
3029            moreOptionText: currentLang==="en"?"More Option":currentLang==="zh-hk"?"更多選項":"更多选项"
3030        });
3031
3032        // Global object to track player states
3033        window.audioPlayers = window.audioPlayers || {};
3034
3035        
3036            $.extend(MediaElementPlayer.prototype, {
3037                buildfasterslower: function(player, controls, layers, media) {
3038                    var t = this;
3039                    
3040                    // Initialize player in global tracking
3041                    if (!window.audioPlayers[t.id]) {
3042                        window.audioPlayers[t.id] = {
3043                            step: 0,
3044                            player: t
3045                        };
3046                    }
3047
3048                    let displaySpeed =
3049                        $('<div class="display-playback-speed hidden">' +
3050                            (currentLang == "en" ? "Playback Speed: 100%" :
3051                                currentLang == "zh-hk" ? "播放速度: 100%" :
3052                                    currentLang == "zh-cn" ? "播放速度: 100%" : "Playback Speed: 100%") +
3053                            '</div> ')
3054                            .appendTo(controls);
3055                    // $.get('/assets/img/svg/audio-more.svg', function(svgContent) {
3056                    let playSpeedButton =
3057                        $('<div class="mejs__button-group-more-Option" id="audio_'+t.id+'">' +
3058                        '<button type="button" class="mejs__button-moreOption" title="' + t.options.moreOptionText 
3058+ '">'+
3059                        `<svg id="audio_${t.id}-icon-moreOption" class="mejs__icon-moreOption" aria-hidden="true" focusable="false" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1.86 8.51">
3060                            <defs>
3061                                <style>
3062                                .cls-1 {
3063                                    fill: #231f20;
3064                                }
3065                                </style>
3066                            </defs>
3067                            <g id="New">
3068                                <g>
3069                                <circle class="cls-1" cx=".93" cy=".93" r=".93"/>
3070                                <circle class="cls-1" cx=".93" cy="4.25" r=".93"/>
3071                                <circle class="cls-1" cx=".93" cy="7.57" r=".93"/>
3072                                </g>
3073                            </g>
3074                        </svg>`+
3075                        '</button>' +
3076                        '</div>') .appendTo(controls)
3077                        .click(function(e) {
3078                            e.preventDefault();
3079                            e.stopPropagation();
3080                            
3081                            // Close any open audio menus from other players and reset their steps
3082                            document.querySelectorAll('.audio-menu').forEach(menu => {
3083                                if (menu.id !== 'audio_'+t.id+'_menu') {
3084                                    // Get player ID from menu ID and reset its step
3085                                    const playerId = menu.id.replace('audio_', '').replace('_menu', '');
3086                                    if (window.audioPlayers[playerId]) {
3087                                        window.audioPlayers[playerId].step = 0;
3088                                    }
3089                                    menu.remove();
3090                                }
3091                            });
3092                            
3093                            if(window.audioPlayers[t.id].step === 0){
3094                                //create element
3095                                let buttonGroup=document.createElement('div');
3096                                buttonGroup.id="audio_"+t.id+"_menu";
3097                                buttonGroup.classList.add('audio-menu');
3098                                // Add click outside and ESC key event listeners
3099                                const handleKeyDown = function(event) {
3100                                    if (event.key === 'Escape') {
3101                                        const menu = document.getElementById('audio_'+t.id+'_menu');
3102                                        if (menu) {
3103                                            window.audioPlayers[t.id].step = 1;
3104                                            menu.remove();
3105                                            window.audioPlayers[t.id].step = 0;
3106                                            document.removeEventListener('keydown', handleKeyDown);
3107                                            document.removeEventListener('click', handleClickOutside);
3108                                        }
3109                                    }
3110                                };
3111
3112                                const handleClickOutside = function(event) {
3113                                    const menu = document.getElementById('audio_'+t.id+'_menu');
3114                                    const button = document.getElementById('audio_'+t.id);
3115                                    if (menu && !menu.contains(event.target) && !button.contains(event.target)) {
3116                                        window.audioPlayers[t.id].step = 1;
3117                                        menu.remove();
3118                                        window.audioPlayers[t.id].step = 0;
3119                                        document.removeEventListener('click', handleClickOutside);
3120                                        document.removeEventListener('keydown', handleKeyDown);
3121                                    }
3122                                };
3123
3124                                setTimeout(() => {
3125                                    document.addEventListener('click', handleClickOutside);
3126                                    document.addEventListener('keydown', handleKeyDown);
3127                                }, 10);
3128                                let playSpeedText=currentLang==="en"?"Play Speed":(currentLang==="zh-hk"?"播放速度":"播放速度")
3129                                let button=document.createElement('button')
3130                                
3131                                let svg=document.createElement('img');
3132                                svg.id=`audio_${t.id}-icon-speed`;
3133                                svg.classList.add('mejs__icon-speed');
3134                                svg.src='/assets/img/svg/audio-speed.svg';
3135                                svg.alt=currentLang==="en"?"audio speed icon":(currentLang==="zh-hk"?"播放速度圖標":"播放速度图标");
3136                                svg.style.width='20px'
3137                                button.appendChild(svg);
3138                                
3139                                let textSpan = document.createElement('span');
3140                                textSpan.textContent = playSpeedText;
3141                                textSpan.style.marginLeft='8px'
3142                                button.appendChild(textSpan);
3143                                button.onclick=(function(e2){
3144                                e2.preventDefault();
3145                                e2.stopPropagation();
3146                                document.querySelector("#audio_"+t.id+"_menu").innerHTML=""
3147
3148                                //back button
3149                                let button2=document.createElement('button')
3150                                let svg=document.createElement('img');
3151                                svg.id=`audio_${t.id}-icon-speed`;
3152                                svg.classList.add('mejs__icon-speed');
3153                                svg.src='/assets/img/svg/arrow-left.svg';
3154                                svg.alt=currentLang==="en"?"audio back icon":(currentLang==="zh-hk"?"返回圖標":"返回图标");
3155                                svg.style.width='20px'
3156                                button2.appendChild(svg);
3157
3158                                let textSpan = document.createElement('span');
3159                                let optionText=currentLang==="en"?"Option":(currentLang==="zh-hk"?"選項":"选项")
3160                                textSpan.textContent = optionText;
3161                                textSpan.style.marginLeft='8px'
3162                                button2.appendChild(textSpan)
3163                                button2.onclick=((event)=>{
3164                                    document.querySelector("#audio_"+t.id+"_menu").remove()
3165                                    window.audioPlayers[t.id].step=0
3166                                })
3167                                document.querySelector("#audio_"+t.id+"_menu").append(button2)
3168
3169                                //speed button array
3170                                let clickButtonEvent=function (event,row) {
3171                                    event.preventDefault();
3172                                    event.stopPropagation();
3173                                    media.pause();
3174                                    media.playbackRate=(["Normal","一般"].includes(row)?1:parseFloat(row))
3175                                    let playSpeedText=(currentLang == "en" ? "Playback Speed:" :
3176                                    currentLang == "zh-hk" ? "播放速度:" :
3177                                        currentLang == "zh-cn" ? "播放速度:" : "Playback Speed:")
3178                                    $('.display-playback-speed').html(playSpeedText+" "+media.playbackRate*100+"%")
3179                                    media.play();
3180                                    document.querySelector("#audio_"+t.id+"_menu").remove()
3181                                    window.audioPlayers[t.id].step=0
3182                                };
3183                                let normalText=currentLang==="en"?"Normal":(currentLang==="zh-hk"?"一般":"一般")
3184                                let playSpeedArray=["0.5","0.75","1","1.25","1.5","1.75","2"]
3185                                playSpeedArray.forEach((row)=>{
3186                                    let button2=document.createElement('button')
3187                                    //play speed
3188                                    let button2Text=row==="1"?normalText:row
3189                                    let span=document.createElement('span')
3190                                    span.textContent=button2Text
3191                                    span.style.paddingLeft='28px'
3192                                    button2.appendChild(span)
3193                                    
3194                                    if(media.playbackRate===parseFloat(row)){
3195                                    let tickSpan=document.createElement('span')
3196                                    tickSpan.style.fontSize='16px';
3197                                    tickSpan.style.color='blue'
3198                                    tickSpan.style.position='absolute'
3199                                    tickSpan.style.right='20px'
3200                                    tickSpan.innerHTML='&#10003;'
3201                                    button2.appendChild(tickSpan)
3202                                    }
3203
3204
3205                                    button2.onclick=((event)=>clickButtonEvent(event,row))
3206                                    document.querySelector("#audio_"+t.id+"_menu").append(button2)
3207                                })
3208                                window.audioPlayers[t.id].step=2
3209                                })
3210                                buttonGroup.append(button);
3211                                document.querySelector("#audio_"+t.id).append(buttonGroup);
3212                                window.audioPlayers[t.id].step=1
3213                            }else if(window.audioPlayers[t.id].step===2){
3214                            }
3215                        })
3216                    // })
3217                    media.addEventListener('play',function() {
3218                    }, false);
3219
3220                    media.addEventListener('pause',function() {
3221                    }, false);
3222                }
3223            });
3224    })(mejs.$);
3225
3226    /*MediaElement.js*/
3227    let currentLang=getLang(),mediaLang='en';
3228
3229    if(currentLang==="zh-hk"){
3230        mediaLang='zh'
3231    }
3232    if(currentLang==='zh-cn'){
3233        mediaLang='zh-cn'
3234    }
3235
3236    let sourcesSelector = document.querySelectorAll('select[name=sources]'),
3237        sourcesTotal = sourcesSelector.length;
3238
3239    for (var i = 0; i < sourcesTotal; i++) {
3240        sourcesSelector[i].addEventListener('change', function () {
3241
3242            var media = this.closest('.players').querySelector('.mejs__container').id,player = mejs.players[media];
3243
3244            player.setSrc(this.value.replace('&amp;', '&'));
3245            player.load();
3246            if (!mejs.Features.isiOS && !mejs.Features.isAndroid) {
3247                player.play();
3248            }
3249
3250            var renderer = document.getElementById(player.media.id + '-rendername');
3251            renderer.querySelector('.src').innerHTML = '<a href="' + this.value + '" target="_blank">' + this.value + '</a>';
3252            renderer.querySelector('.renderer').innerHTML = player.media.rendererName;
3253            renderer.querySelector('.error').innerHTML = '';
3254
3255        });
3256
3257        // These media types cannot play at all on iOS, so disabling them
3258        if (mejs.Features.isiOS) {
3259            sourcesSelector[i].querySelector('option[value^="rtmp"]').disabled = true;
3260            if (sourcesSelector[i].querySelector('option[value$="webm"]')) {
3261                sourcesSelector[i].querySelector('option[value$="webm"]').disabled = true;
3262            }
3263            if (sourcesSelector[i].querySelector('option[value$=".mpd"]')) {
3264                sourcesSelector[i].querySelector('option[value$=".mpd"]').disabled = true;
3265            }
3266            if (sourcesSelector[i].querySelector('option[value$=".ogg"]')) {
3267                sourcesSelector[i].querySelector('option[value$=".ogg"]').disabled = true;
3268            }
3269        }
3270    }
3271
3272    mejs.i18n.language(mediaLang);
3273
3274	var mediaElements = document.querySelectorAll('audio'), i, total = mediaElements.length;
3275
3276	for (let i = 0; i < total; i++) {
3277        mediaElements[i].preload="auto"
3278		let player=new MediaElementPlayer(mediaElements[i], {
3279            features:['playpause','current','progress','duration','volume','fullscreen','fasterslower'],
3280			stretching: 'auto',
3281            hideVolumeOnTouchDevices: false,
3282            autoRewind: false,
3283			success: function (media) {
3284				var renderer = document.getElementById(media.id + '-rendername');
3285
3286				media.addEventListener('loadedmetadata', function () {
3287					var src = media.originalNode.getAttribute('src').replace('&amp;', '&');
3288					if (src !== null && src !== undefined) {
3289						// renderer.querySelector('.src').innerHTML = '<a href="' + src + '" target="_blank">' + src + '</a>';
3290						// renderer.querySelector('.renderer').innerHTML = media.rendererName;
3291						// renderer.querySelector('.error').innerHTML = '';
3292					}
3293				});
3294
3295				media.addEventListener('error', function (e) {
3296					// renderer.querySelector('.error').innerHTML = '<strong>Error</strong>: ' + e.message;
3297				});
3298			}
3299		});
3300    player.media.addEventListener('ended', function() {
3301        mediaElements[i].parentElement.parentElement.parentElement.querySelector(".play-pause-text").innerHTML=(currentLang==='en'?'Play':(currentLang==="zh-hk"?"播放":"播放"));
3302    });
3303	}
3304    let playPauseButtonArray=document.querySelectorAll('.mejs__playpause-button');
3305    playPauseButtonArray.forEach((item)=>{
3306        let playText=currentLang==='en'?'Play':(currentLang==="zh-hk"?"播放":"播放");
3307        let pauseText=currentLang==='en'?'Pause':(currentLang==="zh-hk"?"暫停":"暂停")
3308        const newSpanEle = document.createElement('span');
3309        newSpanEle.classList.add('play-pause-text');
3310        newSpanEle.textContent=playText;
3311        
3312        item.append(newSpanEle)
3313
3314        item.onclick = function(){
3315            if(item.classList.contains('mejs__pause')){
3316                item.parentNode.querySelector('.play-pause-text').textContent=playText;
3317            }else{
3318                item.parentNode.querySelector('.play-pause-text').textContent=pauseText;
3319            }
3320        };
3321    })
3322    let isHoverVolumeBar=false;
3323    $('.mejs__container.mejs__audio').attr('tabindex',-1);
3324    $('.mejs__playpause-button>button').on("keyup",function(e){
3325        if (e.key === 'Tab') {
3326            $(this.parentNode).css('outline','2px solid black');
3327            $(this.parentNode).css('border-radius','4px');
3328        }
3329    });
3330    $('.mejs__volume-button>button').on("keyup",function(e){
3331        if (e.key === 'Tab') {
3332            $(this).parent().parent().find('.mejs__horizontal-volume-container').css('border','2px solid black');
3333            $(this).parent().parent().find('.mejs__horizontal-volume-container').css('border-radius','4px');
3334            $(this).parent().parent().find('.mejs__horizontal-volume-container').css('opacity', 1);
3335        }
3336    });
3337    $('.mejs__volume-button>button').on("focusout",function(){
3338        $(this).parent().parent().find('.mejs__horizontal-volume-container').css('border','none');
3339        $(this).parent().parent().find('.mejs__horizontal-volume-container').css('border-radius','none');
3340        $(this).parent().parent().find('.mejs__horizontal-volume-container').css('opacity', 0);
3341        $(this).parent().parent().find('.mejs__horizontal-volume-slider').hide();
3342        isHoverVolumeBar=false;
3343    });
3344    $('.mejs__playpause-button>button').on("focusout",function(){
3345        $(this.parentNode).css('outline','2px solid transparent');
3346        $(this.parentNode).css('border-radius','none');
3347        $(this).parent().parent().find('.mejs__horizontal-volume-container').css('opacity', 0);
3348    });
3349    $('.mejs__controls').append('<div class="mejs__horizontal-volume-container"></div>')
3350    $('.mejs__volume-button').on("mouseenter",function(){
3351        if(isHoverVolumeBar===false){
3352            $(this).parent().parent().find('.mejs__horizontal-volume-container').css('opacity', 1);
3353            $(this).parent().find('.mejs__horizontal-volume-slider').show();
3354            isHoverVolumeBar=true;
3355        }
3356    });
3357    $('.mejs__horizontal-volume-slider').hide();
3358    $('.mejs__horizontal-volume-container,.mejs__volume-button,.mejs__horizontal-volume-slider').on("mouseout",function(e){
3359        if(isHoverVolumeBar===true){
3360            if(e.relatedTarget.tagName!=='use'
3361                &&e.relatedTarget.tagName!=='svg'
3362                &&!e.relatedTarget.classList.contains('mejs__horizontal-volume-container')
3363                &&!e.relatedTarget.classList.contains('mejs__horizontal-volume-slider')
3364                &&!e.relatedTarget.classList.contains('mejs__horizontal-volume-current')
3365                &&!e.relatedTarget.classList.contains('mejs__horizontal-volume-total')
3366                &&!e.relatedTarget.parentNode.classList.contains('mejs__volume-button')
3367            ){
3368                $(this).parent().parent().find('.mejs__horizontal-volume-container').css('opacity', 0);
3369                $(this).parent().find('.mejs__horizontal-volume-slider').hide();
3370                isHoverVolumeBar=false;
3371            }
3372        }
3373    })
3374    /*end of MediaElement.js*/
3375
3376    //nav
3377    $('nav[aria-label]').attr('aria-label', currentPageLang === 'en' ? 'breadcrumb' : currentPageLang === 'zh-hk' ? '導航' : '导航');
3378
3379    //modal close button aria-label
3380    let closeAriaLabel= currentLang == "zh-hk" ? '關閉' : currentLang == "zh-cn" ? '关闭' : 'Close'
3381    setTimeout(() => {
3382        $('.btn-close').attr('aria-label',closeAriaLabel);
3383    }, 500);
3384
3385    //for collection details donate border 
3386    let donateSection=document.querySelector(".row.section-block.donate-section");
3387    if(donateSection){
3388        donateSection.classList.add("border-b-0")
3389    }
3390})

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.