UNPKG

ticket-selector

Version:

A professional stadium seat selection widget with multi-language support

1 lines 57.7 kB
const t={controls:{zoomIn:"Zoom In (+)",zoomOut:"Zoom Out (-)",fitToScreen:"Fit to Screen",backToStadium:"Back to Stadium",enterFullscreen:"Enter Fullscreen",exitFullscreen:"Exit Fullscreen"},info:{seatsSelected:{zero:"No seats selected",one:"1 seat selected",other:"{count} seats selected"}},loading:{default:"Loading...",loadingSeats:"Loading seats..."},sector:{name:"Sector: {name}",price:"Price: {price}",available:"Available: {available}/{total}",category:"{category} Category",unavailable:"No seats available",soldOut:"All seats are sold out"},seat:{sector:"Sector: {sector}",row:"Row: {row}",seat:"Seat: {seat}",price:"Price: {price}",available:"Available",selected:"Selected",unavailable:"Unavailable",maxReached:"Maximum {max} seats allowed",cannotSelectMore:"Please deselect a seat to continue",category:{premium:"Premium",standard:"Standard",economy:"Economy",basic:"Basic"}},errors:{containerNotFound:"TicketSelector: Container element not found",stadiumNotFound:"Stadium HTML not found! Please add stadium structure to HTML.",htmlStructureInvalid:"Required HTML structure not found! Please check the HTML.",sectorDataNotFound:"Sector data file not found for sector ID {sectorId}",sectorLoadFailed:"Failed to load seat information. Please try again.",panzoomNotLoaded:"Panzoom library not loaded"}},e={controls:{zoomIn:"Böyüt (+)",zoomOut:"Kiçilt (-)",fitToScreen:"Ekrana Sığdır",backToStadium:"Stadiuma Qayıt",enterFullscreen:"Tam Ekran",exitFullscreen:"Tam Ekrandan Çıx"},info:{seatsSelected:{zero:"Heç bir yer seçilməyib",one:"1 yer seçilib",other:"{count} yer seçilib"}},loading:{default:"Yüklənir...",loadingSeats:"Yerlər yüklənir..."},sector:{name:"Sektor: {name}",price:"Qiymət: {price}",available:"Mövcud: {available}/{total}",category:"{category} Kateqoriya",unavailable:"Bu sektorda yer yoxdur",soldOut:"Bütün yerlər satılıb"},seat:{sector:"Sektor: {sector}",row:"Sıra: {row}",seat:"Yer: {seat}",price:"Qiymət: {price}",available:"Mövcud",selected:"Seçildi",unavailable:"Mövcud deyil",maxReached:"Maksimum {max} yer seçilə bilər",cannotSelectMore:"Davam etmək üçün bir yer seçimini ləğv edin",category:{premium:"Premium",standard:"Standart",economy:"Ekonom",basic:"Əsas"}},errors:{containerNotFound:"TicketSelector: Konteyner elementi tapılmadı",stadiumNotFound:"Stadion HTML tapılmadı! Zəhmət olmasa stadion strukturunu HTML-ə əlavə edin.",htmlStructureInvalid:"Tələb olunan HTML strukturu tapılmadı! Zəhmət olmasa HTML-i yoxlayın.",sectorDataNotFound:"Sektor ID {sectorId} üçün sektor data faylı tapılmadı",sectorLoadFailed:"Yer məlumatları yüklənə bilmədi. Zəhmət olmasa yenidən cəhd edin.",panzoomNotLoaded:"Panzoom kitabxanası yüklənməyib"}},n={controls:{zoomIn:"Yakınlaştır (+)",zoomOut:"Uzaklaştır (-)",fitToScreen:"Ekrana Sığdır",backToStadium:"Stadiuma Dön",enterFullscreen:"Tam Ekran",exitFullscreen:"Tam Ekrandan Çık"},info:{seatsSelected:{zero:"Hiç koltuk seçilmedi",one:"1 koltuk seçildi",other:"{count} koltuk seçildi"}},loading:{default:"Yükleniyor...",loadingSeats:"Koltuklar yükleniyor..."},sector:{name:"Sektör: {name}",price:"Fiyat: {price}",available:"Müsait: {available}/{total}",category:"{category} Kategorisi"},seat:{sector:"Sektör: {sector}",row:"Sıra: {row}",seat:"Koltuk: {seat}",price:"Fiyat: {price}",available:"Müsait",selected:"Seçildi",unavailable:"Müsait değil",maxReached:"Maksimum {max} koltuk seçebilirsiniz",cannotSelectMore:"Devam etmek için bir koltuk seçimini iptal edin",category:{premium:"Premium",standard:"Standart",economy:"Ekonomi",basic:"Temel"}},errors:{containerNotFound:"TicketSelector: Konteyner elementi bulunamadı",stadiumNotFound:"Stadyum HTML bulunamadı! Lütfen stadyum yapısını HTML'e ekleyin.",htmlStructureInvalid:"Gerekli HTML yapısı bulunamadı! Lütfen HTML'i kontrol edin.",sectorDataNotFound:"Sektör ID {sectorId} için sektör veri dosyası bulunamadı",sectorLoadFailed:"Koltuk bilgileri yüklenemedi. Lütfen tekrar deneyin.",panzoomNotLoaded:"Panzoom kütüphanesi yüklenmemiş"}};class o{constructor(o=null){this.languages={en:t,az:e,tr:n},this.defaultLanguage="az",this.currentLanguage=this.detectLanguage(o),this.translations=this.languages[this.currentLanguage]||this.languages[this.defaultLanguage]}detectLanguage(t){if(t&&this.languages[t])return t;const e=this.getBrowserLanguage();return this.languages[e]?e:this.defaultLanguage}extractLanguageCode(t){return t&&"string"==typeof t?t.split(/[-_]/)[0].toLowerCase().trim():null}getBrowserLanguage(){if("undefined"!=typeof document){const t=document.documentElement.lang;if(t){const e=this.extractLanguageCode(t);if(e&&this.languages[e])return e}}if("undefined"!=typeof navigator){const t=navigator.language||navigator.userLanguage;if(t){const e=this.extractLanguageCode(t);if(e&&this.languages[e])return e}}return this.defaultLanguage}t(t,e={},n=null){const o=t.split(".");let i=this.translations;for(const e of o){if(!i||"object"!=typeof i||!(e in i)){i=this.getFallbackTranslation(t);break}i=i[e]}return i&&"object"==typeof i&&null!==n&&(i=this.getPlural(i,n)),"string"!=typeof i?t:this.replaceParams(i,e,n)}getFallbackTranslation(t){const e=t.split(".");let n=this.languages[this.defaultLanguage];for(const o of e){if(!n||"object"!=typeof n||!(o in n))return t;n=n[o]}return n}getPlural(t,e){const n=parseInt(e);return 0===n&&t.zero?t.zero:1===n&&t.one?t.one:t.other?t.other:t.other||t.one||t.zero||""}replaceParams(t,e,n){let o=t;return null!==n&&(e.count=n),Object.keys(e).forEach(t=>{const n=`{${t}}`;o=o.replace(new RegExp(n,"g"),e[t])}),o}setLanguage(t){return!!this.languages[t]&&(this.currentLanguage=t,this.translations=this.languages[t],!0)}getCurrentLanguage(){return this.currentLanguage}getAvailableLanguages(){return Object.keys(this.languages)}}function i(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var s={exports:{}};function a(t,e,n){t.addEventListener("wheel",e,n)}s.exports=a,s.exports.addWheelListener=a,s.exports.removeWheelListener=function(t,e,n){t.removeEventListener("wheel",e,n)};var r=s.exports,l={exports:{}},c=.1,u="function"==typeof Float32Array;function h(t,e){return 1-3*e+3*t}function d(t,e){return 3*e-6*t}function m(t){return 3*t}function p(t,e,n){return((h(e,n)*t+d(e,n))*t+m(e))*t}function f(t,e,n){return 3*h(e,n)*t*t+2*d(e,n)*t+m(e)}function g(t){return t}var v=function(t,e,n,o){if(!(0<=t&&t<=1&&0<=n&&n<=1))throw new Error("bezier x values must be in [0, 1] range");if(t===e&&n===o)return g;for(var i=u?new Float32Array(11):new Array(11),s=0;s<11;++s)i[s]=p(s*c,t,n);function a(e){for(var o=0,s=1;10!==s&&i[s]<=e;++s)o+=c;--s;var a=o+(e-i[s])/(i[s+1]-i[s])*c,r=f(a,t,n);return r>=.001?function(t,e,n,o){for(var i=0;i<4;++i){var s=f(e,n,o);if(0===s)return e;e-=(p(e,n,o)-t)/s}return e}(e,a,t,n):0===r?a:function(t,e,n,o,i){var s,a,r=0;do{(s=p(a=e+(n-e)/2,o,i)-t)>0?n=a:e=a}while(Math.abs(s)>1e-7&&++r<10);return a}(e,o,o+c,t,n)}return function(t){return 0===t?0:1===t?1:p(a(t),e,o)}},y={ease:v(.25,.1,.25,1),easeIn:v(.42,0,1,1),easeOut:v(0,0,.58,1),easeInOut:v(.42,0,.58,1),linear:v(0,0,1,1)};function S(){}function b(){var t=new Set,e=new Set,n=0;return{next:o,cancel:o,clearAll:function(){t.clear(),e.clear(),cancelAnimationFrame(n),n=0}};function o(t){e.add(t),n||(n=requestAnimationFrame(i))}function i(){n=0;var o=e;e=t,(t=o).forEach(function(t){t()}),t.clear()}}l.exports=function(t,e,n){var o=Object.create(null),i=Object.create(null),s="function"==typeof(n=n||{}).easing?n.easing:y[n.easing];s||(n.easing,s=y.ease);var a="function"==typeof n.step?n.step:S,r="function"==typeof n.done?n.done:S,l=function(t){if(!t){return"undefined"!=typeof window&&window.requestAnimationFrame?{next:window.requestAnimationFrame.bind(window),cancel:window.cancelAnimationFrame.bind(window)}:{next:function(t){return setTimeout(t,1e3/60)},cancel:function(t){return clearTimeout(t)}}}if("function"!=typeof t.next)throw new Error("Scheduler is supposed to have next(cb) function");if("function"!=typeof t.cancel)throw new Error("Scheduler is supposed to have cancel(handle) function");return t}(n.scheduler),c=Object.keys(e);c.forEach(function(n){o[n]=t[n],i[n]=e[n]-t[n]});var u,h="number"==typeof n.duration?n.duration:400,d=Math.max(1,.06*h),m=0;return u=l.next(function e(){var n=s(m/d);m+=1,p(n),m<=d?(u=l.next(e),a(t)):(u=0,setTimeout(function(){r(t)},0))}),{cancel:function(){l.cancel(u),u=0}};function p(e){c.forEach(function(n){t[n]=i[n]*e+o[n]})}},l.exports.makeAggregateRaf=b,l.exports.sharedScheduler=b();var w,x,E=l.exports;function _(){return"function"==typeof cancelAnimationFrame?cancelAnimationFrame:clearTimeout}function L(){return"function"==typeof requestAnimationFrame?requestAnimationFrame:function(t){return setTimeout(t,16)}}function T(t){return t.stopPropagation(),!1}function k(){}var H,C={exports:{}};var $,M={exports:{}};var I=r,A=E,z=function(t){!function(t){if(!t)throw new Error("Eventify cannot use falsy object as events subject");for(var e=["on","fire","off"],n=0;n<e.length;++n)if(t.hasOwnProperty(e[n]))throw new Error("Subject cannot be eventified, since it already has property '"+e[n]+"'")}(t);var e=function(t){var e=Object.create(null);return{on:function(n,o,i){if("function"!=typeof o)throw new Error("callback is expected to be a function");var s=e[n];return s||(s=e[n]=[]),s.push({callback:o,ctx:i}),t},off:function(n,o){if(void 0===n)return e=Object.create(null),t;if(e[n])if("function"!=typeof o)delete e[n];else for(var i=e[n],s=0;s<i.length;++s)i[s].callback===o&&i.splice(s,1);return t},fire:function(n){var o,i=e[n];if(!i)return t;arguments.length>1&&(o=Array.prototype.splice.call(arguments,1));for(var s=0;s<i.length;++s){var a=i[s];a.callback.apply(a.ctx,o)}return t}}}(t);return t.on=e.on,t.off=e.off,t.fire=e.fire,t},F=function(t,e,n){"object"!=typeof n&&(n={});var o,i,s,a,r,l,c,u,h,d,m="number"==typeof n.minVelocity?n.minVelocity:5,p="number"==typeof n.amplitude?n.amplitude:.25,f="function"==typeof n.cancelAnimationFrame?n.cancelAnimationFrame:_(),g="function"==typeof n.requestAnimationFrame?n.requestAnimationFrame:L();return{start:function(){o=t(),l=h=a=c=0,i=new Date,f(s),f(d),s=g(v)},stop:function(){f(s),f(d);var e=t();r=e.x,u=e.y,i=Date.now(),(a<-m||a>m)&&(r+=l=p*a);(c<-m||c>m)&&(u+=h=p*c);d=g(y)},cancel:function(){f(s),f(d)}};function v(){var e=Date.now(),n=e-i;i=e;var r=t(),l=r.x-o.x,u=r.y-o.y;o=r;var h=1e3/(1+n);a=.8*l*h+.2*a,c=.8*u*h+.2*c,s=g(v)}function y(){var t=Date.now()-i,n=!1,o=0,s=0;l&&((o=-l*Math.exp(-t/342))>.5||o<-.5?n=!0:o=l=0),h&&((s=-h*Math.exp(-t/342))>.5||s<-.5?n=!0:s=h=0),n&&(e(r+o,u+s),d=g(y))}},R=function(t){if(t)return{capture:k,release:k};var e,n,o,i=!1;return{capture:function(t){i=!0,n=window.document.onselectstart,o=window.document.ondragstart,window.document.onselectstart=T,(e=t).ondragstart=T},release:function(){if(!i)return;i=!1,window.document.onselectstart=n,e&&(e.ondragstart=o)}}},P=R(),B=R(!0),D=x?w:(x=1,w=function(){this.x=0,this.y=0,this.scale=1}),V=function(){if(H)return C.exports;function t(t){return t&&t.ownerSVGElement&&t.getCTM}return H=1,C.exports=function(e,n){if(!t(e))throw new Error("svg element is required for svg.panzoom to work");var o=e.ownerSVGElement;if(!o)throw new Error("Do not apply panzoom to the root <svg> element. Use its child instead (e.g. <g></g>). As of March 2016 only FireFox supported transform on the root element");n.disableKeyboardInteraction||o.setAttribute("tabindex",0);return{getBBox:function(){var t=e.getBBox();return{left:t.x,top:t.y,width:t.width,height:t.height}},getScreenCTM:function(){var t=o.getCTM();if(!t)return o.getScreenCTM();return t},getOwner:function(){return o},applyTransform:function(t){e.setAttribute("transform","matrix("+t.scale+" 0 0 "+t.scale+" "+t.x+" "+t.y+")")},initTransform:function(t){var n=e.getCTM();null===n&&(n=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGMatrix());t.x=n.e,t.y=n.f,t.scale=n.a,o.removeAttributeNS(null,"viewBox")}}},C.exports.canAttach=t,C.exports}(),O=function(){if($)return M.exports;function t(t){return t&&t.parentElement&&t.style}return $=1,M.exports=function(e,n){if(!t(e))throw new Error("panzoom requires DOM element to be attached to the DOM tree");var o=e.parentElement;e.scrollTop=0,n.disableKeyboardInteraction||o.setAttribute("tabindex",0);return{getBBox:function(){return{left:0,top:0,width:e.clientWidth,height:e.clientHeight}},getOwner:function(){return o},applyTransform:function(t){e.style.transformOrigin="0 0 0",e.style.transform="matrix("+t.scale+", 0, 0, "+t.scale+", "+t.x+", "+t.y+")"}}},M.exports.canAttach=t,M.exports}(),N=q;function q(t,e){var n=(e=e||{}).controller;if(n||(V.canAttach(t)?n=V(t,e):O.canAttach(t)&&(n=O(t,e))),!n)throw new Error("Cannot create panzoom for the current type of dom element");var o=n.getOwner(),i={x:0,y:0},s=!1,a=new D;n.initTransform&&n.initTransform(a);var r,l="function"==typeof e.filterKey?e.filterKey:Y,c="number"==typeof e.pinchSpeed?e.pinchSpeed:1,u=e.bounds,h="number"==typeof e.maxZoom?e.maxZoom:Number.POSITIVE_INFINITY,d="number"==typeof e.minZoom?e.minZoom:0,m="number"==typeof e.boundsPadding?e.boundsPadding:.05,p="number"==typeof e.zoomDoubleClickSpeed?e.zoomDoubleClickSpeed:1.75,f=e.beforeWheel||Y,g=e.beforeMouseDown||Y,v="number"==typeof e.zoomSpeed?e.zoomSpeed:1,y=Z(e.transformOrigin),S=e.enableTextSelection?B:P;!function(t){var e=typeof t;if("undefined"===e||"boolean"===e)return;var n=X(t.left)&&X(t.top)&&X(t.bottom)&&X(t.right);if(!n)throw new Error("Bounds object is not valid. It can be: undefined, boolean (true|false) or an object {left, top, right, bottom}")}(u),e.autocenter&&function(){var t,e,i=0,s=0,r=st();if(r)i=r.left,s=r.top,t=r.right-r.left,e=r.bottom-r.top;else{var l=o.getBoundingClientRect();t=l.width,e=l.height}var c=n.getBBox();if(0===c.width||0===c.height)return;var u=e/c.height,h=t/c.width,d=Math.min(h,u);a.x=-(c.left+c.width/2)*d+t/2+i,a.y=-(c.top+c.height/2)*d+e/2+s,a.scale=d}();var b,w,x,E,_,L,T,k,H,C,$=0,M=0,R=0,N=null,q=new Date,W=!1,G=!1;T="smoothScroll"in e&&!e.smoothScroll?{start:Y,stop:Y,cancel:Y}:F(function(){return{x:a.x,y:a.y}},function(t,e){It(),nt(t,e)},e.smoothScroll);var U=!1;ut();var K={dispose:function(){ht()},moveBy:ct,moveTo:nt,smoothMoveTo:function(t,e){ct(t-a.x,e-a.y,!0)},centerOn:function(t){var e=t.ownerSVGElement;if(!e)throw new Error("ui element is required to be within the scene");var n=t.getBoundingClientRect(),o=n.left+n.width/2,i=n.top+n.height/2,s=e.getBoundingClientRect(),a=s.width/2-o,r=s.height/2-i;ct(a,r,!0)},zoomTo:Mt,zoomAbs:lt,smoothZoom:Ct,smoothZoomAbs:function(t,e,n){var o={scale:a.scale},i={scale:n};T.cancel(),It(),H=A(o,i,{step:function(n){lt(t,e,n.scale)}})},showRectangle:function(t){var e=o.getBoundingClientRect(),n=et(e.width,e.height),i=t.right-t.left,s=t.bottom-t.top;if(!Number.isFinite(i)||!Number.isFinite(s))throw new Error("Invalid rectangle");var r=n.x/i,l=n.y/s,c=Math.min(r,l);a.x=-(t.left+i/2)*c+n.x/2,a.y=-(t.top+s/2)*c+n.y/2,a.scale=c},pause:function(){ht(),U=!0},resume:function(){U&&(ut(),U=!1)},isPaused:function(){return U},getTransform:function(){return a},getMinZoom:function(){return d},setMinZoom:function(t){d=t},getMaxZoom:function(){return h},setMaxZoom:function(t){h=t},getTransformOrigin:function(){return y},setTransformOrigin:function(t){y=Z(t)},getZoomSpeed:function(){return v},setZoomSpeed:function(t){if(!Number.isFinite(t))throw new Error("Zoom speed should be a number");v=t}};z(K);var Q="number"==typeof e.initialX?e.initialX:a.x,J="number"==typeof e.initialY?e.initialY:a.y,tt="number"==typeof e.initialZoom?e.initialZoom:a.scale;return Q==a.x&&J==a.y&&tt==a.scale||lt(Q,J,tt),K;function et(t,e){if(n.getScreenCTM){var o=n.getScreenCTM(),s=o.a,a=o.d,r=o.e,l=o.f;i.x=t*s-r,i.y=e*a-l}else i.x=t,i.y=e;return i}function nt(t,e){a.x=t,a.y=e,it(),Pt("pan"),at()}function ot(t,e){nt(a.x+t,a.y+e)}function it(){var t=st();if(t){var e,o,i,s,r=!1,l=(e=n.getBBox(),i=e.left,s=e.top,{left:(o={x:i*a.scale+a.x,y:s*a.scale+a.y}).x,top:o.y,right:e.width*a.scale+o.x,bottom:e.height*a.scale+o.y}),c=t.left-l.right;return c>0&&(a.x+=c,r=!0),(c=t.right-l.left)<0&&(a.x+=c,r=!0),(c=t.top-l.bottom)>0&&(a.y+=c,r=!0),(c=t.bottom-l.top)<0&&(a.y+=c,r=!0),r}}function st(){if(u){if("boolean"==typeof u){var t=o.getBoundingClientRect(),e=t.width,n=t.height;return{left:e*m,top:n*m,right:e*(1-m),bottom:n*(1-m)}}return u}}function at(){s=!0,r=window.requestAnimationFrame(dt)}function rt(t,e,n){if(j(t)||j(e)||j(n))throw new Error("zoom requires valid numbers");var o=a.scale*n;if(o<d){if(a.scale===d)return;n=d/a.scale}if(o>h){if(a.scale===h)return;n=h/a.scale}var i=et(t,e);(a.x=i.x-n*(i.x-a.x),a.y=i.y-n*(i.y-a.y),u&&1===m&&1===d)?(a.scale*=n,it()):it()||(a.scale*=n);Pt("zoom"),at()}function lt(t,e,n){rt(t,e,n/a.scale)}function ct(t,e,n){if(!n)return ot(t,e);k&&k.cancel();var o=0,i=0;k=A({x:0,y:0},{x:t,y:e},{step:function(t){ot(t.x-o,t.y-i),o=t.x,i=t.y}})}function ut(){o.addEventListener("mousedown",xt,{passive:!1}),o.addEventListener("dblclick",wt,{passive:!1}),o.addEventListener("touchstart",pt,{passive:!1}),o.addEventListener("keydown",mt,{passive:!1}),I.addWheelListener(o,kt,{passive:!1}),at()}function ht(){I.removeWheelListener(o,kt),o.removeEventListener("mousedown",xt),o.removeEventListener("keydown",mt),o.removeEventListener("dblclick",wt),o.removeEventListener("touchstart",pt),r&&(window.cancelAnimationFrame(r),r=0),T.cancel(),Lt(),Tt(),S.release(),Ft()}function dt(){s&&(s=!1,n.applyTransform(a),Pt("transform"),r=0)}function mt(t){var e=0,n=0,i=0;if(38===t.keyCode?n=1:40===t.keyCode?n=-1:37===t.keyCode?e=1:39===t.keyCode?e=-1:189===t.keyCode||109===t.keyCode?i=1:187!==t.keyCode&&107!==t.keyCode||(i=-1),!l(t,e,n,i)){if(e||n){t.preventDefault(),t.stopPropagation();var s=o.getBoundingClientRect();ct(.05*(a=Math.min(s.width,s.height))*e,.05*a*n)}if(i){var a,r=At(100*i);Mt((a=y?$t():{x:(c=o.getBoundingClientRect()).width/2,y:c.height/2}).x,a.y,r)}var c}}function pt(t){if(function(t){if(e.onTouch&&!e.onTouch(t))return;t.stopPropagation(),t.preventDefault()}(t),vt(),1===t.touches.length)return function(t){M=new Date;var e=t.touches[0],n=Ht(e);b=n;var o=et(n.x,n.y);w=o.x,x=o.y,E=w,_=x,T.cancel(),ft()}(t,t.touches[0]);2===t.touches.length&&(L=bt(t.touches[0],t.touches[1]),C=!0,ft())}function ft(){W||(W=!0,document.addEventListener("touchmove",gt),document.addEventListener("touchend",St),document.addEventListener("touchcancel",St))}function gt(t){if(1===t.touches.length){t.stopPropagation();var e=et((h=Ht(t.touches[0])).x,h.y),n=e.x-w,o=e.y-x;0!==n&&0!==o&&zt(),w=e.x,x=e.y,ct(n,o)}else if(2===t.touches.length){C=!0;var i=t.touches[0],s=t.touches[1],a=bt(i,s),r=1+(a/L-1)*c,l=Ht(i),u=Ht(s);if(w=(l.x+u.x)/2,x=(l.y+u.y)/2,y){var h=$t();w=h.x,x=h.y}Mt(w,x,r),L=a,t.stopPropagation(),t.preventDefault()}}function vt(){R&&(clearTimeout(R),R=0)}function yt(t){if(e.onClick){vt();var n=w-E,o=x-_;Math.sqrt(n*n+o*o)>5||(R=setTimeout(function(){R=0,e.onClick(t)},300))}}function St(t){if(vt(),t.touches.length>0){var e=et((n=Ht(t.touches[0])).x,n.y);w=e.x,x=e.y}else{var n,o=new Date;if(o-$<300)if(y)Ct((n=$t()).x,n.y,p);else Ct(b.x,b.y,p);else o-M<200&&yt(t);$=o,Ft(),Tt()}}function bt(t,e){var n=t.clientX-e.clientX,o=t.clientY-e.clientY;return Math.sqrt(n*n+o*o)}function wt(t){!function(t){vt(),e.onDoubleClick&&!e.onDoubleClick(t)||(t.preventDefault(),t.stopPropagation())}(t);var n=Ht(t);y&&(n=$t()),Ct(n.x,n.y,p)}function xt(t){if(vt(),!g(t)){if(N=t,q=new Date,W)return t.stopPropagation(),!1;if(1===t.button&&null!==window.event||0===t.button){T.cancel();var e=Ht(t),n=et(e.x,e.y);return E=w=n.x,_=x=n.y,document.addEventListener("mousemove",Et),document.addEventListener("mouseup",_t),S.capture(t.target||t.srcElement),!1}}}function Et(t){if(!W){zt();var e=Ht(t),n=et(e.x,e.y),o=n.x-w,i=n.y-x;w=n.x,x=n.y,ct(o,i)}}function _t(){new Date-q<200&&yt(N),S.release(),Ft(),Lt()}function Lt(){document.removeEventListener("mousemove",Et),document.removeEventListener("mouseup",_t),G=!1}function Tt(){document.removeEventListener("touchmove",gt),document.removeEventListener("touchend",St),document.removeEventListener("touchcancel",St),G=!1,C=!1,W=!1}function kt(t){if(!f(t)){T.cancel();var e=t.deltaY;t.deltaMode>0&&(e*=100);var n=At(e);if(1!==n){var o=y?$t():Ht(t);Mt(o.x,o.y,n),t.preventDefault()}}}function Ht(t){var e=o.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top}}function Ct(t,e,n){var o=a.scale,i={scale:o},s={scale:n*o};T.cancel(),It(),H=A(i,s,{step:function(n){lt(t,e,n.scale)},done:Rt})}function $t(){var t=o.getBoundingClientRect();return{x:t.width*y.x,y:t.height*y.y}}function Mt(t,e,n){return T.cancel(),It(),rt(t,e,n)}function It(){H&&(H.cancel(),H=null)}function At(t){return 1-Math.sign(t)*Math.min(.25,Math.abs(v*t/128))}function zt(){G||(Pt("panstart"),G=!0,T.start())}function Ft(){G&&(C||T.stop(),Pt("panend"))}function Rt(){Pt("zoomend")}function Pt(t){K.fire(t,K)}}function Z(t){if(t)return"object"==typeof t?(X(t.x)&&X(t.y)||W(t),t):void W()}function W(t){throw new Error(["Cannot parse transform origin.","Some good examples:",' "center center" can be achieved with {x: 0.5, y: 0.5}',' "top center" can be achieved with {x: 0.5, y: 0}',' "bottom right" can be achieved with {x: 1, y: 1}'].join("\n"))}function Y(){}function X(t){return Number.isFinite(t)}function j(t){return Number.isNaN?Number.isNaN(t):t!=t}!function(){if("undefined"!=typeof document){var t=document.getElementsByTagName("script");if(t){for(var e,n=0;n<t.length;++n){var o=t[n];if(o.src&&o.src.match(/\bpanzoom(\.min)?\.js/)){e=o;break}}if(e){var i=e.getAttribute("query");if(i){var s=e.getAttribute("name")||"pz",a=Date.now();!function t(){var n=document.querySelector(i);if(!n){return Date.now()-a<2e3?void setTimeout(t,100):void 0}var o=function(t){for(var e=t.attributes,n={},o=0;o<e.length;++o){var i=r(e[o]);i&&(n[i.name]=i.value)}return n}(e);window[s]=q(n,o)}()}}}}function r(t){if(t.name&&("p"===t.name[0]&&"z"===t.name[1]&&"-"===t.name[2]))return{name:t.name.substr(3),value:JSON.parse(t.value)}}}();var G=i(N);class U extends EventTarget{constructor(t,e={}){if(super(),this.version="1.0.8",this.classSelector="ticket-select",this.isLoading=!0,this.container="string"==typeof t?document.querySelector(t):t,this.i18n=new o(e.lang),!this.container)throw new Error(this.i18n.t("errors.containerNotFound"));this.showInfo=!1!==e.showInfo,this.showControls=!1!==e.showControls,this.maxSeat=e.maxSeat||1/0,this.currentView="stadium",this.selectedSeats=new Set,this.sectorData=null,this.panzoomInstance=null,this.isDragging=!1,this.isDraggingSector=!1,this.mousePressed=!1,this.startX=0,this.startY=0,this.isFullscreen=!1,this.tooltip=null,this.tooltipTimeout=null,this.TOOLTIP_DELAY=300,this.stadiumHTML=null,this.BASE_VIEWPORT_WIDTH=1216,this.BASE_VIEWPORT_HEIGHT=607,this.MIN_VIEWPORT_WIDTH=800,this.MIN_VIEWPORT_HEIGHT=400,this.G_V_HEIGHT=420.77,this.BASE_ROW_WIDTH=1125.09,this.BASE_ROW_HEIGHT=54.81,this.PERSPECTIVE_SCALE=.9825,this.ROW_OVERLAP=20,this.STEP_SPACING=0,this.BASE_SEAT_SPACING=2.56,this.MIN_FONT_SIZE=4,this.MAX_FONT_SIZE=12,this.FONT_SCALE_FACTOR=3,this.MIN_CIRCLE_RADIUS=4,this.MAX_CIRCLE_RADIUS=10,this.CIRCLE_SCALE_FACTOR=3,this.initWithLoading()}t(t,e={},n=null){return this.i18n.t(t,e,n)}setLanguage(t){return!!this.i18n.setLanguage(t)&&(this.refreshUITexts(),!0)}getCurrentLanguage(){return this.i18n.getCurrentLanguage()}getAvailableLanguages(){return this.i18n.getAvailableLanguages()}refreshUITexts(){if(this.showControls&&this.controls){const t=this.controls.querySelector(`.${this.classSelector}__control-btn--zoom-in`),e=this.controls.querySelector(`.${this.classSelector}__control-btn--zoom-out`),n=this.controls.querySelector(`.${this.classSelector}__control-btn--fit`),o=this.controls.querySelector(`.${this.classSelector}__control-btn--back`),i=this.controls.querySelector(`.${this.classSelector}__control-btn--fullscreen`);if(i){const t=this.isFullscreen?this.t("controls.exitFullscreen"):this.t("controls.enterFullscreen");i.setAttribute("aria-label",t),i.setAttribute("data-tooltip",t)}t&&(t.setAttribute("aria-label",this.t("controls.zoomIn")),t.setAttribute("data-tooltip",this.t("controls.zoomIn"))),e&&(e.setAttribute("aria-label",this.t("controls.zoomOut")),e.setAttribute("data-tooltip",this.t("controls.zoomOut"))),n&&(n.setAttribute("aria-label",this.t("controls.fitToScreen")),n.setAttribute("data-tooltip",this.t("controls.fitToScreen"))),o&&(o.setAttribute("aria-label",this.t("controls.backToStadium")),o.setAttribute("data-tooltip",this.t("controls.backToStadium")))}this.updateSelectedCount()}setupGlobalTooltipListeners(){this.globalClickHandler=t=>{this.tooltip.contains(t.target)||(this.hideTooltip(),this.cancelTooltip())},this.globalKeydownHandler=t=>{"Escape"===t.key&&(this.hideTooltip(),this.cancelTooltip())},document.addEventListener("click",this.globalClickHandler),document.addEventListener("keydown",this.globalKeydownHandler)}createTooltip(){this.tooltip=document.createElement("div"),this.tooltip.className="ticket-tooltip",this.tooltip.style.cssText="\n position: fixed;\n background: rgba(0, 0, 0, 0.85);\n color: white;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n z-index: 10000;\n pointer-events: none;\n opacity: 0;\n transform: translateY(8px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n max-width: 400px;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);\n white-space: nowrap;\n ",document.body.appendChild(this.tooltip)}showTooltip(t,e,n){if(!this.tooltip)return;this.tooltip.innerHTML=t;const o=this.tooltip.getBoundingClientRect();let i;i=e>window.innerWidth/2?e-o.width-10:e+10;let s=n-o.height-10;s<10&&(s=n+20),this.tooltip.style.left=i+"px",this.tooltip.style.top=s+"px",this.tooltip.style.opacity="1",this.tooltip.style.transform="translateY(0)"}hideTooltip(){this.tooltip&&(this.tooltip.style.opacity="0",this.tooltip.style.transform="translateY(10px)")}scheduleTooltip(t,e,n){this.tooltipTimeout&&clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(()=>{this.showTooltip(t,e,n)},this.TOOLTIP_DELAY)}cancelTooltip(){this.tooltipTimeout&&(clearTimeout(this.tooltipTimeout),this.tooltipTimeout=null),this.hideTooltip()}async initWithLoading(){try{await new Promise(t=>setTimeout(t,100)),this.setupContainer(),await new Promise(t=>setTimeout(t,500)),this.setupEventListeners(),this.setupZoomControls(),this.createTooltip(),this.setupGlobalTooltipListeners(),this.setupFullscreenListener(),this.loadStadiumView(),setTimeout(()=>{this.updateSectorAttributes(),this.setupSectorListeners()},400),this.isLoading=!1,this.container.classList.add("is-loaded"),this.dispatchEvent(new CustomEvent("ready",{detail:{version:this.version}}))}catch(t){this.showError("Failed to initialize widget")}}init(){this.setupContainer(),this.setupEventListeners(),this.setupZoomControls(),this.setupSectorListeners()}setupContainer(){if(this.wrapper=this.container.querySelector(`.${this.classSelector}__container`),this.viewport=this.container.querySelector(`.${this.classSelector}__viewport`),this.content=this.container.querySelector(`.${this.classSelector}__content`),!this.viewport||!this.content)return;const t=this.content.querySelector(`.${this.classSelector}__stadium`);t&&(this.stadiumHTML=t.outerHTML,this.createControlsAndInfo(),this.createInitialLoadingScreen())}createInitialLoadingScreen(){const t=this.t("loading.default"),e=`\n <div class="${this.classSelector}__loading">\n <div class="${this.classSelector}__loader">\n <svg viewBox="0 0 24 24">\n <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-dasharray="31.416" stroke-dashoffset="31.416">\n <animate attributeName="stroke-dashoffset" dur="2s" values="31.416;0" repeatCount="indefinite"/>\n <animate attributeName="stroke-dasharray" dur="2s" values="0 31.416;15.708 15.708;0 31.416" repeatCount="indefinite"/>\n </circle>\n </svg>\n </div>\n <div class="${this.classSelector}__loading-text">${t}</div>\n </div>\n `;this.content.insertAdjacentHTML("beforeend",e)}createControlsAndInfo(){let t="";this.showControls&&(t+=`\n <div class="${this.classSelector}__controls">\n <button class="${this.classSelector}__control-btn ${this.classSelector}__control-btn--fullscreen" \n aria-label="${this.t("controls.enterFullscreen")}" \n data-tooltip="${this.t("controls.enterFullscreen")}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 3V5H4V9H2V3H8ZM2 21V15H4V19H8V21H2ZM22 21H16V19H20V15H22V21ZM22 9H20V5H16V3H22V9Z"></path></svg></button>\n <button class="${this.classSelector}__control-btn ${this.classSelector}__control-btn--zoom-in" \n aria-label="${this.t("controls.zoomIn")}" \n data-tooltip="${this.t("controls.zoomIn")}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path></svg></button>\n <button class="${this.classSelector}__control-btn ${this.classSelector}__control-btn--zoom-out" \n aria-label="${this.t("controls.zoomOut")}" \n data-tooltip="${this.t("controls.zoomOut")}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 11V13H19V11H5Z"></path></svg></button>\n <button class="${this.classSelector}__control-btn ${this.classSelector}__control-btn--fit" \n aria-label="${this.t("controls.fitToScreen")}" \n data-tooltip="${this.t("controls.fitToScreen")}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M21 3C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21ZM20 5H4V19H20V5ZM13 17V15H16V12H18V17H13ZM11 7V9H8V12H6V7H11Z"></path></svg></button>\n <button class="${this.classSelector}__control-btn ${this.classSelector}__control-btn--back" \n style="display: none;" \n aria-label="${this.t("controls.backToStadium")}" \n data-tooltip="${this.t("controls.backToStadium")}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22.0003 13.0001L22.0004 11.0002L5.82845 11.0002L9.77817 7.05044L8.36396 5.63623L2 12.0002L8.36396 18.3642L9.77817 16.9499L5.8284 13.0002L22.0003 13.0001Z"></path></svg></button>\n </div>\n `);const e=this.container.querySelector(`.${this.classSelector}__wrapper`),n=e.querySelector(`.${this.classSelector}__info`);if(this.showInfo&&!n&&(t+=`\n <div class="${this.classSelector}__info">\n <span class="${this.classSelector}__selected-count">${this.t("info.seatsSelected.zero")}</span>\n </div>\n `),e.insertAdjacentHTML("beforeend",t),this.controls=this.container.querySelector(`.${this.classSelector}__controls`),this.backBtn=this.container.querySelector(`.${this.classSelector}__control-btn--back`),this.selectedCountEl=this.container.querySelector(`.${this.classSelector}__selected-count`),this.backBtn&&this.backBtn.addEventListener("click",()=>{this.loadStadiumView()}),this.showControls&&this.controls){const t=this.controls.querySelector(`.${this.classSelector}__control-btn--fullscreen`);t&&t.addEventListener("click",()=>{this.toggleFullscreen()}),this.setupControlTooltips()}}setupControlTooltips(){this.controls.querySelectorAll(`.${this.classSelector}__control-btn`).forEach(t=>{const e=t.dataset.tooltip;e&&(t.addEventListener("mouseenter",n=>{const o=t.getBoundingClientRect();o.left,o.width;const i=o.top+o.height/2,s=o.left-8,a=i;this.scheduleControlTooltip(e,s,a)}),t.addEventListener("mouseleave",()=>{this.cancelTooltip()}))})}scheduleControlTooltip(t,e,n){this.tooltipTimeout&&clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(()=>{this.showControlTooltip(t,e,n)},this.TOOLTIP_DELAY)}showControlTooltip(t,e,n){if(!this.tooltip)return;this.tooltip.innerHTML=t;const o=this.tooltip.getBoundingClientRect(),i=e-o.width,s=n-o.height/2;this.tooltip.style.left=i+"px",this.tooltip.style.top=s+"px",this.tooltip.style.opacity="1",this.tooltip.style.transform="translateY(0)"}loadStadiumView(){this.currentView="stadium",this.showControls&&this.backBtn&&(this.backBtn.style.display="none"),this.viewport.classList.remove(`${this.classSelector}__viewport--seats-view`),this.container.classList.remove("is-loaded"),this.showLoading(),setTimeout(()=>{this.stadiumHTML&&(this.content.innerHTML=this.stadiumHTML),this.updateSectorAttributes(),this.setupSectorListeners(),this.initPanzoom(),this.container.classList.add("is-loaded"),setTimeout(()=>this.fitToScreen(),100)},300)}setupSectorListeners(){this.removeSectorListeners();this.content.querySelectorAll(`.${this.classSelector}__sector`).forEach(t=>{let e=0,n=0,o=!1;const i=t=>{const i=t.touches?t.touches[0].clientX:t.clientX,s=t.touches?t.touches[0].clientY:t.clientY;e=i,n=s,o=!1},s=t=>{if(0!==e||0!==n){const i=t.touches?t.touches[0].clientX:t.clientX,s=t.touches?t.touches[0].clientY:t.clientY,a=Math.abs(i-e),r=Math.abs(s-n);(a>5||r>5)&&(o=!0,this.isDraggingSector=!0)}},a=()=>{e=0,n=0,setTimeout(()=>{o=!1,this.isDraggingSector=!1},10)},r=e=>{if(e.stopPropagation(),e.preventDefault(),o||this.isDragging)return;if("true"===t.dataset.disabled)return;this.hideTooltip(),this.cancelTooltip(),this.viewport.classList.add(`${this.classSelector}__viewport--seats-view`),this.container.classList.remove("is-loaded"),this.showLoading();const n=t.dataset.sector,i=t.dataset.sectorId,s=new CustomEvent("sectorClick",{detail:{sectorId:i,sectorName:n,element:t}});this.dispatchEvent(s)},l=e=>{const n="true"===t.dataset.disabled;if(t.style.fillOpacity=n?"0.5":"0.8",t.style.cursor=n?"not-allowed":"pointer",!this.isDragging&&!this.isDraggingSector){const o={name:t.dataset.sector,price:t.dataset.price||"0 AZN",available:parseInt(t.dataset.available)||0,total:parseInt(t.dataset.total)||0,category:"Standard",disabled:n},i=this.createSectorTooltipContent(o);this.scheduleTooltip(i,e.clientX,e.clientY)}},c=e=>{if(!this.isDragging&&!this.isDraggingSector&&this.tooltip&&"1"===this.tooltip.style.opacity){const n="true"===t.dataset.disabled,o={name:t.dataset.sector,price:t.dataset.price||"0 AZN",available:parseInt(t.dataset.available)||0,total:parseInt(t.dataset.total)||0,category:"Standard",disabled:n},i=this.createSectorTooltipContent(o);this.showTooltip(i,e.clientX,e.clientY)}},u=()=>{t.style.fillOpacity="0.6",this.cancelTooltip()};t._clickHandler=r,t._mouseDownHandler=i,t._sectorMoveHandler=s,t._mouseUpHandler=a,t._mouseEnterHandler=l,t._mouseMoveHandler=c,t._mouseLeaveHandler=u,t.addEventListener("mousedown",i),t.addEventListener("mousemove",s),t.addEventListener("mouseup",a),t.addEventListener("touchstart",i),t.addEventListener("touchmove",s),t.addEventListener("touchend",a),t.addEventListener("click",r),t.addEventListener("mouseenter",l),t.addEventListener("mousemove",c),t.addEventListener("mouseleave",u)})}removeSectorListeners(){this.content.querySelectorAll(`.${this.classSelector}__sector`).forEach(t=>{t._clickHandler&&(t.removeEventListener("click",t._clickHandler),t.removeEventListener("mousedown",t._mouseDownHandler),t.removeEventListener("mousemove",t._sectorMoveHandler),t.removeEventListener("mouseup",t._mouseUpHandler),t.removeEventListener("touchstart",t._mouseDownHandler),t.removeEventListener("touchmove",t._sectorMoveHandler),t.removeEventListener("touchend",t._mouseUpHandler),t.removeEventListener("mouseenter",t._mouseEnterHandler),t.removeEventListener("mousemove",t._mouseMoveHandler),t.removeEventListener("mouseleave",t._mouseLeaveHandler),delete t._clickHandler,delete t._mouseDownHandler,delete t._sectorMoveHandler,delete t._mouseUpHandler,delete t._mouseEnterHandler,delete t._mouseMoveHandler,delete t._mouseLeaveHandler)})}createSectorTooltipContent(t){const e=t.price||"100 AZN",n=t.available||25,o=t.total||35;return t.disabled?`\n <div style="text-align: center;">\n <div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">\n ${this.t("sector.name",{name:t.name})}\n </div>\n <div style="color: #ff5252; font-weight: bold; font-size: 14px; margin-top: 8px;">\n ${this.t("sector.unavailable")}\n </div>\n <div style="color: #999; font-size: 12px; margin-top: 4px;">\n ${this.t("sector.soldOut")}\n </div>\n </div>\n `:`\n <div style="text-align: center;">\n <div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">\n ${this.t("sector.name",{name:t.name})}\n </div>\n <div style="margin-bottom: 4px;">\n <strong>${this.t("sector.price",{price:e})}</strong>\n </div>\n <div style="margin-bottom: 4px;">\n <strong>${this.t("sector.available",{available:n,total:o})}</strong>\n </div>\n <div style="color: #4CAF50; font-size: 12px; margin-top: 8px;">\n ${this.t("sector.category",{category:t.category})}\n </div>\n </div>\n `}setSectorData(t,e={}){this.currentView="seats",this.showControls&&this.backBtn&&(this.backBtn.style.display="flex"),this.container.classList.remove("is-loaded"),this.showLoading(),this.sectorData=t,this.sectorPrice=e.price||t.price||null,this.sectorAvailability=e.availability||t.availability||null,setTimeout(()=>{const n=e.sectorColor||null,o=this.generateSeatsForSector(t,n);this.content.innerHTML=`\n <div class="${this.classSelector}__seats-header">\n <h2 class="${this.classSelector}__seats-title">${t.name}</h2>\n </div>\n <svg class="${this.classSelector}__seats-svg" \n viewBox="0 0 ${o.viewBoxWidth} ${o.viewBoxHeight}" \n preserveAspectRatio="xMidYMid meet">\n <g class="${this.classSelector}__seats-group">\n ${o.content}\n </g>\n </svg>\n `,this.setupSeatListeners(),this.destroyPanzoom(),this.initPanzoom(),this.container.classList.add("is-loaded"),setTimeout(()=>this.fitToScreen(),100)},300)}showLoading(t=null){t||(t=this.t("loading.default"));this.content.innerHTML=`\n <div class="${this.classSelector}__loading">\n <div class="${this.classSelector}__loader">\n <svg viewBox="0 0 24 24">\n <circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-dasharray="31.416" stroke-dashoffset="31.416">\n <animate attributeName="stroke-dasharray" dur="2s" values="0 31.416;15.708 15.708;0 31.416" repeatCount="indefinite"/>\n <animate attributeName="stroke-dashoffset" dur="2s" values="0;-15.708;-31.416" repeatCount="indefinite"/>\n </circle>\n </svg>\n </div>\n <div class="${this.classSelector}__loading-text">${t}</div>\n </div>\n `}showError(t){this.content.innerHTML=`\n <div class="${this.classSelector}__loading">\n <div style="color: #bb2932; font-size: 16px; text-align: center;">\n <div style="font-size: 24px; margin-bottom: 10px;">⚠️</div>\n <div>${t}</div>\n </div>\n </div>\n `}generateSeatsForSector(t,e=null){let n="";const o=this.calculateDynamicViewport(t),i=this.calculateMaxSeatsInRow(t),s=Math.min(this.BASE_ROW_WIDTH*o.widthScale,.95*o.width);n+=this.generatePerspectiveBackground(t,this.STEP_SPACING,s,o,i);return[...t.seats].sort((t,e)=>e.id-t.id).forEach((a,r)=>{const l=a.id,c=l-1,u=Math.pow(this.PERSPECTIVE_SCALE,c),h=s*u,d=this.BASE_ROW_HEIGHT*u,m=t.seats.length;let p=this.BASE_ROW_HEIGHT-this.ROW_OVERLAP;i>80?p*=.6:i>50&&(p*=.8);const f=m*p,g=.8*o.height,v=(o.height-Math.min(f,g))/2+(m-1-c)*Math.min(p,g/m),y=(o.width-h)/2;n+=`<g data-row="${l}" data-sector="${t.id||"sector"}">`,n+=this.generateRowSeats({row:a,rowIndex:c,rowWidth:h,rowHeight:d,xPosition:y,yPosition:v,scaleMultiplier:u,currentSeatId:1e3+50*c,sectorName:t.name,maxSeatsInRow:i,sectorColor:e});const S=y-40,b=v+d/2+5,w=14*u;n+=`\n <text class="${this.classSelector}__seats-row-label" \n transform="translate(${S} ${b})" \n style="font-size: ${w}px;">${l}</text>\n `,n+="</g>"}),{content:n,viewBoxWidth:o.width,viewBoxHeight:o.height}}calculateMaxSeatsInRow(t){let e=0;return t.seats.forEach(t=>{let n=0,o=1;t.data.forEach(t=>{t.skipLeft&&t.skipLeft>0&&(o+=t.skipLeft),n=Math.max(n,o),o++,t.skipRight&&t.skipRight>0&&(o+=t.skipRight)}),e=Math.max(e,n)}),e}calculateDynamicViewport(t){const e=this.calculateMaxSeatsInRow(t),n=t.seats.length;let o=this.BASE_VIEWPORT_WIDTH,i=this.BASE_VIEWPORT_HEIGHT;if(e>50){const t=Math.min(2,e/50);o=this.BASE_VIEWPORT_WIDTH*t}if(n>20){const t=Math.min(1.5,n/20);i=this.BASE_VIEWPORT_HEIGHT*t}const s=o/this.BASE_VIEWPORT_WIDTH,a=i/this.BASE_VIEWPORT_HEIGHT;return{width:Math.round(o),height:Math.round(i),widthScale:s,heightScale:a}}calculateActualSeatCount(t){let e=0,n=1;return t.data.forEach(t=>{t.skipLeft&&t.skipLeft>0&&(n+=t.skipLeft),e=Math.max(e,n),n++,t.skipRight&&t.skipRight>0&&(n+=t.skipRight)}),e}calculateRowTotalWidth(t,e,n){let o=0;return t.data.forEach((i,s)=>{i.skipLeft&&i.skipLeft>0&&(o+=i.skipLeft*(e+n)),o+=e,i.skipRight&&i.skipRight>0&&(o+=i.skipRight*(e+n)),s<t.data.length-1&&(o+=n)}),o}generatePerspectiveBackground(t,e,n,o,i){let s=`\n <g id="v">\n <rect class="${this.classSelector}__seats-background" y="0" width="${o.width}" height="${o.height}"></rect>\n <g>\n `;return[...t.seats].sort((t,e)=>t.id-e.id).forEach((a,r)=>{const l=r,c=Math.pow(this.PERSPECTIVE_SCALE,l),u=n*c+100,h=this.BASE_ROW_HEIGHT*c,d=t.seats.length;let m=this.BASE_ROW_HEIGHT-this.ROW_OVERLAP;i>80?m*=.6:i>50&&(m*=.8);const p=d*m,f=.8*o.height,g=((o.height-Math.min(p,f))/2+(d-1-l)*Math.min(m,f/d)+h+e)*this.PERSPECTIVE_SCALE-18,v=(o.width-u)/2;s+=`\n <rect class="${this.classSelector}__seats-step" \n x="${v}" \n y="${g}" \n width="${u}" \n height="12"></rect>\n `}),s+="\n </g>\n </g>\n ",s}generateRowSeats({row:t,rowIndex:e,rowWidth:n,rowHeight:o,xPosition:i,yPosition:s,scaleMultiplier:a,currentSeatId:r,sectorName:l,maxSeatsInRow:c,sectorColor:u=null}){let h="";const d=this.BASE_SEAT_SPACING*a,m=(.85*n-(c-1)*d)/c;this.calculateActualSeatCount(t);const p=m,f=.9*o;let g=i+(n-this.calculateRowTotalWidth(t,p,d))/2,v=0;return t.data.forEach((e,n)=>{e.skipLeft&&e.skipLeft>0&&(g+=e.skipLeft*(p+d));const i=g,r=s+(o-f)/2,c=`seat-${e.id}`,m=!1!==e.available;let y=m?`${this.classSelector}__seat ${this.classSelector}__seat--available`:`${this.classSelector}__seat ${this.classSelector}__seat--unavailable`;u&&(y+=` ${this.classSelector}__seat--color-${u}`),v++;const S=e.number?`${e.number}`:`${v}`;h+=this.generatePerspectiveSeat({seatId:c,row:t.id,seat:e.id,seatName:S,x:i,y:r,width:p,height:f,scale:a,isAvailable:m,seatClass:y,sectorName:l}),g+=p+d,e.skipRight&&e.skipRight>0&&(g+=e.skipRight*(p+d))}),h}generatePerspectiveSeat({seatId:t,row:e,seat:n,seatName:o,x:i,y:s,width:a,height:r,scale:l,isAvailable:c,seatClass:u,sectorName:h}){const d=[`M${i+6},${s}`,`L${i+a-6},${s}`,`Q${i+a},${s} ${i+a},${s+6}`,`L${i+a},${s+r-3}`,`Q${i+a},${s+r} ${i+a-3},${s+r}`,`L${i+3},${s+r}`,`Q${i},${s+r} ${i},${s+r-3}`,`L${i},${s+6}`,`Q${i},${s} ${i+6},${s}`,"Z"].join(" ");let m=Math.min(a,r)/this.CIRCLE_SCALE_FACTOR;m=Math.min(m,this.MAX_CIRCLE_RADIUS),m=Math.max(m,this.MIN_CIRCLE_RADIUS);const p=Math.max(m*l,.8*this.MIN_CIRCLE_RADIUS),f=i+a/2,g=s+r/3.5*l,v=f,y=g+p/8;let S=Math.min(a/this.FONT_SCALE_FACTOR,this.MAX_FONT_SIZE);S=Math.max(S,this.MIN_FONT_SIZE);const b=Math.max(S*l,.7*this.MIN_FONT_SIZE);return`\n <g id="${t}" \n data-row="${e}" \n data-seat="${n}" \n data-sector="17641" \n class="${u}"\n ${c?`\n data-sector-label="${h}" \n data-row-label="${e}" \n data-seat-label="${o}"\n data-seat-id="${t}" \n `:""}>\n <path d="${d}"/>\n <circle cx="${f}" cy="${g}" r="${p}"/>\n <text x="${v}" \n y="${y}" \n text-anchor="middle" \n dominant-baseline="central"\n ${b?`style="font-size: ${b}px;"`:""}>${o}</text>\n </g>\n `}setupSeatListeners(){this.content.querySelectorAll(`.${this.classSelector}__seat.${this.classSelector}__seat--available`).forEach(t=>{const e=t.querySelector("path"),n=t.id;if(!t.classList.contains(`${this.classSelector}__seat--available`))return;const o=o=>{o.stopPropagation(),o.preventDefault(),this.isDragging||(this.hideTooltip(),this.cancelTooltip(),this.toggleSeat(n,t,e))};t.addEventListener("click",o),t.addEventListener("touchend",o),t.addEventListener("mouseenter",o=>{if(this.isDragging)return;const i=this.selectedSeats.size>=this.maxSeat,s=this.selectedSeats.has(n);s||(i?(e.style.filter="",t.style.cursor="not-allowed"):(e.style.filter="brightness(1.2)",t.style.cursor="pointer"));const a=this.getSeatInfo(n),r=this.createSeatTooltipContent(a,i&&!s);this.scheduleTooltip(r,o.clientX,o.clientY)}),t.addEventListener("mousemove",t=>{if(!this.isDragging&&this.tooltip&&"1"===this.tooltip.style.opacity){const e=this.selectedSeats.size>=this.maxSeat,o=this.selectedSeats.has(n),i=this.getSeatInfo(n),s=this.createSeatTooltipContent(i,e&&!o);this.showTooltip(s,t.clientX,t.clientY)}}),t.addEventListener("mouseleave",()=>{this.selectedSeats.has(n)||(e.style.filter=""),this.cancelTooltip()})})}calculateSeatPosition(t,e){let n=1,o=0;for(let i=0;i<t.data.length;i++){const s=t.data[i];if(s.skipLeft&&s.skipLeft>0&&(n+=s.skipLeft),o++,s.id===e)return{physicalPosition:n,seatNumber:o,isAvailable:!1!==s.available};n++,s.skipRight&&s.skipRight>0&&(n+=s.skipRight)}return null}getSeatInfo(t){if(!this.sectorData||!this.sectorData.seats)return{seatId:t,sector:"A2",row:1,seat:1,price:this.sectorPrice||"120 ₼",category:"Standard",isSelected:this.selectedSeats.has(t)};const e=parseInt(t.replace("seat-",""));for(let n=0;n<this.sectorData.seats.length;n++){const o=this.sectorData.seats[n],i=this.calculateSeatPosition(o,e);if(i)return{seatId:t,sector:this.sectorData.name||"A2",row:o.id,seat:i.seatNumber,physicalPosition:i.physicalPosition,price:this.sectorPrice||"120 ₼",category:"Standard",isSelected:this.selectedSeats.has(t),isAvailable:i.isAvailable}}return{seatId:t,sector:"A2",row:1,seat:1,price:this.sectorPrice||"120 ₼",category:"Standard",isSelected:this.selectedSeats.has(t)}}createSeatTooltipContent(t,e=!1){if(e)return`\n <div style="text-align: center;">\n <div style="font-size: 16px; font-weight: bold; margin-bottom: 8px; color: #FF5722;">\n ${this.t("seat.maxReached",{max:this.maxSeat})}\n </div>\n <div style="color: #999; font-size: 12px;">\n ${this.t("seat.cannotSelectMore")}\n </div>\n </div>\n `;const n=t.isSelected?"#FF5722":"#4CAF50",o=t.isSelected?this.t("seat.selected"):this.t("seat.available");return`\n <div style="text-align: center;">\n <div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">\n ${this.t("seat.sector",{sector:t.sector})}\n </div>\n <div style="margin-bottom: 4px;">\n <strong>${this.t("seat.row",{row:t.row})}</strong> &nbsp;&nbsp; <strong>${this.t("seat.seat",{seat:t.seat})}</strong>\n </div>\n <div style="margin-bottom: 4px;">\n <strong>${this.t("seat.price",{price:t.price})}</strong>\n </div>\n <div style="color: ${n}; font-size: 12px; margin-top: 8px;">\n ${o} • ${t.category}\n </div>\n </div>\n `}toggleSeat(t,e,n){if(this.selectedSeats.has(t))this.selectedSeats.delete(t),e.classList.remove(`${this.classSelector}__seat--selected`);else{if(this.selectedSeats.size>=this.maxSeat){const t=`\n <div style="text-align: center;">\n <div style="font-size: 16px; font-weight: bold; margin-bottom: 8px; color: #FF5722;">\n ${this.t("seat.maxReached",{max:this.maxSeat})}\n </div>\n <div style="color: #999; font-size: 12px;">\n ${this.t("seat.cannotSelectMore")}\n </div>\n </div>\n `,n=e.getBoundingClientRect();return this.showTooltip(t,n.left+n.width/2,n.top),void setTimeout(()=>this.hideTooltip(),2e3)}this.selectedSeats.add(t),e.classList.add(`${this.classSelector}__seat--selected`)}this.updateSelectedCount()}updateSelectedCount(){if(this.selectedCountEl||(this.selectedCountEl=this.container.querySelector(`.${this.classSelector}__selected-count`)),!this.selectedCountEl)return;const t=this.selectedSeats.size;this.selectedCountEl.textContent=this.t("info.seatsSelected",{},t);const e=this.container.querySelector(`.${this.classSelector}__info-btn`);if(e){t>0?(e.classList.