diff --git a/Mundialito/Client/lib/sentry/angular.min.js b/Mundialito/Client/lib/sentry/angular.min.js new file mode 100644 index 0000000..1ce2d84 --- /dev/null +++ b/Mundialito/Client/lib/sentry/angular.min.js @@ -0,0 +1,3 @@ +/*! @sentry/integrations 6.19.7 (5b3a175) | https://github.com/getsentry/sentry-javascript */ +!function(n){var t={},i=function(){return i=Object.assign||function(n){for(var t,i=1,r=arguments.length;i=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")}function u(t,n){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var e,i,o=r.call(t),u=[];try{for(;(void 0===n||n-- >0)&&!(e=o.next()).done;)u.push(e.value)}catch(t){i={error:t}}finally{try{e&&!e.done&&(r=o.return)&&r.call(o)}finally{if(i)throw i.error}}return u}function a(){for(var t=[],n=0;n ".length,a=void 0;r&&i++<5&&!("html"===(a=_(r,n))||i>1&&o+e.length*u+a.length>=80);)e.push(a),o+=a.length,r=r.parentNode;return e.reverse().join(" > ")}catch(t){return""}}function _(t,n){var r,e,i,o,u,a=t,s=[];if(!a||!a.tagName)return"";s.push(a.tagName.toLowerCase());var c=n&&n.length?n.filter((function(t){return a.getAttribute(t)})).map((function(t){return[t,a.getAttribute(t)]})):null;if(c&&c.length)c.forEach((function(t){s.push("["+t[0]+'="'+t[1]+'"]')}));else if(a.id&&s.push("#"+a.id),(r=a.className)&&p(r))for(e=r.split(/\s+/),u=0;u1&&(h=d.slice(0,-1).join("/"),v=d.pop()),v){var l=v.match(/^\d+/);l&&(v=l[0])}return T({host:s,pass:a,path:h,projectId:v,port:f,protocol:e,publicKey:i})}(t):T(t)}var D=["fatal","error","warning","log","info","debug","critical"],N=(c(),["debug","info","warn","error","log","assert"]);function q(t){var n=c();if(!("console"in n))return t();var r=n.console,e={};N.forEach((function(t){var i=r[t]&&r[t].__sentry_original__;t in n.console&&i&&(e[t]=r[t],r[t]=i)}));try{return t()}finally{Object.keys(e).forEach((function(t){r[t]=e[t]}))}}function M(){var t={enable:function(){!0},disable:function(){!1}};return N.forEach((function(n){t[n]=function(){}})),t}function I(t,n){return void 0===n&&(n=0),"string"!=typeof t||0===n||t.length<=n?t:t.substr(0,n)+"..."}function A(t,n){if(!Array.isArray(t))return"";for(var r=[],e=0;e"}var n}function z(t){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n}function B(t,n){void 0===n&&(n=40);var r=Object.keys(X(t));if(r.sort(),!r.length)return"[object has no keys]";if(r[0].length>=n)return I(r[0],n);for(var e=r.length;e>0;e--){var i=r.slice(0,e).join(", ");if(!(i.length>n))return e===r.length?i:I(i,n)}return""}function $(t){var n,r;if(b(t)){var e={};try{for(var i=o(Object.keys(t)),u=i.next();!u.done;u=i.next()){var a=u.value;void 0!==t[a]&&(e[a]=$(t[a]))}}catch(t){n={error:t}}finally{try{u&&!u.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return e}return Array.isArray(t)?t.map($):t}M();function W(t){if(!t.length)return[];var n=t,r=n[0].function||"",e=n[n.length-1].function||"";return-1===r.indexOf("captureMessage")&&-1===r.indexOf("captureException")||(n=n.slice(1)),-1!==e.indexOf("sentryWrapped")&&(n=n.slice(0,-1)),n.slice(0,50).map((function(t){return i(i({},t),{filename:t.filename||n[0].filename,function:t.function||"?"})})).reverse()}var J="";function K(t){try{return t&&"function"==typeof t&&t.name||J}catch(t){return J}}function G(){if(!("fetch"in c()))return!1;try{return new Headers,new Request(""),new Response,!0}catch(t){return!1}}function V(t){return t&&/^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(t.toString())}function Q(){if(!G())return!1;try{return new Request("_",{referrerPolicy:"origin"}),!0}catch(t){return!1}}var Y,Z=c(),tt={},nt={};function rt(t){if(!nt[t])switch(nt[t]=!0,t){case"console":!function(){if(!("console"in Z))return;N.forEach((function(t){t in Z.console&&L(Z.console,t,(function(n){return function(){for(var r=[],e=0;e2?n[2]:void 0;if(e){var i=Y,o=String(e);Y=o,it("history",{from:i,to:o})}return t.apply(this,n)}}Z.onpopstate=function(){for(var n=[],r=0;r":r||""}function pt(t,n,r){var e=t.exception=t.exception||{},i=e.values=e.values||[],o=i[0]=i[0]||{};o.value||(o.value=n||""),o.type||(o.type=r||"Error")}function mt(t,n){var r=lt(t);if(r){var e=r.mechanism;if(r.mechanism=i(i(i({},{type:"generic",handled:!0}),e),n),n&&"data"in n){var o=i(i({},e&&e.data),n.data);r.mechanism.data=o}}}function bt(t){if(t&&t.__sentry_captured__)return!0;try{U(t,"__sentry_captured__",!0)}catch(t){}return!1}function wt(t,n,r){void 0===n&&(n=1/0),void 0===r&&(r=1/0);try{return xt("",t,n,r)}catch(t){return{ERROR:"**non-serializable** ("+t+")"}}}function gt(t,n,r){void 0===n&&(n=3),void 0===r&&(r=102400);var e,i=wt(t,n);return e=i,function(t){return~-encodeURI(t).split(/%..|./).length}(JSON.stringify(e))>r?gt(t,n-1,r):i}function xt(t,n,r,e,i){var o,a;void 0===r&&(r=1/0),void 0===e&&(e=1/0),void 0===i&&(o="function"==typeof WeakSet,a=o?new WeakSet:[],i=[function(t){if(o)return!!a.has(t)||(a.add(t),!1);for(var n=0;n=e){y[g]="[MaxProperties ~]";break}var x=m[g];y[g]=xt(g,x,r-1,e,i),p+=1}return h(n),y}function Et(t){return new St((function(n){n(t)}))}function _t(t){return new St((function(n,r){r(t)}))}var St=function(){function t(t){var n=this;this.i=0,this.o=[],this.u=function(t){n.h(1,t)},this.v=function(t){n.h(2,t)},this.h=function(t,r){0===n.i&&(g(r)?r.then(n.u,n.v):(n.i=t,n.l=r,n.p()))},this.p=function(){if(0!==n.i){var t=n.o.slice();n.o=[],t.forEach((function(t){t[0]||(1===n.i&&t[1](n.l),2===n.i&&t[2](n.l),t[0]=!0)}))}};try{t(this.u,this.v)}catch(t){this.v(t)}}return t.prototype.then=function(n,r){var e=this;return new t((function(t,i){e.o.push([!1,function(r){if(n)try{t(n(r))}catch(t){i(t)}else t(r)},function(n){if(r)try{t(r(n))}catch(t){i(t)}else i(n)}]),e.p()}))},t.prototype.catch=function(t){return this.then((function(t){return t}),t)},t.prototype.finally=function(n){var r=this;return new t((function(t,e){var i,o;return r.then((function(t){o=!1,i=t,n&&n()}),(function(t){o=!0,i=t,n&&n()})).then((function(){o?e(i):t(i)}))}))},t}();function kt(t){var n=[];function r(t){return n.splice(n.indexOf(t),1)[0]}return{$:n,add:function(e){if(!(void 0===t||n.length0&&r(!1)}),t);n.forEach((function(t){Et(t).then((function(){--i||(clearTimeout(o),r(!0))}),e)}))}))}}}function jt(n){return"warn"===n?t.Severity.Warning:function(t){return-1!==D.indexOf(t)}(n)?n:t.Severity.Log}function Ot(t){return t>=200&&t<300?"success":429===t?"rate_limit":t>=400&&t<500?"invalid":t>=500?"failed":"unknown"}var Tt={nowSeconds:function(){return Date.now()/1e3}};var Rt=function(){var t=c().performance;if(t&&t.now)return{now:function(){return t.now()},timeOrigin:Date.now()-t.now()}}(),Dt=void 0===Rt?Tt:{nowSeconds:function(){return(Rt.timeOrigin+Rt.now())/1e3}},Nt=Tt.nowSeconds.bind(Tt),qt=Dt.nowSeconds.bind(Dt);function Mt(t,n){return void 0===n&&(n=[]),[t,n]}function It(t){var n=u(t,2),r=n[0],e=n[1],i=JSON.stringify(r);return e.reduce((function(t,n){var r=u(n,2),e=r[0],i=r[1],o=m(i)?String(i):JSON.stringify(i);return t+"\n"+JSON.stringify(e)+"\n"+o}),i)}!function(){var t=c().performance;if(t&&t.now){var n=36e5,r=t.now(),e=Date.now(),i=t.timeOrigin?Math.abs(t.timeOrigin+r-e):n,o=ir}function Lt(t,n,r){var e,u,a,s;void 0===r&&(r=Date.now());var c=i({},t),f=n["x-sentry-rate-limits"],h=n["retry-after"];if(f)try{for(var v=o(f.trim().split(",")),d=v.next();!d.done;d=v.next()){var l=d.value.split(":",2),y=parseInt(l[0],10),p=1e3*(isNaN(y)?60:y);if(l[1])try{for(var m=(a=void 0,o(l[1].split(";"))),b=m.next();!b.done;b=m.next()){c[b.value]=r+p}}catch(t){a={error:t}}finally{try{b&&!b.done&&(s=m.return)&&s.call(m)}finally{if(a)throw a.error}}else c.all=r+p}}catch(t){e={error:t}}finally{try{d&&!d.done&&(u=v.return)&&u.call(v)}finally{if(e)throw e.error}}else h&&(c.all=r+function(t,n){void 0===n&&(n=Date.now());var r=parseInt(""+t,10);if(!isNaN(r))return 1e3*r;var e=Date.parse(""+t);return isNaN(e)?6e4:e-n}(h,r));return c}var Ut=function(){function t(){this.m=!1,this.g=[],this._=[],this.S=[],this.k={},this.j={},this.O={},this.T={},this.R={}}return t.clone=function(n){var r=new t;return n&&(r.S=a(n.S),r.j=i({},n.j),r.O=i({},n.O),r.T=i({},n.T),r.k=n.k,r.D=n.D,r.N=n.N,r.q=n.q,r.M=n.M,r.I=n.I,r._=a(n._),r.A=n.A),r},t.prototype.addScopeListener=function(t){this.g.push(t)},t.prototype.addEventProcessor=function(t){return this._.push(t),this},t.prototype.setUser=function(t){return this.k=t||{},this.q&&this.q.update({user:t}),this.C(),this},t.prototype.getUser=function(){return this.k},t.prototype.getRequestSession=function(){return this.A},t.prototype.setRequestSession=function(t){return this.A=t,this},t.prototype.setTags=function(t){return this.j=i(i({},this.j),t),this.C(),this},t.prototype.setTag=function(t,n){var r;return this.j=i(i({},this.j),((r={})[t]=n,r)),this.C(),this},t.prototype.setExtras=function(t){return this.O=i(i({},this.O),t),this.C(),this},t.prototype.setExtra=function(t,n){var r;return this.O=i(i({},this.O),((r={})[t]=n,r)),this.C(),this},t.prototype.setFingerprint=function(t){return this.I=t,this.C(),this},t.prototype.setLevel=function(t){return this.D=t,this.C(),this},t.prototype.setTransactionName=function(t){return this.M=t,this.C(),this},t.prototype.setTransaction=function(t){return this.setTransactionName(t)},t.prototype.setContext=function(t,n){var r;return null===n?delete this.T[t]:this.T=i(i({},this.T),((r={})[t]=n,r)),this.C(),this},t.prototype.setSpan=function(t){return this.N=t,this.C(),this},t.prototype.getSpan=function(){return this.N},t.prototype.getTransaction=function(){var t=this.getSpan();return t&&t.transaction},t.prototype.setSession=function(t){return t?this.q=t:delete this.q,this.C(),this},t.prototype.getSession=function(){return this.q},t.prototype.update=function(n){if(!n)return this;if("function"==typeof n){var r=n(this);return r instanceof t?r:this}return n instanceof t?(this.j=i(i({},this.j),n.j),this.O=i(i({},this.O),n.O),this.T=i(i({},this.T),n.T),n.k&&Object.keys(n.k).length&&(this.k=n.k),n.D&&(this.D=n.D),n.I&&(this.I=n.I),n.A&&(this.A=n.A)):b(n)&&(n=n,this.j=i(i({},this.j),n.tags),this.O=i(i({},this.O),n.extra),this.T=i(i({},this.T),n.contexts),n.user&&(this.k=n.user),n.level&&(this.D=n.level),n.fingerprint&&(this.I=n.fingerprint),n.requestSession&&(this.A=n.requestSession)),this},t.prototype.clear=function(){return this.S=[],this.j={},this.O={},this.k={},this.T={},this.D=void 0,this.M=void 0,this.I=void 0,this.A=void 0,this.N=void 0,this.q=void 0,this.C(),this},t.prototype.addBreadcrumb=function(t,n){var r="number"==typeof n?Math.min(n,100):100;if(r<=0)return this;var e=i({timestamp:Nt()},t);return this.S=a(this.S,[e]).slice(-r),this.C(),this},t.prototype.clearBreadcrumbs=function(){return this.S=[],this.C(),this},t.prototype.applyToEvent=function(t,n){if(this.O&&Object.keys(this.O).length&&(t.extra=i(i({},this.O),t.extra)),this.j&&Object.keys(this.j).length&&(t.tags=i(i({},this.j),t.tags)),this.k&&Object.keys(this.k).length&&(t.user=i(i({},this.k),t.user)),this.T&&Object.keys(this.T).length&&(t.contexts=i(i({},this.T),t.contexts)),this.D&&(t.level=this.D),this.M&&(t.transaction=this.M),this.N){t.contexts=i({trace:this.N.getTraceContext()},t.contexts);var r=this.N.transaction&&this.N.transaction.name;r&&(t.tags=i({transaction:r},t.tags))}return this.L(t),t.breadcrumbs=a(t.breadcrumbs||[],this.S),t.breadcrumbs=t.breadcrumbs.length>0?t.breadcrumbs:void 0,t.sdkProcessingMetadata=this.R,this.U(a(Pt(),this._),t,n)},t.prototype.setSDKProcessingMetadata=function(t){return this.R=i(i({},this.R),t),this},t.prototype.U=function(t,n,r,e){var o=this;return void 0===e&&(e=0),new St((function(u,a){var s=t[e];if(null===n||"function"!=typeof s)u(n);else{var c=s(i({},n),r);g(c)?c.then((function(n){return o.U(t,n,r,e+1).then(u)})).then(null,a):o.U(t,c,r,e+1).then(u).then(null,a)}}))},t.prototype.C=function(){var t=this;this.m||(this.m=!0,this.g.forEach((function(n){n(t)})),this.m=!1)},t.prototype.L=function(t){t.fingerprint=t.fingerprint?Array.isArray(t.fingerprint)?t.fingerprint:[t.fingerprint]:[],this.I&&(t.fingerprint=t.fingerprint.concat(this.I)),t.fingerprint&&!t.fingerprint.length&&delete t.fingerprint},t}();function Pt(){return f("globalEventProcessors",(function(){return[]}))}function Ht(t){Pt().push(t)}var Xt=function(){function t(t){this.errors=0,this.sid=vt(),this.duration=0,this.status="ok",this.init=!0,this.ignoreDuration=!1;var n=qt();this.timestamp=n,this.started=n,t&&this.update(t)}return t.prototype.update=function(t){if(void 0===t&&(t={}),t.user&&(!this.ipAddress&&t.user.ip_address&&(this.ipAddress=t.user.ip_address),this.did||t.did||(this.did=t.user.id||t.user.email||t.user.username)),this.timestamp=t.timestamp||qt(),t.ignoreDuration&&(this.ignoreDuration=t.ignoreDuration),t.sid&&(this.sid=32===t.sid.length?t.sid:vt()),void 0!==t.init&&(this.init=t.init),!this.did&&t.did&&(this.did=""+t.did),"number"==typeof t.started&&(this.started=t.started),this.ignoreDuration)this.duration=void 0;else if("number"==typeof t.duration)this.duration=t.duration;else{var n=this.timestamp-this.started;this.duration=n>=0?n:0}t.release&&(this.release=t.release),t.environment&&(this.environment=t.environment),!this.ipAddress&&t.ipAddress&&(this.ipAddress=t.ipAddress),!this.userAgent&&t.userAgent&&(this.userAgent=t.userAgent),"number"==typeof t.errors&&(this.errors=t.errors),t.status&&(this.status=t.status)},t.prototype.close=function(t){t?this.update({status:t}):"ok"===this.status?this.update({status:"exited"}):this.update()},t.prototype.toJSON=function(){return $({sid:""+this.sid,init:this.init,started:new Date(1e3*this.started).toISOString(),timestamp:new Date(1e3*this.timestamp).toISOString(),status:this.status,errors:this.errors,did:"number"==typeof this.did||"string"==typeof this.did?""+this.did:void 0,duration:this.duration,attrs:{release:this.release,environment:this.environment,ip_address:this.ipAddress,user_agent:this.userAgent}})},t}(),Ft=function(){function t(t,n,r){void 0===n&&(n=new Ut),void 0===r&&(r=4),this.P=r,this.H=[{}],this.getStackTop().scope=n,t&&this.bindClient(t)}return t.prototype.isOlderThan=function(t){return this.P=t&&(clearInterval(i),r(!1)))}),1)}))},t.prototype.tt=function(){return this.G},t.prototype.rt=function(){return!1!==this.getOptions().enabled&&void 0!==this.Y},t.prototype.ut=function(t,n,r){var e=this,o=this.getOptions(),u=o.normalizeDepth,a=void 0===u?3:u,s=o.normalizeMaxBreadth,c=void 0===s?1e3:s,f=i(i({},t),{event_id:t.event_id||(r&&r.event_id?r.event_id:vt()),timestamp:t.timestamp||Nt()});this.at(f),this.st(f);var h=n;r&&r.captureContext&&(h=Ut.clone(h).update(r.captureContext));var v=Et(f);return h&&(v=h.applyToEvent(f,r)),v.then((function(t){return t&&(t.sdkProcessingMetadata=i(i({},t.sdkProcessingMetadata),{normalizeDepth:wt(a)+" ("+typeof a+")"})),"number"==typeof a&&a>0?e.ct(t,a,c):t}))},t.prototype.ct=function(t,n,r){if(!t)return null;var e=i(i(i(i(i({},t),t.breadcrumbs&&{breadcrumbs:t.breadcrumbs.map((function(t){return i(i({},t),t.data&&{data:wt(t.data,n,r)})}))}),t.user&&{user:wt(t.user,n,r)}),t.contexts&&{contexts:wt(t.contexts,n,r)}),t.extra&&{extra:wt(t.extra,n,r)});return t.contexts&&t.contexts.trace&&(e.contexts.trace=t.contexts.trace),e.sdkProcessingMetadata=i(i({},e.sdkProcessingMetadata),{baseClientNormalized:!0}),e},t.prototype.at=function(t){var n=this.getOptions(),r=n.environment,e=n.release,i=n.dist,o=n.maxValueLength,u=void 0===o?250:o;"environment"in t||(t.environment="environment"in n?r:"production"),void 0===t.release&&void 0!==e&&(t.release=e),void 0===t.dist&&void 0!==i&&(t.dist=i),t.message&&(t.message=I(t.message,u));var a=t.exception&&t.exception.values&&t.exception.values[0];a&&a.value&&(a.value=I(a.value,u));var s=t.request;s&&s.url&&(s.url=I(s.url,u))},t.prototype.st=function(t){var n=Object.keys(this.J);n.length>0&&(t.sdk=t.sdk||{},t.sdk.integrations=a(t.sdk.integrations||[],n))},t.prototype.ft=function(t){this.tt().sendEvent(t)},t.prototype.nt=function(t,n,r){return this.ht(t,n,r).then((function(t){return t.event_id}),(function(t){}))},t.prototype.ht=function(t,n,r){var e=this,i=this.getOptions(),o=i.beforeSend,u=i.sampleRate,a=this.getTransport();function s(t,n){a.recordLostEvent&&a.recordLostEvent(t,n)}if(!this.rt())return _t(new k("SDK not enabled, will not capture event."));var c="transaction"===t.type;return!c&&"number"==typeof u&&Math.random()>u?(s("sample_rate","event"),_t(new k("Discarding event because it's not included in the random sample (sampling rate = "+u+")"))):this.ut(t,r,n).then((function(r){if(null===r)throw s("event_processor",t.type||"event"),new k("An event processor returned null, will not send event.");return n&&n.data&&!0===n.data.__sentry__||c||!o?r:function(t){var n="`beforeSend` method has to return `null` or a valid event.";if(g(t))return t.then((function(t){if(!b(t)&&null!==t)throw new k(n);return t}),(function(t){throw new k("beforeSend rejected with "+t)}));if(!b(t)&&null!==t)throw new k(n);return t}(o(r,n))})).then((function(n){if(null===n)throw s("before_send",t.type||"event"),new k("`beforeSend` returned `null`, will not send event.");var i=r&&r.getSession&&r.getSession();return!c&&i&&e.ot(i,n),e.ft(n),n})).then(null,(function(t){if(t instanceof k)throw t;throw e.captureException(t,{data:{__sentry__:!0},originalException:t}),new k("Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: "+t)}))},t.prototype.Z=function(t){var n=this;this.K+=1,t.then((function(t){return n.K-=1,t}),(function(t){return n.K-=1,t}))},t}();function an(t){if(t.metadata&&t.metadata.sdk){var n=t.metadata.sdk;return{name:n.name,version:n.version}}}function sn(t,n){return n?(t.sdk=t.sdk||{},t.sdk.name=t.sdk.name||n.name,t.sdk.version=t.sdk.version||n.version,t.sdk.integrations=a(t.sdk.integrations||[],n.integrations||[]),t.sdk.packages=a(t.sdk.packages||[],n.packages||[]),t):t}function cn(t,n){var r=an(n),e="aggregates"in t?"sessions":"session";return[Mt(i(i({sent_at:(new Date).toISOString()},r&&{sdk:r}),!!n.tunnel&&{dsn:O(n.dsn)}),[[{type:e},t]]),e]}var fn=function(){function t(){}return t.prototype.sendEvent=function(t){return Et({reason:"NoopTransport: Event has been skipped because no Dsn is configured.",status:"skipped"})},t.prototype.close=function(t){return Et(!0)},t}(),hn=function(){function t(t){this.V=t,this.vt=this.dt()}return t.prototype.eventFromException=function(t,n){throw new k("Backend has to implement `eventFromException` method")},t.prototype.eventFromMessage=function(t,n,r){throw new k("Backend has to implement `eventFromMessage` method")},t.prototype.sendEvent=function(t){if(this.lt&&this.V.dsn&&this.V._experiments&&this.V._experiments.newTransport){var n=function(t,n){var r=an(n),e=t.type||"event",o=(t.sdkProcessingMetadata||{}).transactionSampling||{},u=o.method,a=o.rate;return sn(t,n.metadata.sdk),t.tags=t.tags||{},t.extra=t.extra||{},t.sdkProcessingMetadata&&t.sdkProcessingMetadata.baseClientNormalized||(t.tags.skippedNormalization=!0,t.extra.normalizeDepth=t.sdkProcessingMetadata?t.sdkProcessingMetadata.normalizeDepth:"unset"),delete t.sdkProcessingMetadata,Mt(i(i({event_id:t.event_id,sent_at:(new Date).toISOString()},r&&{sdk:r}),!!n.tunnel&&{dsn:O(n.dsn)}),[[{type:e,sample_rates:[{id:u,rate:a}]},t]])}(t,Vt(this.V.dsn,this.V.yt,this.V.tunnel));this.lt.send(n).then(null,(function(t){}))}else this.vt.sendEvent(t).then(null,(function(t){}))},t.prototype.sendSession=function(t){if(this.vt.sendSession)if(this.lt&&this.V.dsn&&this.V._experiments&&this.V._experiments.newTransport){var n=u(cn(t,Vt(this.V.dsn,this.V.yt,this.V.tunnel)),1)[0];this.lt.send(n).then(null,(function(t){}))}else this.vt.sendSession(t).then(null,(function(t){}))},t.prototype.getTransport=function(){return this.vt},t.prototype.dt=function(){return new fn},t}();function vn(t,n,r){void 0===r&&(r=kt(t.bufferSize||30));var e={};return{send:function(t){var i=function(t){var n=u(t,2),r=u(n[1],1);return u(r[0],1)[0].type}(t),o="event"===i?"error":i,a={category:o,body:It(t)};return Ct(e,o)?_t({status:"rate_limit",reason:dn(e,o)}):r.add((function(){return n(a).then((function(t){var n=t.body,r=t.headers,i=t.reason,u=Ot(t.statusCode);return r&&(e=Lt(e,r)),"success"===u?Et({status:u,reason:i}):_t({status:u,reason:i||n||("rate_limit"===u?dn(e,o):"Unknown transport error")})}))}))},flush:function(t){return r.drain(t)}}}function dn(t,n){return"Too many "+n+" requests, backing off until: "+new Date(At(t,n)).toISOString()}var ln,yn="6.19.7",pn=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(){ln=Function.prototype.toString,Function.prototype.toString=function(){for(var t=[],n=0;n=0;n--){var r=t[n];if(r&&""!==r.filename&&"[native code]"!==r.filename)return r.filename||null}return null}function gn(t){try{if(t.stacktrace)return wn(t.stacktrace.frames);var n;try{n=t.exception.values[0].stacktrace.frames}catch(t){}return n?wn(n):null}catch(t){return null}}var xn=Object.freeze({__proto__:null,FunctionToString:pn,InboundFilters:bn}),En="?";function _n(t,n,r,e){var i={filename:t,function:n,in_app:!0};return void 0!==r&&(i.lineno=r),void 0!==e&&(i.colno=e),i}var Sn=/^\s*at (?:(.*?) ?\((?:address at )?)?((?:file|https?|blob|chrome-extension|address|native|eval|webpack||[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,kn=/\((\S*)(?::(\d+))(?::(\d+))\)/,jn=[30,function(t){var n=Sn.exec(t);if(n){if(n[2]&&0===n[2].indexOf("eval")){var r=kn.exec(n[2]);r&&(n[2]=r[1],n[3]=r[2],n[4]=r[3])}var e=u(Cn(n[1]||En,n[2]),2),i=e[0];return _n(e[1],i,n[3]?+n[3]:void 0,n[4]?+n[4]:void 0)}}],On=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|capacitor).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i,Tn=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,Rn=[50,function(t){var n,r=On.exec(t);if(r){if(r[3]&&r[3].indexOf(" > eval")>-1){var e=Tn.exec(r[3]);e&&(r[1]=r[1]||"eval",r[3]=e[1],r[4]=e[2],r[5]="")}var i=r[3],o=r[1]||En;return o=(n=u(Cn(o,i),2))[0],_n(i=n[1],o,r[4]?+r[4]:void 0,r[5]?+r[5]:void 0)}}],Dn=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,Nn=[40,function(t){var n=Dn.exec(t);return n?_n(n[2],n[1]||En,+n[3],n[4]?+n[4]:void 0):void 0}],qn=/ line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i,Mn=[10,function(t){var n=qn.exec(t);return n?_n(n[2],n[3]||En,+n[1]):void 0}],In=/ line (\d+), column (\d+)\s*(?:in (?:]+)>|([^)]+))\(.*\))? in (.*):\s*$/i,An=[20,function(t){var n=In.exec(t);return n?_n(n[5],n[3]||n[4]||En,+n[1],+n[2]):void 0}],Cn=function(t,n){var r=-1!==t.indexOf("safari-extension"),e=-1!==t.indexOf("safari-web-extension");return r||e?[-1!==t.indexOf("@")?t.split("@")[0]:En,r?"safari-extension:"+n:"safari-web-extension:"+n]:[t,n]};function Ln(t){var n=Pn(t),r={type:t&&t.name,value:Xn(t)};return n.length&&(r.stacktrace={frames:n}),void 0===r.type&&""===r.value&&(r.value="Unrecoverable error caught"),r}function Un(t){return{exception:{values:[Ln(t)]}}}function Pn(t){var n=t.stacktrace||t.stack||"",r=function(t){if(t){if("number"==typeof t.framesToPop)return t.framesToPop;if(Hn.test(t.message))return 1}return 0}(t);try{return function(){for(var t=[],n=0;n0}function sr(){ur+=1,setTimeout((function(){ur-=1}))}function cr(t,n,r){if(void 0===n&&(n={}),"function"!=typeof t)return t;try{var e=t.__sentry_wrapped__;if(e)return e;if(H(t))return t}catch(n){return t}var sentryWrapped=function(){var e=Array.prototype.slice.call(arguments);try{r&&"function"==typeof r&&r.apply(this,arguments);var o=e.map((function(t){return cr(t,n)}));return t.apply(this,o)}catch(t){throw sr(),Gt((function(r){r.addEventProcessor((function(t){return n.mechanism&&(pt(t,void 0,void 0),mt(t,n.mechanism)),t.extra=i(i({},t.extra),{arguments:e}),t})),captureException(t)})),t}};try{for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(sentryWrapped[o]=t[o])}catch(t){}P(sentryWrapped,t),U(t,"__sentry_wrapped__",sentryWrapped);try{Object.getOwnPropertyDescriptor(sentryWrapped,"name").configurable&&Object.defineProperty(sentryWrapped,"name",{get:function(){return t.name}})}catch(t){}return sentryWrapped}function fr(t){if(void 0===t&&(t={}),or.document&&t.eventId&&t.dsn){var n=or.document.createElement("script");n.async=!0,n.src=function(t,n){var r=R(t),e=Qt(r)+"embed/error-page/",i="dsn="+O(r);for(var o in n)if("dsn"!==o)if("user"===o){if(!n.user)continue;n.user.name&&(i+="&name="+encodeURIComponent(n.user.name)),n.user.email&&(i+="&email="+encodeURIComponent(n.user.email))}else i+="&"+encodeURIComponent(o)+"="+encodeURIComponent(n[o]);return e+"?"+i}(t.dsn,t),t.onLoad&&(n.onload=t.onLoad);var r=or.document.head||or.document.body;r&&r.appendChild(n)}}var hr=function(){function t(n){this.name=t.id,this.Tt={onerror:vr,onunhandledrejection:dr},this.V=i({onerror:!0,onunhandledrejection:!0},n)}return t.prototype.setupOnce=function(){Error.stackTraceLimit=50;var t=this.V;for(var n in t){var r=this.Tt[n];r&&t[n]&&(n,r(),this.Tt[n]=void 0)}},t.id="GlobalHandlers",t}();function vr(){et("error",(function(n){var r=u(pr(),2),e=r[0],i=r[1];if(e.getIntegration(hr)){var o=n.msg,a=n.url,s=n.line,c=n.column,f=n.error;if(!(ar()||f&&f.__sentry_own_request__)){var h=void 0===f&&p(o)?function(t,n,r,e){var i=/^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i,o=l(t)?t.message:t,u="Error",a=o.match(i);a&&(u=a[1],o=a[2]);return lr({exception:{values:[{type:u,value:o}]}},n,r,e)}(o,a,s,c):lr(Bn(f||o,void 0,i,!1),a,s,c);h.level=t.Severity.Error,yr(e,f,h,"onerror")}}}))}function dr(){et("unhandledrejection",(function(n){var r=u(pr(),2),e=r[0],i=r[1];if(e.getIntegration(hr)){var o=n;try{"reason"in n?o=n.reason:"detail"in n&&"reason"in n.detail&&(o=n.detail.reason)}catch(t){}if(ar()||o&&o.__sentry_own_request__)return!0;var a=m(o)?{exception:{values:[{type:"UnhandledRejection",value:"Non-Error promise rejection captured with value: "+String(o)}]}}:Bn(o,void 0,i,!0);a.level=t.Severity.Error,yr(e,o,a,"onunhandledrejection")}}))}function lr(t,n,r,e){var i=t.exception=t.exception||{},o=i.values=i.values||[],u=o[0]=o[0]||{},a=u.stacktrace=u.stacktrace||{},s=a.frames=a.frames||[],f=isNaN(parseInt(e,10))?void 0:e,h=isNaN(parseInt(r,10))?void 0:r,v=p(n)&&n.length>0?n:function(){var t=c();try{return t.document.location.href}catch(t){return""}}();return 0===s.length&&s.push({colno:f,filename:v,function:"?",in_app:!0,lineno:h}),t}function yr(t,n,r,e){mt(r,{handled:!1,type:e}),t.captureEvent(r,{originalException:n})}function pr(){var t=$t(),n=t.getClient();return[t,n&&n.getOptions().attachStacktrace]}var mr=["EventTarget","Window","Node","ApplicationCache","AudioTrackList","ChannelMergerNode","CryptoOperation","EventSource","FileReader","HTMLUnknownElement","IDBDatabase","IDBRequest","IDBTransaction","KeyOperation","MediaController","MessagePort","ModalWindow","Notification","SVGElementInstance","Screen","TextTrack","TextTrackCue","TextTrackList","WebSocket","WebSocketWorker","Worker","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload"],br=function(){function t(n){this.name=t.id,this.V=i({XMLHttpRequest:!0,eventTarget:!0,requestAnimationFrame:!0,setInterval:!0,setTimeout:!0},n)}return t.prototype.setupOnce=function(){var t=c();this.V.setTimeout&&L(t,"setTimeout",wr),this.V.setInterval&&L(t,"setInterval",wr),this.V.requestAnimationFrame&&L(t,"requestAnimationFrame",gr),this.V.XMLHttpRequest&&"XMLHttpRequest"in t&&L(XMLHttpRequest.prototype,"send",xr);var n=this.V.eventTarget;n&&(Array.isArray(n)?n:mr).forEach(Er)},t.id="TryCatch",t}();function wr(t){return function(){for(var n=[],r=0;r"}0!==r.length&&$t().addBreadcrumb({category:"ui."+n.name,message:r},{event:n.event,name:n.name,global:n.global})}return n}(this.V.dom)),this.V.xhr&&et("xhr",kr),this.V.fetch&&et("fetch",jr),this.V.history&&et("history",Or)},t.id="Breadcrumbs",t}();function Sr(t){var n={category:"console",data:{arguments:t.args,logger:"console"},level:jt(t.level),message:A(t.args," ")};if("assert"===t.level){if(!1!==t.args[0])return;n.message="Assertion failed: "+(A(t.args.slice(1)," ")||"console.assert"),n.data.arguments=t.args.slice(1)}$t().addBreadcrumb(n,{input:t.args,level:t.level})}function kr(t){if(t.endTimestamp){if(t.xhr.__sentry_own_request__)return;var n=t.xhr.__sentry_xhr__||{},r=n.method,e=n.url,i=n.status_code,o=n.body;$t().addBreadcrumb({category:"xhr",data:{method:r,url:e,status_code:i},type:"http"},{xhr:t.xhr,input:o})}else;}function jr(n){n.endTimestamp&&(n.fetchData.url.match(/sentry_key/)&&"POST"===n.fetchData.method||(n.error?$t().addBreadcrumb({category:"fetch",data:n.fetchData,level:t.Severity.Error,type:"http"},{data:n.error,input:n.args}):$t().addBreadcrumb({category:"fetch",data:i(i({},n.fetchData),{status_code:n.response.status}),type:"http"},{input:n.args,response:n.response})))}function Or(t){var n=c(),r=t.from,e=t.to,i=dt(n.location.href),o=dt(r),u=dt(e);o.path||(o=i),i.protocol===u.protocol&&i.host===u.host&&(e=u.relative),i.protocol===o.protocol&&i.host===o.host&&(r=o.relative),$t().addBreadcrumb({category:"navigation",data:{from:r,to:e}})}var Tr=function(){function t(n){void 0===n&&(n={}),this.name=t.id,this.Rt=n.key||"cause",this.Dt=n.limit||5}return t.prototype.setupOnce=function(){Ht((function(n,r){var e=$t().getIntegration(t);return e?function(t,n,r,e){if(!(r.exception&&r.exception.values&&e&&x(e.originalException,Error)))return r;var i=Rr(n,e.originalException,t);return r.exception.values=a(i,r.exception.values),r}(e.Rt,e.Dt,n,r):n}))},t.id="LinkedErrors",t}();function Rr(t,n,r,e){if(void 0===e&&(e=[]),!x(n[r],Error)||e.length+1>=t)return e;var i=Ln(n[r]);return Rr(t,n[r],r,a([i],e))}var Dr=c(),Nr=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(){Ht((function(n){if($t().getIntegration(t)){if(!Dr.navigator&&!Dr.location&&!Dr.document)return n;var r=n.request&&n.request.url||Dr.location&&Dr.location.href,e=(Dr.document||{}).referrer,o=(Dr.navigator||{}).userAgent,u=i(i(i({},n.request&&n.request.headers),e&&{Referer:e}),o&&{"User-Agent":o}),a=i(i({},r&&{url:r}),{headers:u});return i(i({},n),{request:a})}return n}))},t.id="UserAgent",t}(),qr=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(n,r){n((function(n){var e=r().getIntegration(t);if(e){try{if(function(t,n){if(!n)return!1;if(function(t,n){var r=t.message,e=n.message;if(!r&&!e)return!1;if(r&&!e||!r&&e)return!1;if(r!==e)return!1;if(!Ir(t,n))return!1;if(!Mr(t,n))return!1;return!0}(t,n))return!0;if(function(t,n){var r=Ar(n),e=Ar(t);if(!r||!e)return!1;if(r.type!==e.type||r.value!==e.value)return!1;if(!Ir(t,n))return!1;if(!Mr(t,n))return!1;return!0}(t,n))return!0;return!1}(n,e.Nt))return null}catch(t){return e.Nt=n}return e.Nt=n}return n}))},t.id="Dedupe",t}();function Mr(t,n){var r=Cr(t),e=Cr(n);if(!r&&!e)return!0;if(r&&!e||!r&&e)return!1;if(r=r,(e=e).length!==r.length)return!1;for(var i=0;i response, + responseError: (response) => { ErrorHandler.handle(response.data, response.status, response.headers, response.config); - + Sentry.captureException(response.data); // do something on error return $q.reject(response); } diff --git a/Mundialito/Client/src/app.js b/Mundialito/Client/src/app.js index 88ab876..ac2e273 100644 --- a/Mundialito/Client/src/app.js +++ b/Mundialito/Client/src/app.js @@ -1,5 +1,5 @@ angular.module('mundialitoApp', ['key-value-editor', 'security', 'ngSanitize', 'ngRoute', 'ngAnimate', 'ui.bootstrap', 'autofields.bootstrap', 'cgBusy', 'ajoslin.promise-tracker', 'ui.select', - 'ui.bootstrap.datetimepicker', 'ui.grid', 'ui.grid.autoResize', 'googlechart', 'toaster', 'ui.grid.saveState', 'ui.grid.resizeColumns','ui.toggle']) + 'ui.bootstrap.datetimepicker', 'ui.grid', 'ui.grid.autoResize', 'googlechart', 'toaster', 'ui.grid.saveState', 'ui.grid.resizeColumns','ui.toggle', 'ngSentry']) .value('cgBusyTemplateName', 'App/Partials/angular-busy.html') .config(['$routeProvider', '$httpProvider', '$locationProvider', '$parseProvider', 'securityProvider', 'Constants', function ($routeProvider, $httpProvider, $locationProvider, $parseProvider, securityProvider, Constants) { $locationProvider.html5Mode(true); diff --git a/Mundialito/Views/Home/Index.cshtml b/Mundialito/Views/Home/Index.cshtml index e3739d3..2613711 100644 --- a/Mundialito/Views/Home/Index.cshtml +++ b/Mundialito/Views/Home/Index.cshtml @@ -9,7 +9,7 @@ @Model.ApplicationName - + @@ -33,6 +33,7 @@ +
@@ -141,16 +142,26 @@
+ + + @if (env.IsProduction()) { - + } else { - + } + + diff --git a/Mundialito/gulpfile.js b/Mundialito/gulpfile.js index 6450100..0cf7b08 100644 --- a/Mundialito/gulpfile.js +++ b/Mundialito/gulpfile.js @@ -101,6 +101,12 @@ gulp.task('copy-templates', function () { .pipe(gulp.dest('wwwroot/')); }); +gulp.task('copy-sentry', function () { + return gulp.src(['Client/lib/sentry/*.js']) + .pipe(gulp.dest('wwwroot/sentry')); +}); + + gulp.task('cache-bust-lib', () => { const libPattern = /^lib-[a-z0-9]+\.js$/; let lib = fs.readdirSync('wwwroot/lib').filter(fileName => { @@ -156,4 +162,4 @@ gulp.task('cache-bust-app-min', () => { gulp.task('clean', () => gulp.src(['wwwroot/js/*.js', 'wwwroot/lib/*.js'], { read: false }) .pipe(clean())); -gulp.task('default', gulp.series(['clean', 'build-css-cerulean', 'build-css-space-lab', 'compress-lib', 'compress-app', 'copy-html', 'copy-templates', 'cache-bust-lib', 'cache-bust-lib-min', 'cache-bust-app', 'cache-bust-app-min'])); +gulp.task('default', gulp.series(['clean', 'build-css-cerulean', 'build-css-space-lab', 'compress-lib', 'compress-app', 'copy-html', 'copy-templates', 'copy-sentry', 'cache-bust-lib', 'cache-bust-lib-min', 'cache-bust-app', 'cache-bust-app-min'])); diff --git a/Mundialito/wwwroot/js/app-d59627e3e8cd8f2d05420f29a89370ce.js b/Mundialito/wwwroot/js/app-d59627e3e8cd8f2d05420f29a89370ce.js new file mode 100644 index 0000000..ab503fc --- /dev/null +++ b/Mundialito/wwwroot/js/app-d59627e3e8cd8f2d05420f29a89370ce.js @@ -0,0 +1,2855 @@ +angular.module('mundialitoApp', ['key-value-editor', 'security', 'ngSanitize', 'ngRoute', 'ngAnimate', 'ui.bootstrap', 'autofields.bootstrap', 'cgBusy', 'ajoslin.promise-tracker', 'ui.select', + 'ui.bootstrap.datetimepicker', 'ui.grid', 'ui.grid.autoResize', 'googlechart', 'toaster', 'ui.grid.saveState', 'ui.grid.resizeColumns','ui.toggle', 'ngSentry']) + .value('cgBusyTemplateName', 'App/Partials/angular-busy.html') + .config(['$routeProvider', '$httpProvider', '$locationProvider', '$parseProvider', 'securityProvider', 'Constants', function ($routeProvider, $httpProvider, $locationProvider, $parseProvider, securityProvider, Constants) { + $locationProvider.html5Mode(true); + $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + $httpProvider.interceptors.push('myHttpInterceptor'); + securityProvider.urls.login = Constants.LOGIN_PATH; + securityProvider.usePopups = false; + + $routeProvider. + when('/', { + templateUrl: 'App/Dashboard/Dashboard.html', + controller: 'DashboardCtrl', + resolve: { + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()], + players: ['PlayersManager', (PlayersManager) => PlayersManager.loadAllPlayers()] + } + }). + when('/bets_center', { + templateUrl: 'App/Bets/BetsCenter.html', + controller: 'BetsCenterCtrl', + resolve: { + games: ['GamesManager', (GamesManager) => GamesManager.loadOpenGames()] + } + }). + when('/users/:username', { + templateUrl: 'App/Users/UserProfile.html', + controller: 'UserProfileCtrl', + resolve: { + profileUser: ['$route', 'UsersManager', ($route, UsersManager) => { + var username = $route.current.params.username; + return UsersManager.getUser(username, true); + }], + userGameBets: ['$route', 'BetsManager', ($route, BetsManager) => { + var username = $route.current.params.username; + return BetsManager.getUserBets(username); + }], + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()], + generalBetsAreOpen: ['GeneralBetsManager', (GeneralBetsManager) => GeneralBetsManager.canSubmtiGeneralBet()], + players: ['PlayersManager', (PlayersManager) => PlayersManager.loadAllPlayers()], + allUsers: ['UsersManager', (UsersManager) => UsersManager.loadAllUsers()] + } + }). + when('/manage_users', { + templateUrl: 'App/Users/ManageApp.html', + controller: 'ManageAppCtrl', + resolve: { + users: ['UsersManager', (UsersManager) => UsersManager.loadAllUsers()], + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()], + generalBets: ['GeneralBetsManager', (GeneralBetsManager) => GeneralBetsManager.loadAllGeneralBets()], + players: ['PlayersManager', (PlayersManager) => PlayersManager.loadAllPlayers()] + } + }). + when('/teams', { + templateUrl: 'App/Teams/Teams.html', + controller: 'TeamsCtrl', + resolve: { + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()] + } + }). + when('/teams/:teamId', { + templateUrl: 'App/Teams/Team.html', + controller: 'TeamCtrl', + resolve: { + team: ['$route', 'TeamsManager', ($route, TeamsManager) => { + var teamId = $route.current.params.teamId; + return TeamsManager.getTeam(teamId); + }], + games: ['$route', 'GamesManager', ($route, GamesManager) => { + var teamId = $route.current.params.teamId; + return GamesManager.getTeamGames(teamId); + }] + } + }). + when('/games/:gameId', { + templateUrl: 'App/Games/Game.html', + controller: 'GameCtrl', + resolve: { + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()], + players: ['PlayersManager', (PlayersManager) => PlayersManager.loadAllPlayers()], + game: ['$route', 'GamesManager', ($route, GamesManager) => { + var gameId = $route.current.params.gameId; + return GamesManager.getGame(gameId); + }], + userBet: ['$route', 'BetsManager', ($route, BetsManager) => { + var gameId = $route.current.params.gameId; + return BetsManager.getUserBetOnGame(gameId); + }] + } + }). + when('/games', { + templateUrl: 'App/Games/Games.html', + controller: 'GamesCtrl', + resolve: { + games: ['GamesManager', (GamesManager) => GamesManager.loadAllGames()], + teams: ['TeamsManager', (TeamsManager) => TeamsManager.loadAllTeams()] + } + }). + when('/stadiums/:stadiumId', { + templateUrl: 'App/Stadiums/Stadium.html', + controller: 'StadiumCtrl', + resolve: { + stadium: ['$q', '$route', 'StadiumsManager', (_$q, $route, StadiumsManager) => { + var stadiumId = $route.current.params.stadiumId; + return StadiumsManager.getStadium(stadiumId, true); + }] + } + }). + when('/stadiums', { + templateUrl: 'App/Stadiums/Stadiums.html', + controller: 'StadiumsCtrl', + resolve: { + stadiums: ['StadiumsManager', (StadiumsManager) => StadiumsManager.loadAllStadiums()] + } + }). + when('/login', { + templateUrl: 'App/Accounts/Login.html' + }). + when('/forgot', { + templateUrl: 'App/Accounts/ForgetPassword.html', + controller: 'ForgetPasswordCtrl', + }). + when('/reset', { + templateUrl: 'App/Accounts/ResetPassword.html', + controller: 'ResetPasswordCtrl', + }). + when('/join', { + templateUrl: 'App/Accounts/Register.html' + }). + when('/manage', { + templateUrl: 'App/Accounts/Manage.html' + }). + otherwise({ + redirectTo: '/' + }); + }]) + .run(['$rootScope', '$log', 'security', '$route', '$location', 'PluginsProvider', 'FootballDataGamePlugin', 'FootballDataTeamStatsPlugin', function ($rootScope, $log, security, $route, $location, PluginsProvider, FootballDataGamePlugin, FootballDataTeamStatsPlugin) { + PluginsProvider.registerGameFactory(FootballDataGamePlugin); + PluginsProvider.registerTeamFactory(FootballDataTeamStatsPlugin); + security.events.login = function (security, user) { + $log.log('Current user details: ' + angular.toJson(user)); + $rootScope.mundialitoApp.authenticating = false; + }; + security.events.reloadUser = function (security, user) { + $log.log('User reloaded' + angular.toJson(user)); + $rootScope.mundialitoApp.authenticating = false; + }; + security.events.logout = function (security) { + $log.log('User logged out'); + security.authenticate(); + }; + $rootScope.mundialitoApp = { + params: null, + loading: true, + authenticating: true, + message: null + }; + if (!['/reset', '/forgot', '/join', '/login'].includes($location.$$path)) { + $log.log('Starting authentication') + security.authenticate(); + } + $rootScope.security = security; + + $rootScope.$on('$locationChangeStart', function () { + $log.debug('$locationChangeStart'); + $rootScope.mundialitoApp.loading = true; + }); + $rootScope.$on('$locationChangeSuccess', function () { + $log.debug('$locationChangeSuccess'); + $rootScope.mundialitoApp.params = angular.copy($route.current.params); + $rootScope.mundialitoApp.loading = false; + }); + + $rootScope.$on('$routeChangeStart', function () { + $log.debug('$routeChangeStart'); + $rootScope.mundialitoApp.message = 'Loading...'; + }); + $rootScope.$on('$routeChangeSuccess', function () { + $log.debug('$routeChangeSuccess'); + $rootScope.mundialitoApp.message = null; + }); + + }]); +angular.module('mundialitoApp').constant('Constants', + { + LOGIN_PATH: '/login', + REFRESH_TIME: 300000, + TABLE_GRID_OPTIONS: { + saveWidths: true, + saveVisible: true, + saveOrder: true, + enableRowSelection: false, + enableSelectAll: false, + multiSelect: false, + rowTemplate: '
', + columnDefs: [ + { field: 'Place', displayName: '', resizable: false, maxWidth: 30 }, + { field: 'Name', displayName: 'Name', resizable: true, minWidth: 115 }, + { field: 'Points', displayName: 'Points', resizable: true, minWidth: 45, maxWidth: 75}, + { field: 'GeneralBet.WinningTeam', displayName: 'Team', resizable: false, maxWidth: 45, cellTemplate: '
' }, + { field: 'GeneralBet.GoldenBootPlayer.Name', displayName: 'Player', resizable: false, minWidth: 50, maxWidth: 50, cellTemplate: '
{{COL_FIELD.split(\' \')[0].charAt(0)}}.{{COL_FIELD.split(\' \')[1].charAt(0)}}
' }, + { field: 'Marks', displayName: 'Marks', resizable: true }, + { field: 'Results', displayName: 'Results', resizable: true }, + { field: 'YellowCards', displayName: 'Yellow Cards Marks', maxWidth: 55, resizable: false, headerCellTemplate: '
' }, + { field: 'Corners', displayName: 'Corners Marks', maxWidth: 55, resizable: false, headerCellTemplate: '
' },, + { field: 'PlaceDiff', displayName: '', resizable: false, maxWidth: 45, cellTemplate: '
{{::COL_FIELD}}
' } + ], + } + } +); +'use strict'; +angular.module('mundialitoApp').controller('ForgetPasswordCtrl', ['$scope', '$rootScope', 'security', 'Alert', function ($scope, $rootScope, Security, Alert) { + $rootScope.mundialitoApp.authenticating = false; + + var ForgetModel = function () { + return { + Email: '' + } + }; + + $scope.user = new ForgetModel(); + $scope.forget = function () { + if (!$scope.emailForm.$valid) return; + $rootScope.mundialitoApp.message = "Processing..."; + Security.forgotPassword(angular.copy($scope.user)).then(() => { + Alert.success('Reset password token was sent to your email, please follow the link from there'); + }).catch((e) => { + Alert.error('Failed to generate reset password token: ' + e); + }).finally(function () { + $rootScope.mundialitoApp.message = null; + }); + } + $scope.schema = [ + { property: 'Email', label: 'Email Address', type: 'email', attr: { required: true } }, + ]; +}]); +'use strict'; +angular.module('mundialitoApp').controller('LoginCtrl', ['$scope', '$rootScope' , 'security', function ($scope, $rootScope, Security) { + $rootScope.mundialitoApp.authenticating = false; + + var LoginModel = function () { + return { + username: '', + password: '', + rememberMe: false + } + }; + + $scope.user = new LoginModel(); + $scope.login = () => { + if (!$scope.loginForm.$valid) return; + $rootScope.mundialitoApp.message = "Processing Login..."; + Security.login(angular.copy($scope.user)).finally(function () { + $rootScope.mundialitoApp.message = null; + }); + } + $scope.schema = [ + { property: 'username', type: 'text', attr: { ngMinlength: 4, required: true } }, + { property: 'password', type: 'password', attr: { ngMinlength: 4, required: true } }, + { property: 'rememberMe', label: 'Keep me logged in', type: 'checkbox' } + ]; + + window.login = (response) => { + console.log('Got response from Google: ' + response); + $rootScope.mundialitoApp.message = "Processing Login..."; + Security.googleLogin(response).finally(function () { + $rootScope.mundialitoApp.message = null; + }); + } + + window.onload = function () { + google.accounts.id.initialize({ + client_id: $scope.mundialitoApp.GoogleClientId, + callback: login + }); + google.accounts.id.renderButton( + document.getElementById("buttonDiv"), + { theme: "filled_blue", size: "large", text: "continue_with", shape: "circle" } // customization attributes + ); + google.accounts.id.prompt(); // also display the One Tap dialog + } + +}]); +'use strict'; +angular.module('mundialitoApp').controller('ManageCtrl', ['$scope','Alert', function ($scope, Alert) { + var ChangePasswordModel = function () { + return { + oldPassword: '', + newPassword: '', + confirmPassword: '' + } + }; + + $scope.changingPassword = null; + $scope.changePassword = function () { + $scope.changingPassword = new ChangePasswordModel(); + } + $scope.cancel = function () { + $scope.changingPassword = null; + } + $scope.updatePassword = function () { + if (!$scope.manageForm.$valid) return; + var newPassword = angular.copy($scope.changingPassword); + $scope.changingPassword = null; + $scope.security.changePassword(newPassword).then(function () { + Alert.success("Password was changed sucessfully"); + }, function () { + Alert.error("Failed to change password"); + $scope.changingPassword = newPassword; + }); + } + $scope.changePasswordSchema = [ + { property: 'oldPassword', type: 'password', attr: { required: true } }, + { property: 'newPassword', type: 'password', attr: { ngMinlength: 4, required: true } }, + { property: 'confirmPassword', type: 'password', attr: { confirmPassword: 'changingPassword.newPassword', required: true } } + ]; +}]); +'use strict'; +angular.module('mundialitoApp').controller('RegisterCtrl', ['$scope', 'security', function ($scope, Security) { + $scope.mundialitoApp.authenticating = false; + + var User = function () { + return { + firstname: '', + lastname: '', + email: '', + username: '', + password: '', + confirmPassword: '' + } + } + + $scope.user = new User(); + $scope.join = function () { + if (!$scope.joinForm.$valid) return; + $scope.isJoinActive = true; + $scope.mundialitoApp.message = "Processing Registration..."; + Security.register(angular.copy($scope.user)).finally(function () { + $scope.mundialitoApp.message = null; + $scope.isJoinActive = false; + }); + }; + + $scope.schema = [ + { property: 'firstname', label: 'First Name', type: 'text', attr: { required: true } }, + { property: 'lastname', label: 'Last Name', type: 'text', attr: { required: true } }, + { property: 'email', label: 'Email Address', type: 'email', attr: { required: true } }, + { property: 'username', type: 'text', attr: { ngMinlength: 4, required: true } }, + { property: 'password', type: 'password', attr: { required: true } }, + { property: 'confirmPassword', label: 'Confirm Password', type: 'password', attr: { confirmPassword: 'user.password', required: true } } + ]; + +}]); +'use strict'; +angular.module('mundialitoApp').controller('ResetPasswordCtrl', ['$scope', '$rootScope', 'security', '$location', 'Alert', function ($scope, $rootScope, Security, $location, Alert) { + $rootScope.mundialitoApp.authenticating = false; + + var ResetPasswordModel = function () { + return { + confirmPassword: '', + password: '', + email: $location.search()['email'], + token: $location.search()['token'] + } + }; + + $scope.user = new ResetPasswordModel(); + $scope.reset = function () { + if (!$scope.resetForm.$valid) return; + $rootScope.mundialitoApp.message = "Processing Reset Password..."; + Security.resetPassword(angular.copy($scope.user)).then(() => { + Alert.success('Your was was reset successfully'); + }).finally(function () { + $rootScope.mundialitoApp.message = null; + }); + + } + $scope.schema = [ + { property: 'password', type: 'password', attr: { required: true } }, + { property: 'confirmPassword', label: 'Confirm Password', type: 'password', attr: { confirmPassword: 'user.password', required: true } } + ]; +}]); +'use strict'; +angular.module('mundialitoApp').factory('Bet', ['$http','$log', function($http,$log) { + function Bet(betData) { + if (betData) { + this.setData(betData); + } + // Some other initializations related to bet + }; + + Bet.prototype = { + setData: function(betData) { + angular.extend(this, betData); + }, + getTeamByCornersMark: function() { + if (this.CornersMark === '1') { + return this.Game.HomeTeam; + } + if (this.CornersMark === '2') { + return this.Game.AwayTeam; + } + return null; + }, + getTeamByCardsMark: function() { + if (this.CardsMark === '1') { + return this.Game.HomeTeam; + } + if (this.CardsMark === '2') { + return this.Game.AwayTeam; + } + return null; + }, + update: function() { + $log.debug('Bet: Will update bet ' + this.BetId) + return $http.put('api/bets/' + this.BetId, this, { tracker: 'updateBet' }); + }, + getGameUrl: function() { + return '/games/' + this.Game.GameId; + }, + getClass: function() { + if (this.Points >= 7) { + return 'success'; + } + if (this.Points >= 5) { + return 'primary'; + } + if (this.Points >= 3) { + return 'info'; + } + if (this.Points > 0) { + return 'warning'; + } + return 'danger'; + } + }; + return Bet; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('BetsCenterCtrl', ['$scope', '$log', '$timeout', 'Alert', 'BetsManager', 'games', function ($scope, $log, $timeout, Alert, BetsManager, games) { + $scope.games = games; + $scope.bets = {}; + + + var loadUserBets = function() { + if (!angular.isDefined($scope.security.user) || ($scope.security.user == null)) + { + $log.debug('BetsCenterCtrl: user info not loaded yet, will retry in 1 second'); + $timeout(loadUserBets,1000); + } + else { + $scope.getUserBetsPromise = BetsManager.getUserBets($scope.security.user.Username).then((bets) => { + for (var i = 0; i < bets.length; i++) { + $scope.bets[bets[i].Game.GameId] = bets[i]; + $scope.bets[bets[i].Game.GameId].GameId = bets[i].Game.GameId; + } + + for (var j = 0; j < games.length; j++) { + if (!angular.isDefined($scope.bets[games[j].GameId])) { + $log.debug('BetsCenterCtrl: game ' + games[j].GameId + ' has not bet'); + $scope.bets[games[j].GameId] = { BetId: -1, GameId: games[j].GameId }; + } + else { + $scope.bets[$scope.bets[games[j].GameId]] = bets[i]; + } + } + }); + } + }; + + loadUserBets(); + + $scope.updateBet = function(gameId) { + if ($scope.bets[gameId].BetId !== -1) { + $log.debug('BetsCenterCtrl: Will update bet'); + $scope.bets[gameId].update().then((data) => { + Alert.success('Bet was updated successfully'); + BetsManager.setBet(data); + }).catch(function () { + Alert.error('Failed to update Bet, please try again'); + }); + } + else { + $log.debug('BetsCenterCtrl: Will create new bet'); + BetsManager.addBet($scope.bets[gameId]).then(function(data) { + $log.log('BetsCenterCtrl: Bet ' + data.BetId + ' was added'); + $scope.bets[gameId] = data; + Alert.success('Bet was added successfully'); + }).catch(function () { + Alert.error('Failed to add Bet, please try again'); + }); + } + }; + $scope.shuffleBet = function(gameId) { + var homeGoals, awayGoals; + var toto = ['1', 'X', '2']; + var goals = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5]; + var gameMark = toto[Math.floor((Math.random() * 3))]; + do { + homeGoals = goals[Math.floor((Math.random() * goals.length))]; + awayGoals = goals[Math.floor((Math.random() * goals.length))]; + } while (gameMark !== 'X' && homeGoals === awayGoals); + $log.debug('Random game mark is ' + gameMark); + if (gameMark === 'X') { + awayGoals = homeGoals; + } + $log.debug('Home goals: ' + homeGoals); + $log.debug('Away goals: ' + awayGoals); + $scope.bets[gameId].HomeScore = homeGoals; + $scope.bets[gameId].AwayScore = awayGoals + $scope.bets[gameId].CardsMark = toto[Math.floor((Math.random() * 3))]; + $scope.bets[gameId].CornersMark = toto[Math.floor((Math.random() * 3))]; + }; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('BetsManager', ['$http', '$q', 'Bet', '$log', 'MundialitoUtils', 'GamesManager', function ($http, $q, Bet, $log, MundialitoUtils, GamesManager) { + var betsManager = { + _pool: {}, + _retrieveInstance: function(betId, betData) { + var instance = this._pool[betId]; + + if (instance) { + $log.debug('BetsManager: updating existing instance of bet ' + betId); + instance.setData(betData); + } else { + $log.debug('BetsManager: saving new instance of bet ' + betId); + instance = new Bet(betData); + this._pool[betId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function(betId) { + $log.debug('BetsManager: will fetch bet ' + betId + ' from local pool'); + var instance = this._pool[betId]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('BetsManager: Instance was loaded at ' + instance.LoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function(betId, deferred) { + var scope = this; + $log.debug('BetsManager: will fetch bet ' + betId + ' from server'); + $http.get('api/bets/' + betId, { tracker: 'getBet' }) + .then((betData) => { + var bet = scope._retrieveInstance(betData.data.BetId, betData.data); + deferred.resolve(bet); + }) + .catch(() => { + deferred.reject(); + }); + }, + + /* Public Methods */ + /* Use this function in order to add a new bet */ + addBet: function(betData) { + var deferred = $q.defer(); + var scope = this; + $log.debug('BetsManager: will add new bet - ' + angular.toJson(betData)); + $http.post('api/bets/', betData, { tracker: 'addBetOnGame' }).then((data) => { + var bet = scope._retrieveInstance(data.data.BetId, data.data); + deferred.resolve(bet); + }).catch((err) => { + $log.error('Failed to add bet'); + deferred.reject(err); + }); + return deferred.promise; + }, + + /* Use this function in order to get a bet instance by it's id */ + getBet: function(betId,fresh) { + var deferred = $q.defer(); + var bet = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + bet = this._search(betId); + } + if (bet) { + deferred.resolve(bet); + } else { + this._load(betId, deferred); + } + return deferred.promise; + }, + + /* Use this function in order to get instances of all the game bets */ + getGameBets: function(gameId) { + var deferred = $q.defer(); + var scope = this; + $log.debug('BetsManager: will fetch all bets of game ' + gameId + ' from server'); + $http.get('api/games/' + gameId + '/bets', { tracker: 'getGameBets' }) + .then((betsArray) => { + var bets = []; + betsArray.data.forEach((betData) => { + var bet = scope._retrieveInstance(betData.BetId, betData); + bets.push(bet); + }); + + deferred.resolve(bets); + }) + .catch(function() { + deferred.reject(); + }); + return deferred.promise; + }, + + getUserBets : function(username) { + var deferred = $q.defer(); + var scope = this; + $log.debug('BetsManager: will fetch user ' + username +' bets from server'); + $http.get('api/bets/user/' + username, { tracker: 'getUserBets' }) + .then((betsArray) => { + var bets = []; + betsArray.data.forEach((betData) => { + var bet = scope._retrieveInstance(betData.BetId, betData); + bets.push(bet); + }); + + deferred.resolve(bets); + }) + .catch(function() { + deferred.reject(); + }); + return deferred.promise; + }, + + getUserBetOnGame : function(gameId) { + var deferred = $q.defer(); + var scope = this; + $log.debug('BetsManager: will fetch user bet of game ' + gameId + ' from server'); + $http.get('api/games/' + gameId + '/mybet', { tracker: 'getUserBetOnGame' }) + .then((betData) => { + if (betData.data.BetId != -1) { + var bet = scope._retrieveInstance(betData.data.BetId, betData.data); + deferred.resolve(bet); + } + deferred.resolve(betData.data); + }) + .catch(() => { + deferred.reject(); + }); + return deferred.promise; + }, + + /* This function is useful when we got somehow the bet data and we wish to store it or update the pool and get a general bet instance in return */ + setBet: function(betData) { + $log.debug('BetsManager: will set bet ' + betData.BetId + ' to -' + angular.toJson(betData)); + var scope = this; + var bet = this._search(betData.BetId); + if (bet) { + bet.setData(betData); + } else { + bet = scope._retrieveInstance(betData.BetId, betData); + } + return bet; + } + + }; + return betsManager; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('DashboardCtrl', ['$scope', '$log', 'Constants', '$location', '$timeout', 'GamesManager', 'UsersManager', 'GeneralBetsManager', 'teams', 'players', 'BetsManager', 'MundialitoUtils', + function ($scope, $log, Constants, $location, $timeout, GamesManager, UsersManager, GeneralBetsManager, teams, players, BetsManager, MundialitoUtils) { + $scope.generalBetsAreOpen = false; + $scope.submittedGeneralBet = true; + $scope.pendingUpdateGames = false; + $scope.oneAtATime = true; + $scope.status = {}; + $scope.toggleValue = {}; + $scope.players = players; + + $scope.changed = (game) => { + if ($scope.toggleValue[game.GameId]) { + $scope.selectedDic[game.GameId] = $scope.marksDic[game.GameId]; + $scope.selectedPercentage[game.GameId] = $scope.marksPercentage[game.GameId]; + } else { + $scope.selectedDic[game.GameId] = $scope.resultsDic[game.GameId]; + $scope.selectedPercentage[game.GameId] = $scope.resultsPercentage[game.GameId]; + } + } + + $scope.getGamesPromise = GamesManager.loadAllGames().then((games) => { + $scope.games = games; + $scope.resultsDic = {}; + $scope.marksDic = {}; + $scope.selectedDic = {}; + $scope.resultsPercentage = {}; + $scope.marksPercentage = {}; + $scope.selectedPercentage = {}; + $scope.pendingUpdateGames = _.findWhere($scope.games, { IsPendingUpdate: true }) !== undefined; + $scope.pendingUpdateGamesFolloweesBets = {}; + $log.info('DashboardCtrl: followees:' + $scope.security.user.Followees); + _.filter($scope.games, (game) => game.IsPendingUpdate).forEach(game => { + BetsManager.getGameBets(game.GameId).then((data) => { + let resulsGrouped = _.groupBy(data, (bet) => { return bet.HomeScore + "-" + bet.AwayScore }); + let marksGrouped = _.groupBy(data, (bet) => { + if (bet.HomeScore === bet.AwayScore) { + return 'X'; + } + if (bet.HomeScore > bet.AwayScore) { + return bet.Game.HomeTeam.ShortName; + } + return bet.Game.AwayTeam.ShortName; + }); + $scope.resultsDic[game.GameId] = Object.entries(resulsGrouped).sort((a, b) => b[1].length - a[1].length); + $scope.marksDic[game.GameId] = Object.entries(marksGrouped).sort((a, b) => b[1].length - a[1].length); + $scope.resultsPercentage[game.GameId] = {} + $scope.resultsDic[game.GameId].forEach(resItem => { + $scope.resultsPercentage[game.GameId][resItem[0]] = Math.round((resItem[1].length / data.length) * 100); + }); + $scope.marksPercentage[game.GameId] = {} + $scope.marksDic[game.GameId].forEach(markItem => { + $scope.marksPercentage[game.GameId][markItem[0]] = Math.round((markItem[1].length / data.length) * 100); + }); + let followeesBets = _.filter(data, (bet) => { + return $scope.security.user.Followees.includes(bet.User.Username) || $scope.security.user.Username === bet.User.Username; + }); + $scope.pendingUpdateGamesFolloweesBets[game.GameId] = followeesBets; + $scope.changed(game); + }); + }); + }); + + var userHasGeneralBet = () => { + if (!angular.isDefined($scope.security.user) || ($scope.security.user == null)) { + $log.debug('DashboardCtrl: user info not loaded yet, will retry in 1 second'); + $timeout(userHasGeneralBet, 1000); + } + else { + GeneralBetsManager.hasGeneralBet($scope.security.user.Username).then((data) => { + $scope.submittedGeneralBet = data === true; + }); + } + }; + userHasGeneralBet(); + GeneralBetsManager.canSubmtiGeneralBet().then((data) => { + $scope.generalBetsAreOpen = (data === true); + if (!$scope.generalBetsAreOpen) { + GeneralBetsManager.loadAllGeneralBets().then(function (data) { + $scope.generalBets = data; + $scope.winningTeams = {}; + $scope.winningPlayers = {}; + for (var i = 0; i < $scope.generalBets.length; i++) { + if (!angular.isDefined($scope.winningTeams[$scope.generalBets[i].WinningTeam.Name])) { + $scope.winningTeams[$scope.generalBets[i].WinningTeam.Name] = 0; + } + $scope.winningTeams[$scope.generalBets[i].WinningTeam.Name] += 1; + if (!angular.isDefined($scope.winningPlayers[$scope.generalBets[i].GoldenBootPlayer.Name])) { + $scope.winningPlayers[$scope.generalBets[i].GoldenBootPlayer.Name] = 0; + } + $scope.winningPlayers[$scope.generalBets[i].GoldenBootPlayer.Name] += 1; + } + + var chart1 = {}; + chart1.type = "PieChart"; + chart1.options = { + displayExactValues: true, + is3D: true, + backgroundColor: { fill: 'transparent' }, + chartArea: { left: 10, top: 20, bottom: 0, height: "100%" }, + title: 'Winning Team Bets Distribution' + }; + chart1.data = [ + ['Team', 'Number Of Users'] + ]; + for (var team in $scope.winningTeams) { + chart1.data.push([team, $scope.winningTeams[team]]); + } + $scope.chart = chart1; + chart1 = {}; + chart1.type = "PieChart"; + chart1.options = { + displayExactValues: true, + is3D: true, + backgroundColor: { fill: 'transparent' }, + chartArea: { left: 10, top: 20, bottom: 0, height: "100%" }, + title: 'Winning Golden Boot Player Bets Distribution' + }; + chart1.data = [ + ['Player', 'Number Of Users'] + ]; + for (var player in $scope.winningPlayers) { + chart1.data.push([player, $scope.winningPlayers[player]]); + } + $scope.playersChart = chart1; + }); + } + }); + $scope.getUsersPromise = UsersManager.loadAllUsers().then((users) => { + $scope.users = users; + $scope.usersDic = users.reduce((acc, item) => { + acc[item.Id] = item; + return acc; + }, {}); + }); + $scope.isOpenForBetting = (item) => item.IsOpen; + $scope.isPendingUpdate = (item) => item.IsPendingUpdate; + $scope.isDecided = function (item) { + return !item.IsOpen && !item.IsPendingUpdate; + }; + $scope.isGameBet = (game) => (item) => item.Game.GameId === game.GameId; + $scope.hasBets = (game) => $scope.pendingUpdateGamesFolloweesBets[game.GameId] !== undefined && $scope.pendingUpdateGamesFolloweesBets[game.GameId].length > 0 + $scope.gridOptions = { + ...Constants.TABLE_GRID_OPTIONS, ...{ + data: 'users', + onRegisterApi: (gridApi) => { + $scope.gridApi = gridApi; + $scope.gridApi.colResizable.on.columnSizeChanged($scope, saveState); + $scope.gridApi.core.on.columnVisibilityChanged($scope, saveState); + $scope.gridApi.core.on.sortChanged($scope, saveState); + } + } + }; + + function saveState() { + var state = $scope.gridApi.saveState.save(); + localStorage.setItem('gridState', state); + }; + + function restoreState() { + $timeout(() => { + var state = localStorage.getItem('gridState'); + if (state) $scope.gridApi.saveState.restore($scope, state); + }); + }; + $scope.getTableHeight = () => { + var rowHeight = 30; + var headerHeight = 30; + var total = (($scope.users ? $scope.users.length : 0) * rowHeight + headerHeight); + $log.debug('Total Height: ' + total); + return { + height: total + "px" + }; + }; + $scope.goToUser = (rowItem) => { + $location.path(rowItem.entity.getUrl()); + }; + }]); + +'use strict'; +angular.module('mundialitoApp').factory('Game', ['$http','$log', function($http,$log) { + function Game(gameData) { + if (gameData) { + this.setData(gameData); + } + // Some other initializations related to game + }; + + Game.prototype = { + setData: function(gameData) { + angular.extend(this, gameData); + }, + delete: function() { + if (confirm('Are you sure you would like to delete game ' + this.GameId)) { + $log.debug('Game: Will delete game ' + this.GameId) + return $http.delete("api/games/" + this.GameId, { tracker: 'deleteGame' }); + } + }, + update: function() { + $log.debug('Game: Will update game ' + this.GameId) + return $http.put("api/games/" + this.GameId, this, { tracker: 'editGame' }); + }, + getUrl: function() { + return '/games/' + this.GameId; + } + }; + return Game; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('GameCtrl', ['$scope', '$log', 'Constants', 'UsersManager', 'GamesManager', 'BetsManager', 'game', 'userBet', 'Alert', '$location', 'PluginsProvider', 'keyValueEditorUtils', 'MundialitoUtils', 'teams', 'players', function ($scope, $log, Constants, UsersManager, GamesManager, BetsManager, game, userBet, Alert, $location, PluginsProvider, keyValueEditorUtils, MundialitoUtils, teams, players) { + $scope.game = game; + $scope.teamsDic = {}; + $scope.playersDic = {}; + $scope.simulatedGame = {}; + $scope.plugins = {}; + $scope.userBet = userBet; + $scope.userBet.GameId = game.GameId; + $scope.showEditForm = false; + $scope.toKeyValue = (object) => { + return _.keys(object).map((key) => { return { 'name': key, 'value': object[key] } }); + }; + $scope.integrationsData = $scope.toKeyValue($scope.game.IntegrationsData); + for (var i = 0; i < teams.length; i++) { + $scope.teamsDic[teams[i].TeamId] = teams[i]; + } + for (var i = 0; i < players.length; i++) { + $scope.playersDic[players[i].PlayerId] = players[i]; + } + PluginsProvider.getGameDetailsFromAll($scope.game).then((results) => { + results.forEach((result) => { + $scope.plugins[result.property] = { data: result.data, template: result.template }; + }); + }); + + if (!$scope.game.IsOpen) { + $scope.getGameBetsPromsie = BetsManager.getGameBets($scope.game.GameId).then((data) => { + $log.debug("GameCtrl: get game bets" + angular.toJson(data)); + $scope.gameBets = data; + var chart1 = {}; + chart1.type = "PieChart"; + chart1.options = { + displayExactValues: true, + is3D: true, + backgroundColor: { fill: 'transparent' }, + chartArea: { left: 10, top: 20, bottom: 0, height: "100%" }, + title: 'Bets Distribution' + }; + var mark1 = _.filter(data, function (bet) { return bet.HomeScore > bet.AwayScore; }).length; + var markX = _.filter(data, function (bet) { return bet.HomeScore === bet.AwayScore; }).length; + var mark2 = _.filter(data, function (bet) { return bet.HomeScore < bet.AwayScore; }).length; + chart1.data = [ + ['Game Mark', 'Number Of Users'], + ['1', mark1], + ['X', markX], + ['2', mark2] + ]; + $scope.chart = chart1; + $scope.getUsersPromise = UsersManager.loadAllUsers().then((users) => { + $scope.usersMap = new Map(); + users.forEach((obj) => { + $scope.usersMap.set(obj.Username, obj); + }); + let followeesUsers = _.chain(users).filter((user) => $scope.security.user.Followees.includes(user.Username)).pluck('Username').value(); + $scope.followeesBets = _.filter($scope.gameBets, (bet) => followeesUsers.includes(bet.User.Username)); + let topUsers = _.chain(users).first(3).pluck('Username').value(); + $scope.top3UsersBets = _.filter($scope.gameBets, (bet) => topUsers.includes(bet.User.Username)); + let myPlace = 0; + users.forEach((user, place) => { + if (user.Username === $scope.security.user.Username) { + myPlace = place; + } + }); + let lowIndex = Math.max(myPlace - 3, 0); + let upperIndex = Math.min(myPlace + 3, users.length); + let neighbors = _.chain(users.slice(lowIndex, upperIndex + 1)) + .pluck('Username').filter((user) => user !== $scope.security.user.Username).value(); + $scope.neighborsBets = _.filter($scope.gameBets, (bet) => neighbors.includes(bet.User.Username)); + }); + }); + } + + $scope.updateGame = () => { + if ((angular.isDefined(game.Stadium.Games)) && (game.Stadium.Games != null)) { + delete game.Stadium.Games; + } + $scope.game.IntegrationsData = keyValueEditorUtils.mapEntries(keyValueEditorUtils.compactEntries($scope.integrationsData)); + $scope.updateGamePromise = $scope.game.update().then((res) => { + Alert.success('Game was updated successfully'); + GamesManager.setGame(res.data); + }).catch((err) => { + Alert.error('Failed to update game, please try again'); + $log.error('Error updating game', err); + }); + }; + + $scope.updateBet = () => { + if ($scope.userBet.BetId !== -1) { + $scope.updateBetPromise = $scope.userBet.update().then((data) => { + Alert.success('Bet was updated successfully'); + BetsManager.setBet(data); + }).catch((err) => { + Alert.error('Failed to update bet, please try again'); + $log.error('Error updating bet', err); + }); + } + else { + BetsManager.addBet($scope.userBet).then((data) => { + $log.log('GameCtrl: Bet ' + data.BetId + ' was added'); + $scope.userBet = data; + Alert.success('Bet was added successfully'); + }, (err) => { + Alert.error('Failed to add bet, please try again'); + $log.error('Error adding bet', err); + }); + } + }; + + $scope.simulateGame = () => { + $log.debug('GameCtrl: simulating game'); + $scope.simulateGamePromise = GamesManager.simulateGame($scope.game.GameId, $scope.simulatedGame).then((data) => { + $scope.users = data; + Alert.success('Table updated with simulation result'); + }).catch((err) => { + Alert.error('Failed to simulate game, please try again'); + $log.error('Error simulating game', err); + }); + } + + $scope.sort = (column) => { + $log.debug('GameCtrl: sorting by ' + column); + $scope.gameBets = _.sortBy($scope.gameBets, (item) => { + switch (column) { + case 'points': return item.Points; + case 'cards': return item.CardsMark; + case 'corners': return item.CornersMark; + case 'user': return item.User.FirstName + item.User.LastName; + case 'result': return item.HomeScore + '-' + item.AwayScore; + } + }); + }; + + $scope.gridOptions = { + ...Constants.TABLE_GRID_OPTIONS, ...{ + data: 'users', + onRegisterApi: (gridApi) => { + $scope.gridApi = gridApi; + $scope.gridApi.colResizable.on.columnSizeChanged($scope, saveState); + $scope.gridApi.core.on.columnVisibilityChanged($scope, saveState); + $scope.gridApi.core.on.sortChanged($scope, saveState); + } + } + }; + $scope.getTableHeight = () => { + var rowHeight = 30; + var headerHeight = 30; + var total = (($scope.users ? $scope.users.length : 0) * rowHeight + headerHeight); + $log.debug('Total Height: ' + total); + return { + height: total + "px" + }; + }; + $scope.goToUser = (rowItem) => { + $location.path(rowItem.entity.getUrl()); + }; + function saveState() { + var state = $scope.gridApi.saveState.save(); + localStorage.setItem('gridState', state); + }; + $scope.getUserPlace = (user) => { + return $scope.usersMap.get(user.Username).Place; + } + $scope.$watch('simulatedGame', () => { $scope.users = undefined }, true); + $scope.loadTeamsForm = () => { + $scope.teamsForm = {}; + $scope.getTeamGamesPromise = GamesManager.getTeamGames($scope.game.HomeTeam.TeamId).then((res) => { + storeTeamForm(res, $scope.game.HomeTeam.TeamId); + }).catch((err) => { + Alert.error('Failed to get teams form'); + $log.error('Failed to get teams form', err); + }); + GamesManager.getTeamGames($scope.game.AwayTeam.TeamId).then((res) => { + storeTeamForm(res, $scope.game.AwayTeam.TeamId); + }).catch((err) => { + Alert.error('Failed to get teams form'); + $log.error('Failed to get teams form', err); + }); + } + + function storeTeamForm(games, teamId) { + const form = _.chain(games).sortBy((game) => new Date(game.Date)).filter((game) => game.IsBetResolved).map((game) => { + return MundialitoUtils.getGameMark(game, teamId); + }).value(); + $scope.teamsForm[teamId] = { + form : form, + games: _.filter(games, (game) => game.IsBetResolved) + } + } + $scope.loadTeamsForm(); +}]); +'use strict'; +angular.module('mundialitoApp').controller('GamesCtrl', ['$scope','$log','GamesManager','games','teams', 'StadiumsManager' ,'Alert',function ($scope,$log, GamesManager, games, teams, StadiumsManager, Alert) { + $scope.newGame = null; + $scope.gamesFilter = "Open"; + $scope.gamesToggle = false; + $scope.games = games; + $scope.teams = teams; + $scope.changed = () => { + if ($scope.gamesFilter === "Open") { + $scope.gamesFilter = "All" + } else { + $scope.gamesFilter = "Open" + } + } + + StadiumsManager.loadAllStadiums().then(function (res) { + $scope.stadiums = res; + }); + + $scope.addNewGame = function () { + $('.selectpicker').selectpicker('refresh'); + $scope.newGame = GamesManager.getEmptyGameObject(); + }; + + $scope.saveNewGame = function() { + $scope.addGamePromise = GamesManager.addGame($scope.newGame).then((data) => { + Alert.success('Game was added successfully'); + $scope.newGame = GamesManager.getEmptyGameObject(); + $scope.games.push(data); + }); + }; + + $scope.isPendingUpdate = function(item) { + return item.IsPendingUpdate; + }; + + $scope.updateGame = function(game) { + if ((angular.isDefined(game.Stadium.Games)) && (game.Stadium.Games != null)) { + delete game.Stadium.Games; + } + $scope.editGamePromise = game.update().then((data) => { + Alert.success('Game was updated successfully'); + GamesManager.setGame(data); + }); + }; +}]); +'use strict'; +angular.module('mundialitoApp').factory('GamesManager', ['$http', '$q', 'Game', '$log', 'MundialitoUtils', 'User', function ($http, $q, Game, $log, MundialitoUtils, User) { + var gamesPromise = undefined; + var openGamesPromise = undefined; + var gamesManager = { + _pool: {}, + _retrieveInstance: function(gameId, gameData) { + var instance = this._pool[gameId]; + + if (instance) { + $log.debug('GamesManager: updating existing instance of game ' + gameId); + instance.setData(gameData); + } else { + $log.debug('GamesManager: saving new instance of game ' + gameId); + instance = new Game(gameData); + this._pool[gameId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function(gameId) { + $log.debug('GamesManager: will fetch game ' + gameId + ' from local pool'); + var instance = this._pool[gameId]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('GamesManager: Instance was loaded at ' + instance.LoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function(gameId, deferred) { + var scope = this; + $log.debug('GamesManager: will fetch game ' + gameId + ' from server'); + $http.get('api/games/' + gameId, { tracker: 'getGame'}) + .then((gameData) => { + var game = scope._retrieveInstance(gameData.data.GameId, gameData.data); + deferred.resolve(game); + }) + .catch(() => { + deferred.reject(); + }); + }, + + /* Public Methods */ + + /* Use this function in order to get a new empty game data object */ + getEmptyGameObject: function() { + return { + HomeTeam: '', + AwayTeam: '', + Date: '', + Stadium: '', + }; + }, + + /* Use this function in order to add a new game */ + addGame: function(gameData) { + var deferred = $q.defer(); + if (!angular.isObject(gameData.AwayTeam)) { + gameData.AwayTeam = angular.fromJson(gameData.AwayTeam); + } + if (!angular.isObject(gameData.HomeTeam)) { + gameData.HomeTeam = angular.fromJson(gameData.HomeTeam); + } + if (!angular.isObject(gameData.Stadium)) { + gameData.Stadium = angular.fromJson(gameData.Stadium); + } + var scope = this; + $log.debug('GamesManager: will add new game - ' + angular.toJson(gameData)); + $http.post("api/games", gameData, { tracker: 'addGame' }).then((data) => { + var game = scope._retrieveInstance(data.data.GameId, data.data); + deferred.resolve(game); + }) + .catch(function() { + deferred.reject(); + }); + return deferred.promise; + }, + + /* Use this function in order to get a game instance by it's id */ + getGame: function(gameId,fresh) { + var deferred = $q.defer(); + var game = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + game = this._search(gameId); + } + if (game) { + deferred.resolve(game); + } else { + this._load(gameId, deferred); + } + return deferred.promise; + }, + + /* Use this function in order to get instances of all the games */ + loadAllGames: function () { + if (gamesPromise) { + return gamesPromise; + } + var deferred = $q.defer(); + var scope = this; + $log.debug('GamesManager: will fetch all games from server'); + $http.get('api/games', { tracker: 'getGames'}) + .then((gamesArray) => { + var games = []; + gamesArray.data.forEach((gameData) => { + var game = scope._retrieveInstance(gameData.GameId, gameData); + games.push(game); + }); + + deferred.resolve(games); + }) + .catch(() => { + deferred.reject(); + }); + gamesPromise = deferred.promise; + return deferred.promise; + }, + + /* Use this function in order to get instances of all the open games */ + loadOpenGames: function () { + if (openGamesPromise) { + return openGamesPromise; + } + var deferred = $q.defer(); + var scope = this; + $log.debug('GamesManager: will fetch all open games from server'); + $http.get('api/games/open', { tracker: 'getOpenGames'}) + .then((gamesArray) => { + var games = []; + gamesArray.data.forEach((gameData) => { + var game = scope._retrieveInstance(gameData.GameId, gameData); + games.push(game); + }); + + deferred.resolve(games); + }) + .catch(() => { + deferred.reject(); + }); + openGamesPromise = deferred.promise; + return deferred.promise; + }, + + /* Use this function in order to get instances of all the games of a specific team */ + getTeamGames: function(teamId) { + var deferred = $q.defer(); + var scope = this; + $log.debug('GamesManager: will fetch all games of team ' + teamId + ' from server'); + $http.get('api/teams/' + teamId + '/games', { tracker: 'getTeamGames'}) + .then((gamesArray) => { + var games = []; + gamesArray.data.forEach((gameData) => { + var game = scope._retrieveInstance(gameData.GameId, gameData); + games.push(game); + }); + + deferred.resolve(games); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + } , + + /* Use this function in order to get instances of all the games in specific stadium */ + getStadiumGames: function(stadiumId) { + var deferred = $q.defer(); + var scope = this; + $log.debug('GamesManager: will fetch all games in stadium ' + stadiumId + ' from server'); + $http.get('api/games/Stadium/' + stadiumId, { tracker: 'getStadiumGames'}) + .then(function(gamesArray) { + var games = []; + gamesArray.data.forEach((gameData) => { + var game = scope._retrieveInstance(gameData.GameId, gameData); + games.push(game); + }); + deferred.resolve(games); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + } , + + simulateGame: function(gameId, gameResulst) { + var deferred = $q.defer(); + $log.debug('GamesManager: will simulate game ' + gameId); + $http.post('api/games/' + gameId + '/simulate', gameResulst, { tracker: 'simulateGame'}) + .then((usersArray) => { + var users = []; + usersArray.data.forEach((userData) => { + users.push(new User(userData)); + }); + deferred.resolve(users); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + + }, + + /* This function is useful when we got somehow the game data and we wish to store it or update the pool and get a game instance in return */ + setGame: function(gameData) { + $log.debug('GamesManager: will set game ' + gameData.GameId + ' to -' + angular.toJson(gameData)); + var scope = this; + var game = this._search(gameData.GameId); + if (game) { + game.setData(gameData); + } else { + game = scope._retrieveInstance(gameData.GameId,gameData); + } + return game; + } + + }; + return gamesManager; +}]); + +'use strict'; +angular.module('mundialitoApp').directive('mundialitoGames', ['Alert', function (Alert) { + return { + restrict: 'E', + scope: { + games: '=info', + gamesType: '=filter', + showOnly: '=', + onAdd: '&' + }, + templateUrl: 'App/Games/gamesTemplate.html', + link: ($scope) => { + $scope.allGames = $scope.games; + $scope.$watch('gamesType', function(newValue) { + if ((newValue) && (newValue !== "All")) { + $scope.games = $scope.games.filter((game) => { + return game.IsOpen; + }); + } else { + $scope.games = $scope.allGames; + } + }); + $scope.deleteGame = (game) => { + var scope = game; + game.delete().then(() => { + Alert.success('Game was deleted successfully'); + $scope.games.splice($scope.games.indexOf(scope), 1); + }); + }; + } + }; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('Alert', ['toaster', '$log', '$rootScope', function (toaster, $log, $rootScope) { + var service = { + success: success, + error: error, + note: note + }; + + return service; + + + function success(message) { + toaster.pop('success', 'Success', message); + }; + + function error(message, title) { + toaster.pop('error', title || 'Error', message); + } + + function note(message) { + toaster.pop('note', 'Info', message); + } +}]); +'use strict'; +angular.module('mundialitoApp').factory('ErrorHandler', ['$rootScope', '$log', 'Alert', '$location', 'Constants', function ($rootScope, $log, Alert, $location, Constants) { + var ErrorHandler = this; + + ErrorHandler.handle = (data, status, headers, config) => { + $log.log(data); + if (config.ignoreError) { + return; + } + if (status === 401) { + localStorage.removeItem('accessToken'); + sessionStorage.removeItem('accessToken'); + $location.path(Constants.LOGIN_PATH); + return; + } + var message = []; + var title = undefined; + if (data.Message) { + title = data.Message; + } + if (data.errors) { + angular.forEach(data.errors, (errors) => { + angular.forEach(errors, (errors) => { + message.push(errors); + }); + }); + } + if (data.ModelState) { + angular.forEach(data.ModelState, function (errors) { + message.push(errors); + }); + } + if (data.ExceptionMessage) { + message.push(data.ExceptionMessage); + } + if (data.error_description) { + message.push(data.error_description); + } + if (message.length === 0 && !title) { + title = "General Error"; + message.push("Looks like the server is down, please try again in few minutes"); + } + Alert.error(message.join('\n'), title); + } + + return ErrorHandler; +}]) + .factory('myHttpInterceptor', ['ErrorHandler', '$q', function (ErrorHandler, $q) { + return { + response: (response) => response, + responseError: (response) => { + ErrorHandler.handle(response.data, response.status, response.headers, response.config); + Sentry.captureException(response.data); + // do something on error + return $q.reject(response); + } + }; + }]); +angular.module('mundialitoApp').factory('MundialitoUtils', [ 'Constants', function (Constants) { + + var Utils = { + shouldRefreshInstance : (instance) => { + if (!angular.isDefined(instance.LoadTime) || !angular.isDate(instance.LoadTime)) { + return false; + } + var now = new Date().getTime(); + return ((now - instance.LoadTime.getTime()) > Constants.REFRESH_TIME); + }, + shortName : (name) => { + if (name.indexOf(' ') !== -1) { + let temp = name.split(' ') + return temp[0].substring(0, 1) + '.' + temp[1].substring(0, 1); + } + return name.substring(0, 1); + }, + getGameMark: (res, teamId) => { + if (res.HomeTeam.TeamId === teamId) { + if (res.HomeScore > res.AwayScore) { + return { game : res.GameId, mark : "W" }; + } else if (res.HomeScore < res.AwayScore) { + return { game : res.GameId, mark : "L" }; + } + return { game : res.GameId, mark : "D" }; + } else { + if (res.HomeScore > res.AwayScore) { + return { game : res.GameId, mark : "L" }; + } else if (res.HomeScore < res.AwayScore) { + return { game : res.GameId, mark : "W" }; + } + return { game : res.GameId, mark : "D" }; + } + } + }; + + return Utils; +}]); +'use strict'; +angular.module('mundialitoApp').directive('accessLevel', ['$log','security', function ($log,Security) { + return { + restrict: 'A', + link: function ($scope, element, attrs) { + var prevDisp = element.css('display') + , userRole = "" + , accessLevel; + + + $scope.$watch( + function () { + return Security.user; + }, + + function (newValue) { + $scope.user = newValue; + if (($scope.user === undefined) || ($scope.user === null)) { + userRole = "Active" + } else if ($scope.user.Roles) { + //$log.debug('Security.user has been changed:' + $scope.user.Username); + userRole = $scope.user.Roles; + } else { + userRole = "Active" + } + updateCSS(); + }, + true + ); + + attrs.$observe('accessLevel', function (al) { + if (al) accessLevel = al; + updateCSS(); + }); + + function updateCSS() { + if (userRole && accessLevel) { + if (userRole === accessLevel) + element.css('display', prevDisp); + else + element.css('display', 'none'); + } + } + } + }; +}]); +'use strict'; +angular.module('mundialitoApp').directive('activeNav', ['$location', function ($location) { + return { + restrict: 'A', + link: function (scope, element) { + var nestedA = element.find('a')[0]; + var path = nestedA.href; + + scope.location = $location; + scope.$watch('location.absUrl()', function (newPath) { + if (path === newPath) { + element.addClass('active'); + } else { + element.removeClass('active'); + } + }); + } + }; +}]); +'use strict'; +angular.module('mundialitoApp').directive('confirmPassword', [function () { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, element, attrs, ngModel) { + ngModel.$parsers.unshift(function (viewValue, $scope) { + var password = scope.$eval(attrs.confirmPassword); + var noMatch = viewValue != password; + ngModel.$setValidity('noMatch', !noMatch); + return viewValue; + }); + } + } +}]); +'use strict'; +angular.module('mundialitoApp').directive('mundialitoToggleText', [function () { + function link(scope, element, attrs) { + var state; + scope.$watch(attrs.varieble, function (value) { + state = value; + updateText(); + }); + + function updateText() { + var text = state == true ? attrs.trueLabel : attrs.falseLabel; + element.text(text); + } + } + return { + link: link + }; +}]); +'use strict'; +angular.module('mundialitoApp').directive('teamFlag', ['$rootScope', ($rootScope) => ({ + restrict: 'E', + scope: { + team: '=', + style: '=' + }, + templateUrl: 'App/General/teamFlagTemplate.html', + link: (scope) => { + scope.useFlagsCss = $rootScope.mundialitoApp.clientConfig.UseFlagsCss; + } +})]); + +'use strict'; +angular.module('mundialitoApp').factory('GeneralBet', ['$http','$log', function($http,$log) { + function GeneralBet(betData) { + if (betData) { + this.setData(betData); + } + // Some other initializations related to general bet + }; + + GeneralBet.prototype = { + setData: function(betData) { + angular.extend(this, betData); + }, + update: function() { + $log.debug('General Bet: Will update general bet ' + this.GeneralBetId); + return $http.put('api/generalbets/' + this.GeneralBetId, this, { tracker: 'updateGeneralBet' }); + }, + resolve: function() { + $log.debug('General Bet: Will resolve general bet ' + this.GeneralBetId); + var data = { + TeamIsRight: this.TeamIsRight || false, + PlayerIsRight: this.PlayerIsRight || false + }; + return $http.put('api/generalbets/' + this.GeneralBetId + '/resolve', data, { tracker: 'resolveGeneralBet' }); + } + }; + return GeneralBet; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('GeneralBetsManager', ['$http', '$q', 'GeneralBet', '$log', 'MundialitoUtils', function ($http, $q, GeneralBet, $log, MundialitoUtils) { + var generalBetsManager = { + _pool: {}, + _retrieveInstance: function (betId, betData) { + var instance = this._pool[betId]; + + if (instance) { + $log.debug('GeneralBetsManager: updating existing instance of bet ' + betId); + instance.setData(betData); + } else { + $log.debug('GeneralBetsManager: saving new instance of bet ' + betId); + instance = new GeneralBet(betData); + this._pool[betId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function (betId) { + $log.debug('GeneralBetsManager: will fetch bet ' + betId + ' from local pool'); + var instance = this._pool[betId]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('GeneralBetsManager: Instance was loaded at ' + instance.LoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function (betId, deferred) { + var scope = this; + $log.debug('GeneralBetsManager: will fetch bet ' + betId + ' from server'); + $http.get('api/generalbets/' + betId, { tracker: 'getGeneralBet' }) + .then((betData) => { + var bet = scope._retrieveInstance(betData.data.GeneralBetId, betData.data); + deferred.resolve(bet); + }) + .catch((e) => { + deferred.reject(e); + }); + }, + + /* Public Methods */ + /* Use this function in order to add a new general bet */ + addGeneralBet: function (betData) { + var deferred = $q.defer(); + var scope = this; + $log.debug('GeneralBetsManager: will add new bet - ' + angular.toJson(betData)); + $http.post('api/generalbets/', betData, { tracker: 'addGeneralBet' }).then((data) => { + var bet = scope._retrieveInstance(data.data.GeneralBetId, data.data); + deferred.resolve(bet); + }).catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* Use this function in order to get a general bet instance by it's id */ + getGeneralBet: function (betId, fresh) { + var deferred = $q.defer(); + var bet = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + bet = this._search(betId); + } + if (bet) { + deferred.resolve(bet); + } else { + this._load(betId, deferred); + } + return deferred.promise; + }, + + /* Use this function in order to get instances of all the general bets */ + loadAllGeneralBets: function () { + var deferred = $q.defer(); + var scope = this; + $log.debug('GeneralBetsManager: will fetch all general bets from server'); + $http.get('api/generalbets', { tracker: 'getGeneralBets' }) + .then((gamesArray) => { + var generalBets = []; + gamesArray.data.forEach((betData) => { + var bet = scope._retrieveInstance(betData.GeneralBetId, betData); + generalBets.push(bet); + }); + + deferred.resolve(generalBets); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + hasGeneralBet: function (username) { + var deferred = $q.defer(); + $log.debug('GeneralBetsManager: will check if user ' + username + ' has general bets'); + $http.get('api/generalbets/has-bet/' + username, { tracker: 'getUserGeneralBet' }) + .then((answer) => { + deferred.resolve(answer.data); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + canSubmtiGeneralBet: function () { + var deferred = $q.defer(); + $log.debug('GeneralBetsManager: will check if user general bets are closed'); + $http.get('api/generalbets/cansubmitbets/', { tracker: 'getCanSubmitGeneralBets' }) + .then((answer) => { + deferred.resolve(answer.data); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* Use this function in order to get a general bet instance by it's owner username */ + getUserGeneralBet: function (username) { + var deferred = $q.defer(); + var scope = this; + $log.debug('GeneralBetsManager: will fetch user ' + username + ' general bet from server'); + $http.get('api/generalbets/user/' + username, { tracker: 'getUserGeneralBet' }) + .then((betData) => { + var bet = scope._retrieveInstance(betData.data.GeneralBetId, betData.data); + deferred.resolve(bet); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* This function is useful when we got somehow the bet data and we wish to store it or update the pool and get a general bet instance in return */ + setGeneralBet: function (betData) { + $log.debug('GeneralBetsManager: will set bet ' + betData.GeneralBetId + ' to -' + angular.toJson(betData)); + var scope = this; + var bet = this._search(betData.GeneralBetId); + if (bet) { + bet.setData(betData); + } else { + bet = scope._retrieveInstance(betData.GeneralBetId, betData); + } + return bet; + } + }; + return generalBetsManager; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('Player', ['$http', '$log', function ($http, $log) { + function Player(playerData) { + if (playerData) { + this.setData(playerData); + } + // Some other initializations related to stadium + }; + + Player.prototype = { + setData: function (playerData) { + angular.extend(this, playerData); + } + }; + return Player; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('PlayersManager', ['$http', '$q', 'Player', '$log', function ($http, $q, Player, $log) { + var playersPromise = undefined; + var playersManager = { + _pool: {}, + _retrieveInstance: function (playerId, playerData) { + var instance = this._pool[playerId]; + + if (instance) { + $log.debug('playersPromise: updating existing instance of player ' + playerId); + instance.setData(playerData); + } else { + $log.debug('playersPromise: saving new instance of player ' + playerId); + instance = new Player(playerData); + this._pool[playerId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + + /* Public Methods */ + + getPlayerSchema: function () { + return [ + { property: 'Name', label: 'Name', type: 'text', attr: { required: true } } + ]; + }, + + /* Use this function in order to get instances of all the players */ + loadAllPlayers: function () { + if (playersPromise) { + return playersPromise; + } + var deferred = $q.defer(); + var scope = this; + $log.debug('PlayersManager: will fetch all players from server'); + $http.get("api/players", { tracker: 'getPlayers', cache: true }) + .then((playersArray) => { + var players = []; + playersArray.data.forEach((playerData) => { + var player = scope._retrieveInstance(playerData.PlayerId, playerData); + players.push(player); + }); + deferred.resolve(players); + }) + .catch((e) => { + deferred.reject(e); + }); + playersPromise = deferred.promise; + return deferred.promise; + }, + + }; + return playersManager; +}]); + +'use strict'; +angular.module('mundialitoApp').factory('Stadium', ['$http','$log', function($http,$log) { + function Stadium(stadiumData) { + if (stadiumData) { + this.setData(stadiumData); + } + // Some other initializations related to stadium + }; + + Stadium.prototype = { + setData: function(stadiumData) { + angular.extend(this, stadiumData); + }, + delete: function() { + if (confirm('Are you sure you would like to delete stadium ' + this.Name)) { + $log.debug('Stadium: Will delete stadium ' + this.StadiumId) + return $http.delete("api/stadiums/" + this.StadiumId, { tracker: 'deleteStadium' }); + } + }, + update: function() { + $log.debug('Stadium: Will update stadium ' + this.StadiumId) + var stadiumToUpdate = {}; + angular.copy(this,stadiumToUpdate); + delete stadiumToUpdate.Games; + return $http.put("api/stadiums/" + this.StadiumId, stadiumToUpdate, { tracker: 'editStadium' }); + }, + getUrl: function() { + return '/stadiums/' + this.StadiumId; + } + }; + return Stadium; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('StadiumCtrl', ['$scope', '$log', 'StadiumsManager', 'GamesManager', 'stadium', 'Alert', function ($scope, $log, StadiumsManager, GamesManager, stadium, Alert) { + $scope.stadium = stadium; + $scope.showEditForm = false; + + $scope.getStadiumGamesPromise = GamesManager.getStadiumGames($scope.stadium.StadiumId).then((data) => { + $log.debug('StadiumCtrl: Got games of stadium'); + $scope.games = data; + }); + + $scope.updateStadium = () => { + $scope.editStadiumPromise = $scope.stadium.update().then(() => { + Alert.success('Stadium was updated successfully'); + }); + }; + + $scope.schema = StadiumsManager.getStaidumSchema(); +}]); +'use strict'; +angular.module('mundialitoApp').controller('StadiumsCtrl', ['$scope', '$log', 'StadiumsManager', 'stadiums', 'Alert', function ($scope, $log, StadiumsManager, stadiums, Alert) { + $scope.stadiums = stadiums; + $scope.showNewStadium = false; + $scope.newStadium = null; + + $scope.addNewStadium = () => { + $scope.newStadium = StadiumsManager.getEmptyStadiumObject(); + }; + + $scope.saveNewStadium = () => { + StadiumsManager.addStadium($scope.newStadium).then((data) => { + Alert.success('Stadium was added successfully'); + $scope.newStadium = null; + $scope.stadiums.push(data); + }); + }; + + $scope.deleteStadium = (stadium) => { + var scope = stadium; + stadium.delete().then(() => { + Alert.success('Stadium was deleted successfully'); + $scope.stadiums.splice($scope.stadiums.indexOf(scope), 1); + }); + }; + + $scope.schema = StadiumsManager.getStaidumSchema(); +}]); +'use strict'; +angular.module('mundialitoApp').factory('StadiumsManager', ['$http', '$q', 'Stadium', '$log', 'MundialitoUtils', function ($http, $q, Stadium, $log, MundialitoUtils) { + var stadiumsPromise = undefined; + var stadiumsManager = { + _pool: {}, + _retrieveInstance: function (stadiumId, stadiumData) { + var instance = this._pool[stadiumId]; + + if (instance) { + $log.debug('StadiumsManager: updating existing instance of stadium ' + stadiumId); + instance.setData(stadiumData); + } else { + $log.debug('StadiumsManager: saving new instance of stadium ' + stadiumId); + instance = new Stadium(stadiumData); + this._pool[stadiumId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function (stadiumId) { + $log.debug('StadiumsManager: will fetch stadium ' + stadiumId + ' from local pool'); + var instance = this._pool[stadiumId]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('StadiumsManager: Instance was loaded at ' + instance.LoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function (stadiumId, deferred) { + var scope = this; + $log.debug('StadiumsManager: will fetch stadium ' + stadiumId + ' from server'); + $http.get('api/stadiums/' + stadiumId, { tracker: 'getStadium' }) + .then((stadiumData) => { + var stadium = scope._retrieveInstance(stadiumData.data.StadiumId, stadiumData.data); + deferred.resolve(stadium); + }) + .catch((e) => { + deferred.reject(e); + }); + }, + + /* Public Methods */ + + getStaidumSchema: function () { + return [ + { property: 'Name', label: 'Name', type: 'text', attr: { required: true } }, + { property: 'City', label: 'City', type: 'text', attr: { required: true } }, + { property: 'Capacity', label: 'Capacity', type: 'number', attr: { required: true } } + ]; + }, + + /* Use this function in order to get a new empty stadium data object */ + getEmptyStadiumObject: function () { + return { + HomeTeam: '', + AwayTeam: '' + }; + }, + + /* Use this function in order to add a new stadium */ + addStadium: function (stadiumData) { + var deferred = $q.defer(); + var scope = this; + $log.debug('StadiumsManager: will add new stadium - ' + angular.toJson(stadiumData)); + $http.post("api/stadiums", stadiumData, { tracker: 'addStadium' }).then((res) => { + var stadium = scope._retrieveInstance(res.data.StadiumId, res.data); + deferred.resolve(stadium); + }).catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* Use this function in order to get a stadium instance by it's id */ + getStadium: function (stadiumId, fresh) { + var deferred = $q.defer(); + var stadium = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + stadium = this._search(stadiumId); + } + if (stadium) { + deferred.resolve(stadium); + } else { + this._load(stadiumId, deferred); + } + return deferred.promise; + }, + + /* Use this function in order to get instances of all the stadiums */ + loadAllStadiums: function () { + if (stadiumsPromise) { + return stadiumsPromise; + } + var deferred = $q.defer(); + var scope = this; + $log.debug('StadiumsManager: will fetch all games from server'); + $http.get("api/stadiums", { tracker: 'getStadiums', cache: true }) + .then((stadiumsArray) => { + var stadiums = []; + stadiumsArray.data.forEach((stadiumData) => { + var stadium = scope._retrieveInstance(stadiumData.StadiumId, stadiumData); + stadiums.push(stadium); + }); + deferred.resolve(stadiums); + }) + .catch((e) => { + deferred.reject(e); + }); + stadiumsPromise = deferred.promise; + return deferred.promise; + }, + + /* This function is useful when we got somehow the stadium data and we wish to store it or update the pool and get a stadium instance in return */ + setStadium: function (stadiumData) { + $log.debug('StadiumsManager: will set stadium ' + stadiumData.StadiumId + ' to -' + angular.toJson(stadiumData)); + var scope = this; + var stadium = this._search(stadiumData.StadiumId); + if (stadium) { + stadium.setData(stadiumData); + } else { + stadium = scope._retrieveInstance(stadiumData.StadiumId, stadiumData); + } + return stadium; + } + }; + return stadiumsManager; +}]); + +angular.module('mundialitoApp').factory('Team', ['$http','$log', function($http,$log) { + function Team(teamData) { + if (teamData) { + this.setData(teamData); + } + // Some other initializations related to game + }; + + Team.prototype = { + setData: function(teamData) { + angular.extend(this, teamData); + this.Logo = this.Logo.toLowerCase(); + this.Flag = this.Flag.toLowerCase(); + }, + delete: function() { + if (confirm('Are you sure you would like to delete team ' + this.Name)) { + $log.debug('Team: Will delete team ' + this.TeamId) + return $http.delete("api/teams/" + this.TeamId, { tracker: 'deleteTeam'}); + } + }, + update: function() { + $log.debug('Team: Will update game ' + this.TeamId) + return $http.put("api/teams/" + this.TeamId, this, { tracker: 'editTeam'}); + }, + getUrl: function() { + return '/teams/' + this.TeamId; + } + }; + return Team; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('TeamCtrl', ['$scope', '$log', 'TeamsManager', 'team', 'games', 'Alert', 'PluginsProvider', 'MundialitoUtils', function ($scope, $log, TeamsManager, team, games, Alert, PluginsProvider, MundialitoUtils) { + $scope.team = team; + $scope.games = games; + $scope.plugins = {}; + $scope.teamsForm = {}; + $scope.showEditForm = false; + $scope.toKeyValue = (object) => { + return _.keys(object).map((key) => { return { 'name': key, 'value': object[key] } }); + }; + $scope.IntegrationsData = $scope.toKeyValue($scope.team.IntegrationsData); + $scope.fromKeyValue = (array) => { + let res = {}; + array.forEach((item) => { + if (item.name !== '') { + res[item.name] = item.value; + } + }) + return res; + }; + + const form = _.chain($scope.games).sortBy((game) => new Date(game.Date)).filter((game) => game.IsBetResolved).map((game) => { + return MundialitoUtils.getGameMark(game, $scope.team.TeamId); + }).value(); + $scope.teamsForm[$scope.team.TeamId] = { + form : form, + games: _.filter($scope.games, (game) => game.IsBetResolved) + } + PluginsProvider.getTeamDetailsFromAll($scope.team).then((results) => { + results.forEach((result) => { + $scope.plugins[result.property] = { data: result.data, template: result.template }; + }); + }); + + $scope.updateTeam = () => { + $scope.team.IntegrationsData = $scope.fromKeyValue($scope.IntegrationsData); + $scope.editTeamPromise = $scope.team.update().then((data) => { + Alert.success('Team was updated successfully'); + TeamsManager.setTeam(data.data); + }); + }; + + $scope.schema = TeamsManager.getTeamSchema(); + +}]); +'use strict'; +angular.module('mundialitoApp').controller('TeamsCtrl', ['$scope', '$log', 'TeamsManager', 'teams', 'Alert', function ($scope, $log, TeamsManager, teams, Alert) { + $scope.teams = teams; + $scope.showNewTeam = false; + $scope.newTeam = null; + + $scope.addNewTeam = function () { + $('.selectpicker').selectpicker('refresh'); + $scope.newTeam = TeamsManager.getEmptyTeamObject(); + }; + + $scope.saveNewTeam = function() { + TeamsManager.addTeam($scope.newTeam).then(function(data) { + Alert.success('Team was added successfully'); + $scope.newTeam = null; + $scope.teams.push(data); + }); + }; + + $scope.deleteTeam = function(team) { + var scope = team; + team.delete().then(() => { + Alert.success('Team was deleted successfully'); + $scope.teams.splice($scope.teams.indexOf(scope), 1); + }) + }; + + $scope.schema = TeamsManager.getTeamSchema(); +}]); +angular.module('mundialitoApp').factory('TeamsManager', ['$http', '$q', 'Team','$log','MundialitoUtils', function($http,$q,Team,$log,MundialitoUtils) { + var teamsManager = { + _pool: {}, + _retrieveInstance: function(teamId, teamData) { + var instance = this._pool[teamId]; + + if (instance) { + $log.debug('TeamsManager: updating existing instance of team ' + teamId); + instance.setData(teamData); + } else { + $log.debug('TeamsManager: saving new instance of team ' + teamId); + instance = new Team(teamData); + this._pool[teamId] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function(teamId) { + $log.debug('TeamsManager: will fetch team ' + teamId + ' from local pool'); + var instance = this._pool[teamId]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('TeamsManager: Instance was loaded at ' + instanceLoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function(teamId, deferred) { + var scope = this; + $log.debug('TeamsManager: will fetch team ' + teamId + ' from server'); + $http.get("api/teams/" + teamId, { tracker: 'getTeam'}) + .then((teamData) => { + var team = scope._retrieveInstance(teamData.data.TeamId, teamData.data); + deferred.resolve(team); + }) + .catch((e) => { + deferred.reject(e); + }); + }, + + /* Public Methods */ + + getTeamSchema: function() { + return [ + { property: 'Name', label: 'Name', type: 'text', attr: { required: true } }, + { property: 'Flag', label: 'Flag', type: 'url', attr: { required: true } }, + { property: 'TeamPage', label: 'TeamPage', type: 'url', attr: { required: false } }, + { property: 'Logo', label: 'Logo', type: 'url', attr: { required: true } }, + { property: 'ShortName', label: 'Short Name', type: 'text', attr: { ngMaxlength: 3, ngMinlength: 3, required: true } }, + { property: 'TournamentTeamId', label: 'Tournament Team Id', type: 'number', attr: { required: false } }, + ]; + }, + + /* Use this function in order to get a new empty team data object */ + getEmptyTeamObject: function() { + return { + Name: '', + Flag: '', + Logo: '', + ShortName: '', + TournamentTeamId: null, + TeamPage: null, + + } + }, + + /* Use this function in order to add a new team */ + addTeam: function(teamData) { + var deferred = $q.defer(); + var scope = this; + $log.debug('TeamsManager: will add new team - ' + angular.toJson(teamData)); + $http.post("api/teams", teamData, { tracker: 'addTeam'}) + .then((data) => { + var team = scope._retrieveInstance(data.data.TeamId, data.data); + deferred.resolve(team); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* Use this function in order to get a team instance by it's id */ + getTeam: function(teamId,fresh) { + var deferred = $q.defer(); + var team = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + team = this._search(teamId); + } + if (team) { + deferred.resolve(team); + } else { + this._load(teamId, deferred); + } + return deferred.promise; + }, + + /* Use this function in order to get instances of all the teams */ + loadAllTeams: function() { + var deferred = $q.defer(); + var scope = this; + $log.debug('TeamsManager: will fetch all teams from server'); + $http.get("api/teams", { tracker: 'getTeams', cache: true }) + .then((teamsArray) => { + var teams = []; + teamsArray.data.forEach((teamData) => { + var team = scope._retrieveInstance(teamData.TeamId, teamData); + teams.push(team); + }); + deferred.resolve(teams); + }) + .catch((e) => { + deferred.reject(e); + }); + return deferred.promise; + }, + + /* This function is useful when we got somehow the team data and we wish to store it or update the pool and get a team instance in return */ + setTeam: function(teamData) { + $log.debug('TeamsManager: will set team ' + teamData.TeamId + ' to -' + angular.toJson(teamData)); + var scope = this; + var team = this._search(teamData.TeamId); + if (team) { + team.setData(teamData); + } else { + team = scope._retrieveInstance(teamData.TeamId,teamData); + } + return team; + } + + }; + return teamsManager; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('ManageAppCtrl', ['$scope', '$log', 'Alert', 'users','teams', 'generalBets','UsersManager', 'players', function ($scope, $log, Alert, users, teams, generalBets, UsersManager, players) { + $scope.users = users; + $scope.generalBets = generalBets; + $scope.deleteUser = (user) => { + var scope = user; + $scope.deleteUserPromise = user.delete().then(() => { + Alert.success('User was deleted successfully'); + $scope.users.splice($scope.users.indexOf(scope), 1); + }); + }; + + $scope.resolveBet = (bet) => { + $scope.resolveGeneralBetPromise = bet.resolve().then(() => { + Alert.success('General bet was resolved successfully'); + }); + }; + + $scope.makeAdmin = (user) => { + user.makeAdmin().then(() => { + Alert.success('User is now admin'); + user.Roles = "Admin"; + }); + }; + + $scope.activate = (user) => { + user.activate().then(() => { + Alert.success('User was activated successfully'); + }); + }; + + $scope.deactivate = (user) => { + user.deactivate().then(() => { + Alert.success('User was deactivated successfully'); + }); + }; +}]); +'use strict'; +angular.module('mundialitoApp').factory('User', ['$http','$log', function($http, $log) { + function User(userData) { + if (userData) { + this.setData(userData); + } + // Some other initializations related to user + }; + + User.prototype = { + setData: function(userData) { + angular.extend(this, userData); + }, + getUrl: function() { + return '/users/' + this.Username; + }, + delete: function() { + if (confirm('Are you sure you would like to delete user ' + this.Username)) { + $log.debug('User: Will delete user ' + this.Username) + return $http.delete("api/users/" + this.Id, { tracker: 'deleteUser' }); + } + }, + makeAdmin :function() { + if (confirm('Are you sure you would like to make ' + this.Name + ' Admin?')) { + $log.debug('User: Will make user ' + this.Username + ' admin') + return $http.post("api/users/makeadmin/" + this.Id, { tracker: 'makeAdmin' }); + } + }, + activate: function () { + if (confirm('Are you sure you would like to activate ' + this.Name)) { + $log.debug('User: Will actiavte user ' + this.Username) + return $http.post('api/users/' + this.Id + '/activate'); + } + }, + deactivate: function () { + if (confirm('Are you sure you would like to deactiavte ' + this.Name)) { + $log.debug('User: Will deactiavte user ' + this.Username) + return $http.delete('api/users/' + this.Id + '/activate'); + } + }, + }; + return User; +}]); + +'use strict'; +angular.module('mundialitoApp').controller('UserProfileCtrl', ['$scope', '$log', 'UsersManager', 'Alert', 'GeneralBetsManager', 'profileUser', 'userGameBets', 'teams', 'generalBetsAreOpen', 'players', function ($scope, $log, UsersManager, Alert, GeneralBetsManager, profileUser, userGameBets, teams, generalBetsAreOpen, players) { + $scope.profileUser = profileUser; + $scope.userGameBets = userGameBets; + $scope.teams = teams; + $scope.players = players; + $scope.noGeneralBetWasSubmitted = false; + $scope.generalBetsAreOpen = (generalBetsAreOpen === true); + $log.debug('UserProfileCtrl: generalBetsAreOpen = ' + generalBetsAreOpen); + $scope.alreadyFollow = $scope.security.user.Followees.includes($scope.profileUser.Username) + + $scope.isLoggedUserProfile = () => { + var res = ($scope.security.user != null) && ($scope.security.user.Username === $scope.profileUser.Username); + $log.debug('UserProfileCtrl: isLoggedUserProfile = ' + res); + return ($scope.security.user != null) && ($scope.security.user.Username === $scope.profileUser.Username); + }; + + $scope.isGeneralBetClosed = () => { + var res = !$scope.generalBetsAreOpen; + $log.debug('UserProfileCtrl: isGeneralBetClosed = ' + res); + return res; + }; + + $scope.isGeneralBetReadOnly = () => { + var res = (!$scope.isLoggedUserProfile() || ($scope.isGeneralBetClosed())); + $log.debug('UserProfileCtrl: isGeneralBetReadOnly = ' + res); + return res; + } + + $scope.shoudLoadGeneralBet = () => { + var res = ($scope.isLoggedUserProfile() || ($scope.isGeneralBetClosed())); + $log.debug('UserProfileCtrl: shoudLoadGeneralBet = ' + res); + return res; + } + + if ($scope.shoudLoadGeneralBet()) { + $scope.generalBetsPromise = GeneralBetsManager.hasGeneralBet($scope.profileUser.Username).then((answer) => { + $log.debug('UserProfileCtrl: hasGeneralBet = ' + answer); + if (answer === true) { + GeneralBetsManager.getUserGeneralBet($scope.profileUser.Username).then((generalBet) => { + $log.info('UserProfileCtrl: got user general bet - ' + angular.toJson(generalBet)); + $scope.generalBet = generalBet; + }); + } + else { + $scope.generalBet = {}; + if ($scope.isGeneralBetClosed()) { + $scope.noGeneralBetWasSubmitted = true; + return; + } + if ($scope.isLoggedUserProfile() && !$scope.isGeneralBetClosed()) { + return; + } + $scope.noGeneralBetWasSubmitted = true; + } + }); + } + + $scope.saveGeneralBet = () => { + if (angular.isDefined($scope.generalBet.GeneralBetId)) { + $scope.generalBetsPromise = $scope.generalBet.update().then(() => { + Alert.success('General Bet was updated successfully'); + }, () => { + Alert.error('Failed to update General Bet, please try again'); + }); + } + else { + $scope.generalBetsPromise = GeneralBetsManager.addGeneralBet($scope.generalBet).then((data) => { + $log.log('UserProfileCtrl: General Bet ' + data.GeneralBetId + ' was added'); + $scope.generalBet = data; + Alert.success('General Bet was added successfully'); + }, () => { + Alert.error('Failed to add General Bet, please try again'); + }); + } + }; + + $scope.social = () => { + if ($scope.alreadyFollow) { + UsersManager.unfollow($scope.profileUser.Username).then(() => { + $scope.alreadyFollow = false; + const index = $scope.security.user.Followees.indexOf($scope.profileUser.Username); + $scope.security.user.Followees.splice(index, 1); + Alert.success('You no longer following ' + $scope.profileUser.Username); + }).catch((err) => { + Alert.error('Failed to unfollow ' + $scope.profileUser.Username + ': ' + err); + }); + } else { + UsersManager.follow($scope.profileUser.Username).then(() => { + $scope.alreadyFollow = true; + $scope.security.user.Followees.push($scope.profileUser.Username); + Alert.success('You are now following ' + $scope.profileUser.Username); + }).catch((err) => { + Alert.error('Failed to follow ' + $scope.profileUser.Username + ': ' + err); + }); + } + }; + + $scope.getSocialPromise = UsersManager.getSocial($scope.profileUser.Username).then((data) => { + $log.log('UserProfileCtrl: Got social response'); + $scope.followers = data['followers']; + $scope.followees = data['followees']; + }); + + if ($scope.isLoggedUserProfile()) { + $scope.getStatsPromise = UsersManager.getMyStats().then((data) => { + $scope.performance = data; + }).catch((err) => { + $log.error('Failed to get user slef statistics', err); + Alert.error('Failed to fetch user statistics: ' + err); + }); + } else { + $scope.getStatsPromise = UsersManager.getStats($scope.profileUser.Username).then((data) => { + $scope.performance = data; + }).catch((err) => { + $log.error('Failed to get user statistics', err); + Alert.error('Failed to fetch user statistics: ' + err); + }); + } + if ($scope.security.user.Username === $scope.profileUser.Username) { + $scope.compareUsersPromise = UsersManager.getUserProgess($scope.security.user.Username); + } else { + $scope.compareUsersPromise = UsersManager.compareUsers($scope.security.user.Username, $scope.profileUser.Username); + } + $scope.compareUsersPromise.then((res) => { + if (res.length > 0) { + let users = _.map(res[0].Entries, (entry) => { return entry.Name }); + var cols = _.map(users, (user) => { + return { + id: user, + label: user, + type: "number" + } + }); + cols.unshift({ + id: "date", + label: "Date", + type: "date" + }); + let rows = _.map(res, (entry) => { + var res = { c: [{ + v: new Date(entry.Date), + }]}; + _.each(entry.Entries, (entry) => { + res.c.push({ + v: entry.Place, + }); + }); + return res; + }); + $scope.chart = { + type: "LineChart", + data: { + "cols": cols, + "rows": rows + }, + options: { + colors: ['#0000FF', '#009900', '#CC0000', '#DD9900'], + defaultColors: ['#0000FF', '#009900', '#CC0000', '#DD9900'], + displayExactValues: true, + is3D: true, + backgroundColor: { fill: 'transparent' }, + vAxis: { + title: "Place", + }, + hAxis: { + title: "Date" + } + } + }; + } + }).catch((err) => { + $log.error('Failed to compare users', err); + Alert.error('Failed to compare users: ' + err); + }); + + $scope.capture = () => { + html2canvas(document.body).then((canvas) => { + // Convert the canvas to a data URL + var dataURL = canvas.toDataURL('image/png'); + + // Create a temporary link element + var link = document.createElement('a'); + link.href = dataURL; + link.download = $scope.profileUser.Username + '.png'; + + // Trigger the download + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }); + } +}]); + +'use strict'; +angular.module('mundialitoApp').factory('UsersManager', ['$http', '$q', 'User', '$log', 'MundialitoUtils', function ($http, $q, User, $log, MundialitoUtils) { + var usersPromise = undefined; + var usersManager = { + _pool: {}, + _retrieveInstance: function (username, userData) { + var instance = this._pool[username]; + + if (instance) { + $log.debug('UsersManager: updating existing instance of user ' + username); + instance.setData(userData); + } else { + $log.debug('UsersManager: saving new instance of user ' + username); + instance = new User(userData); + this._pool[username] = instance; + } + instance.LoadTime = new Date(); + return instance; + }, + _search: function (username) { + $log.debug('UsersManager: will fetch user ' + username + ' from local pool'); + var instance = this._pool[username]; + if (angular.isDefined(instance) && MundialitoUtils.shouldRefreshInstance(instance)) { + $log.debug('UsersManager: Instance was loaded at ' + instance, LoadTime + ', will reload it from server'); + return undefined; + } + return instance; + }, + _load: function (username, deferred) { + var scope = this; + $log.debug('UsersManager: will fetch user ' + username + ' from server'); + $http.get('api/users/' + username, { tracker: 'getUser' }) + .then((userData) => { + var user = scope._retrieveInstance(userData.data.Username, userData.data); + deferred.resolve(user); + }) + .catch((e) => { + deferred.reject(e); + }); + }, + + /* Public Methods */ + /* Use this function in order to get a user instance by it's id */ + getUser: function (username, fresh) { + var deferred = $q.defer(); + var user = undefined; + if ((!angular.isDefined(fresh) || (!fresh))) { + user = this._search(username); + } + if (user) { + deferred.resolve(user); + } else { + this._load(username, deferred); + } + return deferred.promise; + }, + + getSocial: (username) => { + $log.debug('UsersManager: will fetch followers and followees of user ' + username); + return $http.get('api/users/' + username + '/followees', { tracker: 'getSocial' }) + .then((followees) => { + return $http.get('api/users/' + username + '/followers', { tracker: 'getSocial' }).then((followers) => { + return { + followers: followers.data, + followees: followees.data + }; + }); + }); + }, + + compareUsers: (usera, userb) => { + $log.debug('UsersManager: will compare users: ' + usera + ' and ' + userb); + return $http.get('api/users/compare/' + usera + '/' + userb) + .then((res) => { + return res.data; + }); + }, + + getUserProgess: () => { + $log.debug('UsersManager: will get user progress'); + return $http.get('api/users/me/progress') + .then((res) => { + return res.data; + }); + }, + + getMyStats: () => { + $log.debug('UsersManager: will the stats of logged user'); + return $http.get('api/stats/me', { tracker: 'getStats' }) + .then((res) => { + return res.data; + }); + }, + + getStats: (username) => { + $log.debug('UsersManager: will the stats of ' + username); + return $http.get('api/stats/' + username, { tracker: 'getStats' }) + .then((res) => { + return res.data; + }); + }, + + follow: (username) => { + $log.debug('UsersManager: will follow ' + username); + return $http.post('api/users/follow/' + username, undefined, { tracker: 'follow' }); + }, + + unfollow: (username) => { + $log.debug('UsersManager: will unfollow ' + username); + return $http.delete('api/users/follow/' + username, undefined, { tracker: 'unfollow' }); + }, + + /* Use this function in order to get instances of all the users */ + loadAllUsers: function () { + if (usersPromise) { + return usersPromise; + } + var deferred = $q.defer(); + var scope = this; + $log.debug('UsersManager: will fetch all users from server'); + $http.get('api/users', { tracker: 'getUsers' }) + .then((usersArray) => { + var users = []; + usersArray.data.forEach(function (userData) { + var user = scope._retrieveInstance(userData.Username, userData); + users.push(user); + }); + deferred.resolve(users); + }) + .catch((e) => { + deferred.reject(e); + }); + usersPromise = deferred.promise; + return deferred.promise; + }, + + /* This function is useful when we got somehow the user data and we wish to store it or update the pool and get a user instance in return */ + setUser: function (userData) { + $log.debug('UsersManager: will set user ' + userData.Username + ' to -' + angular.toJson(userData)); + var scope = this; + var user = this._search(userData.Username); + if (user) { + user.setData(userData); + } else { + user = scope._retrieveInstance(userData.Username, userData); + } + return user; + } + + }; + return usersManager; +}]); + +angular.module('mundialitoApp') + .factory('FootballDataGamePlugin', ['$q', '$rootScope', 'GenericProxyService', function ($q, $rootScope, GenericProxyService) { + var baseUrl = 'https://api.football-data.org/v4/matches/'; + const integrationKey = 'football-data' + + function getGameDetails(game) { + var url = baseUrl + game.IntegrationsData[integrationKey]; + if ((!$rootScope.mundialitoApp.clientConfig) || (!$rootScope.mundialitoApp.clientConfig['football-data-api-key'])) { + return $q.reject('Skipping football-data as no api key provided'); + } + return GenericProxyService.proxyRequest('GET', url, undefined, { + 'X-Auth-Token': $rootScope.mundialitoApp.clientConfig['football-data-api-key'] + }).then((response) => { + return { + data: response, + property: 'odds', + template: 'App/General/Plugins/FootballDataGameTemplate.html' + }; + }).catch((error) => { + return $q.reject(error); + }); + } + + return { + getGameDetails: getGameDetails, + integrationKey: integrationKey + }; + }]); + +angular.module('mundialitoApp') + .factory('FootballDataTeamStatsPlugin', ['$q', '$rootScope', 'GenericProxyService', function ($q, $rootScope, GenericProxyService) { + var baseUrl = 'https://api.football-data.org/v4/teams/'; + const integrationKey = 'football-data' + + function calcAge(dateOfBirth) { + return (new Date().getFullYear()) - parseInt(dateOfBirth.substring(0, 4), 10); + } + + function getTeamDetails(team) { + var url = baseUrl + team.IntegrationsData[integrationKey]; + if ((!$rootScope.mundialitoApp.clientConfig) || (!$rootScope.mundialitoApp.clientConfig['football-data-api-key'])) { + return $q.reject('Skipping football-data as no api key provided'); + } + return GenericProxyService.proxyRequest('GET', url, undefined, { + 'X-Auth-Token': $rootScope.mundialitoApp.clientConfig['football-data-api-key'] + }).then((response) => { + response.coach.age = calcAge(response.coach.dateOfBirth); + response.squad.forEach(player => { + player.age = calcAge(player.dateOfBirth); + player.icon = player.position.toLowerCase() === 'goalkeeper' ? 'goalkeeper' : 'player' + }); + return { + data: response, + property: 'team-squad', + template: 'App/General/Plugins/FootballDataTeamStatsTemplate.html' + }; + }).catch((error) => { + return $q.reject(error); + }); + } + + return { + getTeamDetails: getTeamDetails, + integrationKey: integrationKey + }; + }]); + +angular.module('mundialitoApp') + .factory('GenericProxyService', ['$http', '$q', function($http, $q) { + var baseUrl = 'api/genericproxy'; // Proxy server URL + + function proxyRequest(method, url, data, headers) { + var deferred = $q.defer(); + + $http({ + method: method, + url: baseUrl + '?url=' + url, + data: data, + headers: headers, + ignoreError: true + }).then((response) => { + deferred.resolve(response.data); + }).catch((error) => { + deferred.reject(error); + }); + + return deferred.promise; + } + + return { + proxyRequest: proxyRequest + }; + }]); + +angular.module('mundialitoApp') + .factory('PluginsProvider', ['$q', '$log', function ($q, $log) { + var gamesFactories = []; + var teamsFactories = []; + + + function getGameDetailsFromAll(game) { + let relevantPlugins = []; + if (!!game.IntegrationsData) { + relevantPlugins = _.filter(gamesFactories, (plugin) => { return game.IntegrationsData[plugin.integrationKey] !== undefined;}); + } + var promises = relevantPlugins.map((factory) => factory.getGameDetails(game)); + return $q.all(promises).then((results) => { + return results; + }).catch((e) => { + $log.warn('Error fetching game details: ' + e); + return $q.reject(e) + }); + } + + function getTeamDetailsFromAll(team) { + let relevantPlugins = []; + if (!!team.IntegrationsData) { + relevantPlugins = _.filter(teamsFactories, (plugin) => { return team.IntegrationsData[plugin.integrationKey] !== undefined;}); + } + var promises = relevantPlugins.map((factory) => factory.getTeamDetails(team)); + return $q.all(promises).then((results) => { + return results; + }).catch((e) => { + $log.warn('Error fetching team details: ' + e); + return $q.reject(e) + }); + } + + return { + getGameDetailsFromAll: getGameDetailsFromAll, + getTeamDetailsFromAll: getTeamDetailsFromAll, + registerGameFactory: (factory) => { + gamesFactories.push(factory); + }, + registerTeamFactory: (factory) => { + teamsFactories.push(factory); + } + }; + }]); diff --git a/Mundialito/wwwroot/js/app-min-dbea857653a57fb18c602c8a4373eee2.js b/Mundialito/wwwroot/js/app-min-dbea857653a57fb18c602c8a4373eee2.js new file mode 100644 index 0000000..85c752c --- /dev/null +++ b/Mundialito/wwwroot/js/app-min-dbea857653a57fb18c602c8a4373eee2.js @@ -0,0 +1 @@ +angular.module("mundialitoApp",["key-value-editor","security","ngSanitize","ngRoute","ngAnimate","ui.bootstrap","autofields.bootstrap","cgBusy","ajoslin.promise-tracker","ui.select","ui.bootstrap.datetimepicker","ui.grid","ui.grid.autoResize","googlechart","toaster","ui.grid.saveState","ui.grid.resizeColumns","ui.toggle","ngSentry"]).value("cgBusyTemplateName","App/Partials/angular-busy.html").config(["$routeProvider","$httpProvider","$locationProvider","$parseProvider","securityProvider","Constants",function(e,a,t,r,s,n){t.html5Mode(!0),a.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",a.interceptors.push("myHttpInterceptor"),s.urls.login=n.LOGIN_PATH,s.usePopups=!1,e.when("/",{templateUrl:"App/Dashboard/Dashboard.html",controller:"DashboardCtrl",resolve:{teams:["TeamsManager",e=>e.loadAllTeams()],players:["PlayersManager",e=>e.loadAllPlayers()]}}).when("/bets_center",{templateUrl:"App/Bets/BetsCenter.html",controller:"BetsCenterCtrl",resolve:{games:["GamesManager",e=>e.loadOpenGames()]}}).when("/users/:username",{templateUrl:"App/Users/UserProfile.html",controller:"UserProfileCtrl",resolve:{profileUser:["$route","UsersManager",(e,a)=>{var t=e.current.params.username;return a.getUser(t,!0)}],userGameBets:["$route","BetsManager",(e,a)=>{var t=e.current.params.username;return a.getUserBets(t)}],teams:["TeamsManager",e=>e.loadAllTeams()],generalBetsAreOpen:["GeneralBetsManager",e=>e.canSubmtiGeneralBet()],players:["PlayersManager",e=>e.loadAllPlayers()],allUsers:["UsersManager",e=>e.loadAllUsers()]}}).when("/manage_users",{templateUrl:"App/Users/ManageApp.html",controller:"ManageAppCtrl",resolve:{users:["UsersManager",e=>e.loadAllUsers()],teams:["TeamsManager",e=>e.loadAllTeams()],generalBets:["GeneralBetsManager",e=>e.loadAllGeneralBets()],players:["PlayersManager",e=>e.loadAllPlayers()]}}).when("/teams",{templateUrl:"App/Teams/Teams.html",controller:"TeamsCtrl",resolve:{teams:["TeamsManager",e=>e.loadAllTeams()]}}).when("/teams/:teamId",{templateUrl:"App/Teams/Team.html",controller:"TeamCtrl",resolve:{team:["$route","TeamsManager",(e,a)=>{var t=e.current.params.teamId;return a.getTeam(t)}],games:["$route","GamesManager",(e,a)=>{var t=e.current.params.teamId;return a.getTeamGames(t)}]}}).when("/games/:gameId",{templateUrl:"App/Games/Game.html",controller:"GameCtrl",resolve:{teams:["TeamsManager",e=>e.loadAllTeams()],players:["PlayersManager",e=>e.loadAllPlayers()],game:["$route","GamesManager",(e,a)=>{var t=e.current.params.gameId;return a.getGame(t)}],userBet:["$route","BetsManager",(e,a)=>{var t=e.current.params.gameId;return a.getUserBetOnGame(t)}]}}).when("/games",{templateUrl:"App/Games/Games.html",controller:"GamesCtrl",resolve:{games:["GamesManager",e=>e.loadAllGames()],teams:["TeamsManager",e=>e.loadAllTeams()]}}).when("/stadiums/:stadiumId",{templateUrl:"App/Stadiums/Stadium.html",controller:"StadiumCtrl",resolve:{stadium:["$q","$route","StadiumsManager",(e,a,t)=>{var r=a.current.params.stadiumId;return t.getStadium(r,!0)}]}}).when("/stadiums",{templateUrl:"App/Stadiums/Stadiums.html",controller:"StadiumsCtrl",resolve:{stadiums:["StadiumsManager",e=>e.loadAllStadiums()]}}).when("/login",{templateUrl:"App/Accounts/Login.html"}).when("/forgot",{templateUrl:"App/Accounts/ForgetPassword.html",controller:"ForgetPasswordCtrl"}).when("/reset",{templateUrl:"App/Accounts/ResetPassword.html",controller:"ResetPasswordCtrl"}).when("/join",{templateUrl:"App/Accounts/Register.html"}).when("/manage",{templateUrl:"App/Accounts/Manage.html"}).otherwise({redirectTo:"/"})}]).run(["$rootScope","$log","security","$route","$location","PluginsProvider","FootballDataGamePlugin","FootballDataTeamStatsPlugin",function(e,a,t,r,s,n,i,o){n.registerGameFactory(i),n.registerTeamFactory(o),t.events.login=function(t,r){a.log("Current user details: "+angular.toJson(r)),e.mundialitoApp.authenticating=!1},t.events.reloadUser=function(t,r){a.log("User reloaded"+angular.toJson(r)),e.mundialitoApp.authenticating=!1},t.events.logout=function(e){a.log("User logged out"),e.authenticate()},e.mundialitoApp={params:null,loading:!0,authenticating:!0,message:null},["/reset","/forgot","/join","/login"].includes(s.$$path)||(a.log("Starting authentication"),t.authenticate()),e.security=t,e.$on("$locationChangeStart",function(){a.debug("$locationChangeStart"),e.mundialitoApp.loading=!0}),e.$on("$locationChangeSuccess",function(){a.debug("$locationChangeSuccess"),e.mundialitoApp.params=angular.copy(r.current.params),e.mundialitoApp.loading=!1}),e.$on("$routeChangeStart",function(){a.debug("$routeChangeStart"),e.mundialitoApp.message="Loading..."}),e.$on("$routeChangeSuccess",function(){a.debug("$routeChangeSuccess"),e.mundialitoApp.message=null})}]),angular.module("mundialitoApp").constant("Constants",{LOGIN_PATH:"/login",REFRESH_TIME:3e5,TABLE_GRID_OPTIONS:{saveWidths:!0,saveVisible:!0,saveOrder:!0,enableRowSelection:!1,enableSelectAll:!1,multiSelect:!1,rowTemplate:'
',columnDefs:[{field:"Place",displayName:"",resizable:!1,maxWidth:30},{field:"Name",displayName:"Name",resizable:!0,minWidth:115},{field:"Points",displayName:"Points",resizable:!0,minWidth:45,maxWidth:75},{field:"GeneralBet.WinningTeam",displayName:"Team",resizable:!1,maxWidth:45,cellTemplate:'
'},{field:"GeneralBet.GoldenBootPlayer.Name",displayName:"Player",resizable:!1,minWidth:50,maxWidth:50,cellTemplate:"
{{COL_FIELD.split(' ')[0].charAt(0)}}.{{COL_FIELD.split(' ')[1].charAt(0)}}
"},{field:"Marks",displayName:"Marks",resizable:!0},{field:"Results",displayName:"Results",resizable:!0},{field:"YellowCards",displayName:"Yellow Cards Marks",maxWidth:55,resizable:!1,headerCellTemplate:'
'},{field:"Corners",displayName:"Corners Marks",maxWidth:55,resizable:!1,headerCellTemplate:'
'},,{field:"PlaceDiff",displayName:"",resizable:!1,maxWidth:45,cellTemplate:"
{{::COL_FIELD}}
"}]}}),angular.module("mundialitoApp").controller("ForgetPasswordCtrl",["$scope","$rootScope","security","Alert",function(e,a,t,r){a.mundialitoApp.authenticating=!1;e.user=new function(){return{Email:""}},e.forget=function(){e.emailForm.$valid&&(a.mundialitoApp.message="Processing...",t.forgotPassword(angular.copy(e.user)).then(()=>{r.success("Reset password token was sent to your email, please follow the link from there")}).catch(e=>{r.error("Failed to generate reset password token: "+e)}).finally(function(){a.mundialitoApp.message=null}))},e.schema=[{property:"Email",label:"Email Address",type:"email",attr:{required:!0}}]}]),angular.module("mundialitoApp").controller("LoginCtrl",["$scope","$rootScope","security",function(e,a,t){a.mundialitoApp.authenticating=!1;e.user=new function(){return{username:"",password:"",rememberMe:!1}},e.login=(()=>{e.loginForm.$valid&&(a.mundialitoApp.message="Processing Login...",t.login(angular.copy(e.user)).finally(function(){a.mundialitoApp.message=null}))}),e.schema=[{property:"username",type:"text",attr:{ngMinlength:4,required:!0}},{property:"password",type:"password",attr:{ngMinlength:4,required:!0}},{property:"rememberMe",label:"Keep me logged in",type:"checkbox"}],window.login=(e=>{console.log("Got response from Google: "+e),a.mundialitoApp.message="Processing Login...",t.googleLogin(e).finally(function(){a.mundialitoApp.message=null})}),window.onload=function(){google.accounts.id.initialize({client_id:e.mundialitoApp.GoogleClientId,callback:login}),google.accounts.id.renderButton(document.getElementById("buttonDiv"),{theme:"filled_blue",size:"large",text:"continue_with",shape:"circle"}),google.accounts.id.prompt()}}]),angular.module("mundialitoApp").controller("ManageCtrl",["$scope","Alert",function(e,a){var t=function(){return{oldPassword:"",newPassword:"",confirmPassword:""}};e.changingPassword=null,e.changePassword=function(){e.changingPassword=new t},e.cancel=function(){e.changingPassword=null},e.updatePassword=function(){if(e.manageForm.$valid){var t=angular.copy(e.changingPassword);e.changingPassword=null,e.security.changePassword(t).then(function(){a.success("Password was changed sucessfully")},function(){a.error("Failed to change password"),e.changingPassword=t})}},e.changePasswordSchema=[{property:"oldPassword",type:"password",attr:{required:!0}},{property:"newPassword",type:"password",attr:{ngMinlength:4,required:!0}},{property:"confirmPassword",type:"password",attr:{confirmPassword:"changingPassword.newPassword",required:!0}}]}]),angular.module("mundialitoApp").controller("RegisterCtrl",["$scope","security",function(e,a){e.mundialitoApp.authenticating=!1;e.user=new function(){return{firstname:"",lastname:"",email:"",username:"",password:"",confirmPassword:""}},e.join=function(){e.joinForm.$valid&&(e.isJoinActive=!0,e.mundialitoApp.message="Processing Registration...",a.register(angular.copy(e.user)).finally(function(){e.mundialitoApp.message=null,e.isJoinActive=!1}))},e.schema=[{property:"firstname",label:"First Name",type:"text",attr:{required:!0}},{property:"lastname",label:"Last Name",type:"text",attr:{required:!0}},{property:"email",label:"Email Address",type:"email",attr:{required:!0}},{property:"username",type:"text",attr:{ngMinlength:4,required:!0}},{property:"password",type:"password",attr:{required:!0}},{property:"confirmPassword",label:"Confirm Password",type:"password",attr:{confirmPassword:"user.password",required:!0}}]}]),angular.module("mundialitoApp").controller("ResetPasswordCtrl",["$scope","$rootScope","security","$location","Alert",function(e,a,t,r,s){a.mundialitoApp.authenticating=!1;e.user=new function(){return{confirmPassword:"",password:"",email:r.search().email,token:r.search().token}},e.reset=function(){e.resetForm.$valid&&(a.mundialitoApp.message="Processing Reset Password...",t.resetPassword(angular.copy(e.user)).then(()=>{s.success("Your was was reset successfully")}).finally(function(){a.mundialitoApp.message=null}))},e.schema=[{property:"password",type:"password",attr:{required:!0}},{property:"confirmPassword",label:"Confirm Password",type:"password",attr:{confirmPassword:"user.password",required:!0}}]}]),angular.module("mundialitoApp").factory("Bet",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)},getTeamByCornersMark:function(){return"1"===this.CornersMark?this.Game.HomeTeam:"2"===this.CornersMark?this.Game.AwayTeam:null},getTeamByCardsMark:function(){return"1"===this.CardsMark?this.Game.HomeTeam:"2"===this.CardsMark?this.Game.AwayTeam:null},update:function(){return a.debug("Bet: Will update bet "+this.BetId),e.put("api/bets/"+this.BetId,this,{tracker:"updateBet"})},getGameUrl:function(){return"/games/"+this.Game.GameId},getClass:function(){return this.Points>=7?"success":this.Points>=5?"primary":this.Points>=3?"info":this.Points>0?"warning":"danger"}},t}]),angular.module("mundialitoApp").controller("BetsCenterCtrl",["$scope","$log","$timeout","Alert","BetsManager","games",function(e,a,t,r,s,n){e.games=n,e.bets={};var i=function(){angular.isDefined(e.security.user)&&null!=e.security.user?e.getUserBetsPromise=s.getUserBets(e.security.user.Username).then(t=>{for(var r=0;r{r.success("Bet was updated successfully"),s.setBet(e)}).catch(function(){r.error("Failed to update Bet, please try again")})):(a.debug("BetsCenterCtrl: Will create new bet"),s.addBet(e.bets[t]).then(function(s){a.log("BetsCenterCtrl: Bet "+s.BetId+" was added"),e.bets[t]=s,r.success("Bet was added successfully")}).catch(function(){r.error("Failed to add Bet, please try again")}))},e.shuffleBet=function(t){var r,s,n=["1","X","2"],i=[0,0,0,0,1,1,1,1,2,2,3,3,4,5],o=n[Math.floor(3*Math.random())];do{r=i[Math.floor(Math.random()*i.length)],s=i[Math.floor(Math.random()*i.length)]}while("X"!==o&&r===s);a.debug("Random game mark is "+o),"X"===o&&(s=r),a.debug("Home goals: "+r),a.debug("Away goals: "+s),e.bets[t].HomeScore=r,e.bets[t].AwayScore=s,e.bets[t].CardsMark=n[Math.floor(3*Math.random())],e.bets[t].CornersMark=n[Math.floor(3*Math.random())]}}]),angular.module("mundialitoApp").factory("BetsManager",["$http","$q","Bet","$log","MundialitoUtils","GamesManager",function(e,a,t,r,s,n){return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("BetsManager: updating existing instance of bet "+e),s.setData(a)):(r.debug("BetsManager: saving new instance of bet "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("BetsManager: will fetch bet "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("BetsManager: Instance was loaded at "+a.LoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("BetsManager: will fetch bet "+a+" from server"),e.get("api/bets/"+a,{tracker:"getBet"}).then(e=>{var a=s._retrieveInstance(e.data.BetId,e.data);t.resolve(a)}).catch(()=>{t.reject()})},addBet:function(t){var s=a.defer(),n=this;return r.debug("BetsManager: will add new bet - "+angular.toJson(t)),e.post("api/bets/",t,{tracker:"addBetOnGame"}).then(e=>{var a=n._retrieveInstance(e.data.BetId,e.data);s.resolve(a)}).catch(e=>{r.error("Failed to add bet"),s.reject(e)}),s.promise},getBet:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},getGameBets:function(t){var s=a.defer(),n=this;return r.debug("BetsManager: will fetch all bets of game "+t+" from server"),e.get("api/games/"+t+"/bets",{tracker:"getGameBets"}).then(e=>{var a=[];e.data.forEach(e=>{var t=n._retrieveInstance(e.BetId,e);a.push(t)}),s.resolve(a)}).catch(function(){s.reject()}),s.promise},getUserBets:function(t){var s=a.defer(),n=this;return r.debug("BetsManager: will fetch user "+t+" bets from server"),e.get("api/bets/user/"+t,{tracker:"getUserBets"}).then(e=>{var a=[];e.data.forEach(e=>{var t=n._retrieveInstance(e.BetId,e);a.push(t)}),s.resolve(a)}).catch(function(){s.reject()}),s.promise},getUserBetOnGame:function(t){var s=a.defer(),n=this;return r.debug("BetsManager: will fetch user bet of game "+t+" from server"),e.get("api/games/"+t+"/mybet",{tracker:"getUserBetOnGame"}).then(e=>{if(-1!=e.data.BetId){var a=n._retrieveInstance(e.data.BetId,e.data);s.resolve(a)}s.resolve(e.data)}).catch(()=>{s.reject()}),s.promise},setBet:function(e){r.debug("BetsManager: will set bet "+e.BetId+" to -"+angular.toJson(e));var a=this._search(e.BetId);return a?a.setData(e):a=this._retrieveInstance(e.BetId,e),a}}}]),angular.module("mundialitoApp").controller("DashboardCtrl",["$scope","$log","Constants","$location","$timeout","GamesManager","UsersManager","GeneralBetsManager","teams","players","BetsManager","MundialitoUtils",function(e,a,t,r,s,n,i,o,l,u,d,m){e.generalBetsAreOpen=!1,e.submittedGeneralBet=!0,e.pendingUpdateGames=!1,e.oneAtATime=!0,e.status={},e.toggleValue={},e.players=u,e.changed=(a=>{e.toggleValue[a.GameId]?(e.selectedDic[a.GameId]=e.marksDic[a.GameId],e.selectedPercentage[a.GameId]=e.marksPercentage[a.GameId]):(e.selectedDic[a.GameId]=e.resultsDic[a.GameId],e.selectedPercentage[a.GameId]=e.resultsPercentage[a.GameId])}),e.getGamesPromise=n.loadAllGames().then(t=>{e.games=t,e.resultsDic={},e.marksDic={},e.selectedDic={},e.resultsPercentage={},e.marksPercentage={},e.selectedPercentage={},e.pendingUpdateGames=void 0!==_.findWhere(e.games,{IsPendingUpdate:!0}),e.pendingUpdateGamesFolloweesBets={},a.info("DashboardCtrl: followees:"+e.security.user.Followees),_.filter(e.games,e=>e.IsPendingUpdate).forEach(a=>{d.getGameBets(a.GameId).then(t=>{let r=_.groupBy(t,e=>e.HomeScore+"-"+e.AwayScore),s=_.groupBy(t,e=>e.HomeScore===e.AwayScore?"X":e.HomeScore>e.AwayScore?e.Game.HomeTeam.ShortName:e.Game.AwayTeam.ShortName);e.resultsDic[a.GameId]=Object.entries(r).sort((e,a)=>a[1].length-e[1].length),e.marksDic[a.GameId]=Object.entries(s).sort((e,a)=>a[1].length-e[1].length),e.resultsPercentage[a.GameId]={},e.resultsDic[a.GameId].forEach(r=>{e.resultsPercentage[a.GameId][r[0]]=Math.round(r[1].length/t.length*100)}),e.marksPercentage[a.GameId]={},e.marksDic[a.GameId].forEach(r=>{e.marksPercentage[a.GameId][r[0]]=Math.round(r[1].length/t.length*100)});let n=_.filter(t,a=>e.security.user.Followees.includes(a.User.Username)||e.security.user.Username===a.User.Username);e.pendingUpdateGamesFolloweesBets[a.GameId]=n,e.changed(a)})})});var c=()=>{angular.isDefined(e.security.user)&&null!=e.security.user?o.hasGeneralBet(e.security.user.Username).then(a=>{e.submittedGeneralBet=!0===a}):(a.debug("DashboardCtrl: user info not loaded yet, will retry in 1 second"),s(c,1e3))};function g(){var a=e.gridApi.saveState.save();localStorage.setItem("gridState",a)}c(),o.canSubmtiGeneralBet().then(a=>{e.generalBetsAreOpen=!0===a,e.generalBetsAreOpen||o.loadAllGeneralBets().then(function(a){e.generalBets=a,e.winningTeams={},e.winningPlayers={};for(var t=0;t{e.users=a,e.usersDic=a.reduce((e,a)=>(e[a.Id]=a,e),{})}),e.isOpenForBetting=(e=>e.IsOpen),e.isPendingUpdate=(e=>e.IsPendingUpdate),e.isDecided=function(e){return!e.IsOpen&&!e.IsPendingUpdate},e.isGameBet=(e=>a=>a.Game.GameId===e.GameId),e.hasBets=(a=>void 0!==e.pendingUpdateGamesFolloweesBets[a.GameId]&&e.pendingUpdateGamesFolloweesBets[a.GameId].length>0),e.gridOptions={...t.TABLE_GRID_OPTIONS,data:"users",onRegisterApi:a=>{e.gridApi=a,e.gridApi.colResizable.on.columnSizeChanged(e,g),e.gridApi.core.on.columnVisibilityChanged(e,g),e.gridApi.core.on.sortChanged(e,g)}},e.getTableHeight=(()=>{var t=30*(e.users?e.users.length:0)+30;return a.debug("Total Height: "+t),{height:t+"px"}}),e.goToUser=(e=>{r.path(e.entity.getUrl())})}]),angular.module("mundialitoApp").factory("Game",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)},delete:function(){if(confirm("Are you sure you would like to delete game "+this.GameId))return a.debug("Game: Will delete game "+this.GameId),e.delete("api/games/"+this.GameId,{tracker:"deleteGame"})},update:function(){return a.debug("Game: Will update game "+this.GameId),e.put("api/games/"+this.GameId,this,{tracker:"editGame"})},getUrl:function(){return"/games/"+this.GameId}},t}]),angular.module("mundialitoApp").controller("GameCtrl",["$scope","$log","Constants","UsersManager","GamesManager","BetsManager","game","userBet","Alert","$location","PluginsProvider","keyValueEditorUtils","MundialitoUtils","teams","players",function(e,a,t,r,s,n,i,o,l,u,d,m,c,g,p){e.game=i,e.teamsDic={},e.playersDic={},e.simulatedGame={},e.plugins={},e.userBet=o,e.userBet.GameId=i.GameId,e.showEditForm=!1,e.toKeyValue=(e=>_.keys(e).map(a=>({name:a,value:e[a]}))),e.integrationsData=e.toKeyValue(e.game.IntegrationsData);for(var f=0;fnew Date(e.Date)).filter(e=>e.IsBetResolved).map(e=>c.getGameMark(e,t)).value();e.teamsForm[t]={form:r,games:_.filter(a,e=>e.IsBetResolved)}}d.getGameDetailsFromAll(e.game).then(a=>{a.forEach(a=>{e.plugins[a.property]={data:a.data,template:a.template}})}),e.game.IsOpen||(e.getGameBetsPromsie=n.getGameBets(e.game.GameId).then(t=>{a.debug("GameCtrl: get game bets"+angular.toJson(t)),e.gameBets=t;var s={type:"PieChart",options:{displayExactValues:!0,is3D:!0,backgroundColor:{fill:"transparent"},chartArea:{left:10,top:20,bottom:0,height:"100%"},title:"Bets Distribution"}},n=_.filter(t,function(e){return e.HomeScore>e.AwayScore}).length,i=_.filter(t,function(e){return e.HomeScore===e.AwayScore}).length,o=_.filter(t,function(e){return e.HomeScore{e.usersMap=new Map,a.forEach(a=>{e.usersMap.set(a.Username,a)});let t=_.chain(a).filter(a=>e.security.user.Followees.includes(a.Username)).pluck("Username").value();e.followeesBets=_.filter(e.gameBets,e=>t.includes(e.User.Username));let r=_.chain(a).first(3).pluck("Username").value();e.top3UsersBets=_.filter(e.gameBets,e=>r.includes(e.User.Username));let s=0;a.forEach((a,t)=>{a.Username===e.security.user.Username&&(s=t)});let n=Math.max(s-3,0),i=Math.min(s+3,a.length),o=_.chain(a.slice(n,i+1)).pluck("Username").filter(a=>a!==e.security.user.Username).value();e.neighborsBets=_.filter(e.gameBets,e=>o.includes(e.User.Username))})})),e.updateGame=(()=>{angular.isDefined(i.Stadium.Games)&&null!=i.Stadium.Games&&delete i.Stadium.Games,e.game.IntegrationsData=m.mapEntries(m.compactEntries(e.integrationsData)),e.updateGamePromise=e.game.update().then(e=>{l.success("Game was updated successfully"),s.setGame(e.data)}).catch(e=>{l.error("Failed to update game, please try again"),a.error("Error updating game",e)})}),e.updateBet=(()=>{-1!==e.userBet.BetId?e.updateBetPromise=e.userBet.update().then(e=>{l.success("Bet was updated successfully"),n.setBet(e)}).catch(e=>{l.error("Failed to update bet, please try again"),a.error("Error updating bet",e)}):n.addBet(e.userBet).then(t=>{a.log("GameCtrl: Bet "+t.BetId+" was added"),e.userBet=t,l.success("Bet was added successfully")},e=>{l.error("Failed to add bet, please try again"),a.error("Error adding bet",e)})}),e.simulateGame=(()=>{a.debug("GameCtrl: simulating game"),e.simulateGamePromise=s.simulateGame(e.game.GameId,e.simulatedGame).then(a=>{e.users=a,l.success("Table updated with simulation result")}).catch(e=>{l.error("Failed to simulate game, please try again"),a.error("Error simulating game",e)})}),e.sort=(t=>{a.debug("GameCtrl: sorting by "+t),e.gameBets=_.sortBy(e.gameBets,e=>{switch(t){case"points":return e.Points;case"cards":return e.CardsMark;case"corners":return e.CornersMark;case"user":return e.User.FirstName+e.User.LastName;case"result":return e.HomeScore+"-"+e.AwayScore}})}),e.gridOptions={...t.TABLE_GRID_OPTIONS,data:"users",onRegisterApi:a=>{e.gridApi=a,e.gridApi.colResizable.on.columnSizeChanged(e,h),e.gridApi.core.on.columnVisibilityChanged(e,h),e.gridApi.core.on.sortChanged(e,h)}},e.getTableHeight=(()=>{var t=30*(e.users?e.users.length:0)+30;return a.debug("Total Height: "+t),{height:t+"px"}}),e.goToUser=(e=>{u.path(e.entity.getUrl())}),e.getUserPlace=(a=>e.usersMap.get(a.Username).Place),e.$watch("simulatedGame",()=>{e.users=void 0},!0),e.loadTeamsForm=(()=>{e.teamsForm={},e.getTeamGamesPromise=s.getTeamGames(e.game.HomeTeam.TeamId).then(a=>{v(a,e.game.HomeTeam.TeamId)}).catch(e=>{l.error("Failed to get teams form"),a.error("Failed to get teams form",e)}),s.getTeamGames(e.game.AwayTeam.TeamId).then(a=>{v(a,e.game.AwayTeam.TeamId)}).catch(e=>{l.error("Failed to get teams form"),a.error("Failed to get teams form",e)})}),e.loadTeamsForm()}]),angular.module("mundialitoApp").controller("GamesCtrl",["$scope","$log","GamesManager","games","teams","StadiumsManager","Alert",function(e,a,t,r,s,n,i){e.newGame=null,e.gamesFilter="Open",e.gamesToggle=!1,e.games=r,e.teams=s,e.changed=(()=>{"Open"===e.gamesFilter?e.gamesFilter="All":e.gamesFilter="Open"}),n.loadAllStadiums().then(function(a){e.stadiums=a}),e.addNewGame=function(){$(".selectpicker").selectpicker("refresh"),e.newGame=t.getEmptyGameObject()},e.saveNewGame=function(){e.addGamePromise=t.addGame(e.newGame).then(a=>{i.success("Game was added successfully"),e.newGame=t.getEmptyGameObject(),e.games.push(a)})},e.isPendingUpdate=function(e){return e.IsPendingUpdate},e.updateGame=function(a){angular.isDefined(a.Stadium.Games)&&null!=a.Stadium.Games&&delete a.Stadium.Games,e.editGamePromise=a.update().then(e=>{i.success("Game was updated successfully"),t.setGame(e)})}}]),angular.module("mundialitoApp").factory("GamesManager",["$http","$q","Game","$log","MundialitoUtils","User",function(e,a,t,r,s,n){var i=void 0,o=void 0;return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("GamesManager: updating existing instance of game "+e),s.setData(a)):(r.debug("GamesManager: saving new instance of game "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("GamesManager: will fetch game "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("GamesManager: Instance was loaded at "+a.LoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("GamesManager: will fetch game "+a+" from server"),e.get("api/games/"+a,{tracker:"getGame"}).then(e=>{var a=s._retrieveInstance(e.data.GameId,e.data);t.resolve(a)}).catch(()=>{t.reject()})},getEmptyGameObject:function(){return{HomeTeam:"",AwayTeam:"",Date:"",Stadium:""}},addGame:function(t){var s=a.defer();angular.isObject(t.AwayTeam)||(t.AwayTeam=angular.fromJson(t.AwayTeam)),angular.isObject(t.HomeTeam)||(t.HomeTeam=angular.fromJson(t.HomeTeam)),angular.isObject(t.Stadium)||(t.Stadium=angular.fromJson(t.Stadium));var n=this;return r.debug("GamesManager: will add new game - "+angular.toJson(t)),e.post("api/games",t,{tracker:"addGame"}).then(e=>{var a=n._retrieveInstance(e.data.GameId,e.data);s.resolve(a)}).catch(function(){s.reject()}),s.promise},getGame:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},loadAllGames:function(){if(i)return i;var t=a.defer(),s=this;return r.debug("GamesManager: will fetch all games from server"),e.get("api/games",{tracker:"getGames"}).then(e=>{var a=[];e.data.forEach(e=>{var t=s._retrieveInstance(e.GameId,e);a.push(t)}),t.resolve(a)}).catch(()=>{t.reject()}),i=t.promise,t.promise},loadOpenGames:function(){if(o)return o;var t=a.defer(),s=this;return r.debug("GamesManager: will fetch all open games from server"),e.get("api/games/open",{tracker:"getOpenGames"}).then(e=>{var a=[];e.data.forEach(e=>{var t=s._retrieveInstance(e.GameId,e);a.push(t)}),t.resolve(a)}).catch(()=>{t.reject()}),o=t.promise,t.promise},getTeamGames:function(t){var s=a.defer(),n=this;return r.debug("GamesManager: will fetch all games of team "+t+" from server"),e.get("api/teams/"+t+"/games",{tracker:"getTeamGames"}).then(e=>{var a=[];e.data.forEach(e=>{var t=n._retrieveInstance(e.GameId,e);a.push(t)}),s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},getStadiumGames:function(t){var s=a.defer(),n=this;return r.debug("GamesManager: will fetch all games in stadium "+t+" from server"),e.get("api/games/Stadium/"+t,{tracker:"getStadiumGames"}).then(function(e){var a=[];e.data.forEach(e=>{var t=n._retrieveInstance(e.GameId,e);a.push(t)}),s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},simulateGame:function(t,s){var i=a.defer();return r.debug("GamesManager: will simulate game "+t),e.post("api/games/"+t+"/simulate",s,{tracker:"simulateGame"}).then(e=>{var a=[];e.data.forEach(e=>{a.push(new n(e))}),i.resolve(a)}).catch(e=>{i.reject(e)}),i.promise},setGame:function(e){r.debug("GamesManager: will set game "+e.GameId+" to -"+angular.toJson(e));var a=this._search(e.GameId);return a?a.setData(e):a=this._retrieveInstance(e.GameId,e),a}}}]),angular.module("mundialitoApp").directive("mundialitoGames",["Alert",function(e){return{restrict:"E",scope:{games:"=info",gamesType:"=filter",showOnly:"=",onAdd:"&"},templateUrl:"App/Games/gamesTemplate.html",link:a=>{a.allGames=a.games,a.$watch("gamesType",function(e){a.games=e&&"All"!==e?a.games.filter(e=>e.IsOpen):a.allGames}),a.deleteGame=(t=>{var r=t;t.delete().then(()=>{e.success("Game was deleted successfully"),a.games.splice(a.games.indexOf(r),1)})})}}}]),angular.module("mundialitoApp").factory("Alert",["toaster","$log","$rootScope",function(e,a,t){return{success:function(a){e.pop("success","Success",a)},error:function(a,t){e.pop("error",t||"Error",a)},note:function(a){e.pop("note","Info",a)}}}]),angular.module("mundialitoApp").factory("ErrorHandler",["$rootScope","$log","Alert","$location","Constants",function(e,a,t,r,s){return this.handle=((e,n,i,o)=>{if(a.log(e),!o.ignoreError){if(401===n)return localStorage.removeItem("accessToken"),sessionStorage.removeItem("accessToken"),void r.path(s.LOGIN_PATH);var l=[],u=void 0;e.Message&&(u=e.Message),e.errors&&angular.forEach(e.errors,e=>{angular.forEach(e,e=>{l.push(e)})}),e.ModelState&&angular.forEach(e.ModelState,function(e){l.push(e)}),e.ExceptionMessage&&l.push(e.ExceptionMessage),e.error_description&&l.push(e.error_description),0!==l.length||u||(u="General Error",l.push("Looks like the server is down, please try again in few minutes")),t.error(l.join("\n"),u)}}),this}]).factory("myHttpInterceptor",["ErrorHandler","$q",function(e,a){return{response:e=>e,responseError:t=>(e.handle(t.data,t.status,t.headers,t.config),Sentry.captureException(t.data),a.reject(t))}}]),angular.module("mundialitoApp").factory("MundialitoUtils",["Constants",function(e){return{shouldRefreshInstance:a=>{return!(!angular.isDefined(a.LoadTime)||!angular.isDate(a.LoadTime))&&(new Date).getTime()-a.LoadTime.getTime()>e.REFRESH_TIME},shortName:e=>{if(-1!==e.indexOf(" ")){let a=e.split(" ");return a[0].substring(0,1)+"."+a[1].substring(0,1)}return e.substring(0,1)},getGameMark:(e,a)=>e.HomeTeam.TeamId===a?e.HomeScore>e.AwayScore?{game:e.GameId,mark:"W"}:e.HomeScoree.AwayScore?{game:e.GameId,mark:"L"}:e.HomeScore({restrict:"E",scope:{team:"=",style:"="},templateUrl:"App/General/teamFlagTemplate.html",link:a=>{a.useFlagsCss=e.mundialitoApp.clientConfig.UseFlagsCss}})]),angular.module("mundialitoApp").factory("GeneralBet",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)},update:function(){return a.debug("General Bet: Will update general bet "+this.GeneralBetId),e.put("api/generalbets/"+this.GeneralBetId,this,{tracker:"updateGeneralBet"})},resolve:function(){a.debug("General Bet: Will resolve general bet "+this.GeneralBetId);var t={TeamIsRight:this.TeamIsRight||!1,PlayerIsRight:this.PlayerIsRight||!1};return e.put("api/generalbets/"+this.GeneralBetId+"/resolve",t,{tracker:"resolveGeneralBet"})}},t}]),angular.module("mundialitoApp").factory("GeneralBetsManager",["$http","$q","GeneralBet","$log","MundialitoUtils",function(e,a,t,r,s){return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("GeneralBetsManager: updating existing instance of bet "+e),s.setData(a)):(r.debug("GeneralBetsManager: saving new instance of bet "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("GeneralBetsManager: will fetch bet "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("GeneralBetsManager: Instance was loaded at "+a.LoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("GeneralBetsManager: will fetch bet "+a+" from server"),e.get("api/generalbets/"+a,{tracker:"getGeneralBet"}).then(e=>{var a=s._retrieveInstance(e.data.GeneralBetId,e.data);t.resolve(a)}).catch(e=>{t.reject(e)})},addGeneralBet:function(t){var s=a.defer(),n=this;return r.debug("GeneralBetsManager: will add new bet - "+angular.toJson(t)),e.post("api/generalbets/",t,{tracker:"addGeneralBet"}).then(e=>{var a=n._retrieveInstance(e.data.GeneralBetId,e.data);s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},getGeneralBet:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},loadAllGeneralBets:function(){var t=a.defer(),s=this;return r.debug("GeneralBetsManager: will fetch all general bets from server"),e.get("api/generalbets",{tracker:"getGeneralBets"}).then(e=>{var a=[];e.data.forEach(e=>{var t=s._retrieveInstance(e.GeneralBetId,e);a.push(t)}),t.resolve(a)}).catch(e=>{t.reject(e)}),t.promise},hasGeneralBet:function(t){var s=a.defer();return r.debug("GeneralBetsManager: will check if user "+t+" has general bets"),e.get("api/generalbets/has-bet/"+t,{tracker:"getUserGeneralBet"}).then(e=>{s.resolve(e.data)}).catch(e=>{s.reject(e)}),s.promise},canSubmtiGeneralBet:function(){var t=a.defer();return r.debug("GeneralBetsManager: will check if user general bets are closed"),e.get("api/generalbets/cansubmitbets/",{tracker:"getCanSubmitGeneralBets"}).then(e=>{t.resolve(e.data)}).catch(e=>{t.reject(e)}),t.promise},getUserGeneralBet:function(t){var s=a.defer(),n=this;return r.debug("GeneralBetsManager: will fetch user "+t+" general bet from server"),e.get("api/generalbets/user/"+t,{tracker:"getUserGeneralBet"}).then(e=>{var a=n._retrieveInstance(e.data.GeneralBetId,e.data);s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},setGeneralBet:function(e){r.debug("GeneralBetsManager: will set bet "+e.GeneralBetId+" to -"+angular.toJson(e));var a=this._search(e.GeneralBetId);return a?a.setData(e):a=this._retrieveInstance(e.GeneralBetId,e),a}}}]),angular.module("mundialitoApp").factory("Player",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)}},t}]),angular.module("mundialitoApp").factory("PlayersManager",["$http","$q","Player","$log",function(e,a,t,r){var s=void 0;return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("playersPromise: updating existing instance of player "+e),s.setData(a)):(r.debug("playersPromise: saving new instance of player "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},getPlayerSchema:function(){return[{property:"Name",label:"Name",type:"text",attr:{required:!0}}]},loadAllPlayers:function(){if(s)return s;var t=a.defer(),n=this;return r.debug("PlayersManager: will fetch all players from server"),e.get("api/players",{tracker:"getPlayers",cache:!0}).then(e=>{var a=[];e.data.forEach(e=>{var t=n._retrieveInstance(e.PlayerId,e);a.push(t)}),t.resolve(a)}).catch(e=>{t.reject(e)}),s=t.promise,t.promise}}}]),angular.module("mundialitoApp").factory("Stadium",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)},delete:function(){if(confirm("Are you sure you would like to delete stadium "+this.Name))return a.debug("Stadium: Will delete stadium "+this.StadiumId),e.delete("api/stadiums/"+this.StadiumId,{tracker:"deleteStadium"})},update:function(){a.debug("Stadium: Will update stadium "+this.StadiumId);var t={};return angular.copy(this,t),delete t.Games,e.put("api/stadiums/"+this.StadiumId,t,{tracker:"editStadium"})},getUrl:function(){return"/stadiums/"+this.StadiumId}},t}]),angular.module("mundialitoApp").controller("StadiumCtrl",["$scope","$log","StadiumsManager","GamesManager","stadium","Alert",function(e,a,t,r,s,n){e.stadium=s,e.showEditForm=!1,e.getStadiumGamesPromise=r.getStadiumGames(e.stadium.StadiumId).then(t=>{a.debug("StadiumCtrl: Got games of stadium"),e.games=t}),e.updateStadium=(()=>{e.editStadiumPromise=e.stadium.update().then(()=>{n.success("Stadium was updated successfully")})}),e.schema=t.getStaidumSchema()}]),angular.module("mundialitoApp").controller("StadiumsCtrl",["$scope","$log","StadiumsManager","stadiums","Alert",function(e,a,t,r,s){e.stadiums=r,e.showNewStadium=!1,e.newStadium=null,e.addNewStadium=(()=>{e.newStadium=t.getEmptyStadiumObject()}),e.saveNewStadium=(()=>{t.addStadium(e.newStadium).then(a=>{s.success("Stadium was added successfully"),e.newStadium=null,e.stadiums.push(a)})}),e.deleteStadium=(a=>{var t=a;a.delete().then(()=>{s.success("Stadium was deleted successfully"),e.stadiums.splice(e.stadiums.indexOf(t),1)})}),e.schema=t.getStaidumSchema()}]),angular.module("mundialitoApp").factory("StadiumsManager",["$http","$q","Stadium","$log","MundialitoUtils",function(e,a,t,r,s){var n=void 0;return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("StadiumsManager: updating existing instance of stadium "+e),s.setData(a)):(r.debug("StadiumsManager: saving new instance of stadium "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("StadiumsManager: will fetch stadium "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("StadiumsManager: Instance was loaded at "+a.LoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("StadiumsManager: will fetch stadium "+a+" from server"),e.get("api/stadiums/"+a,{tracker:"getStadium"}).then(e=>{var a=s._retrieveInstance(e.data.StadiumId,e.data);t.resolve(a)}).catch(e=>{t.reject(e)})},getStaidumSchema:function(){return[{property:"Name",label:"Name",type:"text",attr:{required:!0}},{property:"City",label:"City",type:"text",attr:{required:!0}},{property:"Capacity",label:"Capacity",type:"number",attr:{required:!0}}]},getEmptyStadiumObject:function(){return{HomeTeam:"",AwayTeam:""}},addStadium:function(t){var s=a.defer(),n=this;return r.debug("StadiumsManager: will add new stadium - "+angular.toJson(t)),e.post("api/stadiums",t,{tracker:"addStadium"}).then(e=>{var a=n._retrieveInstance(e.data.StadiumId,e.data);s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},getStadium:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},loadAllStadiums:function(){if(n)return n;var t=a.defer(),s=this;return r.debug("StadiumsManager: will fetch all games from server"),e.get("api/stadiums",{tracker:"getStadiums",cache:!0}).then(e=>{var a=[];e.data.forEach(e=>{var t=s._retrieveInstance(e.StadiumId,e);a.push(t)}),t.resolve(a)}).catch(e=>{t.reject(e)}),n=t.promise,t.promise},setStadium:function(e){r.debug("StadiumsManager: will set stadium "+e.StadiumId+" to -"+angular.toJson(e));var a=this._search(e.StadiumId);return a?a.setData(e):a=this._retrieveInstance(e.StadiumId,e),a}}}]),angular.module("mundialitoApp").factory("Team",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e),this.Logo=this.Logo.toLowerCase(),this.Flag=this.Flag.toLowerCase()},delete:function(){if(confirm("Are you sure you would like to delete team "+this.Name))return a.debug("Team: Will delete team "+this.TeamId),e.delete("api/teams/"+this.TeamId,{tracker:"deleteTeam"})},update:function(){return a.debug("Team: Will update game "+this.TeamId),e.put("api/teams/"+this.TeamId,this,{tracker:"editTeam"})},getUrl:function(){return"/teams/"+this.TeamId}},t}]),angular.module("mundialitoApp").controller("TeamCtrl",["$scope","$log","TeamsManager","team","games","Alert","PluginsProvider","MundialitoUtils",function(e,a,t,r,s,n,i,o){e.team=r,e.games=s,e.plugins={},e.teamsForm={},e.showEditForm=!1,e.toKeyValue=(e=>_.keys(e).map(a=>({name:a,value:e[a]}))),e.IntegrationsData=e.toKeyValue(e.team.IntegrationsData),e.fromKeyValue=(e=>{let a={};return e.forEach(e=>{""!==e.name&&(a[e.name]=e.value)}),a});const l=_.chain(e.games).sortBy(e=>new Date(e.Date)).filter(e=>e.IsBetResolved).map(a=>o.getGameMark(a,e.team.TeamId)).value();e.teamsForm[e.team.TeamId]={form:l,games:_.filter(e.games,e=>e.IsBetResolved)},i.getTeamDetailsFromAll(e.team).then(a=>{a.forEach(a=>{e.plugins[a.property]={data:a.data,template:a.template}})}),e.updateTeam=(()=>{e.team.IntegrationsData=e.fromKeyValue(e.IntegrationsData),e.editTeamPromise=e.team.update().then(e=>{n.success("Team was updated successfully"),t.setTeam(e.data)})}),e.schema=t.getTeamSchema()}]),angular.module("mundialitoApp").controller("TeamsCtrl",["$scope","$log","TeamsManager","teams","Alert",function(e,a,t,r,s){e.teams=r,e.showNewTeam=!1,e.newTeam=null,e.addNewTeam=function(){$(".selectpicker").selectpicker("refresh"),e.newTeam=t.getEmptyTeamObject()},e.saveNewTeam=function(){t.addTeam(e.newTeam).then(function(a){s.success("Team was added successfully"),e.newTeam=null,e.teams.push(a)})},e.deleteTeam=function(a){var t=a;a.delete().then(()=>{s.success("Team was deleted successfully"),e.teams.splice(e.teams.indexOf(t),1)})},e.schema=t.getTeamSchema()}]),angular.module("mundialitoApp").factory("TeamsManager",["$http","$q","Team","$log","MundialitoUtils",function(e,a,t,r,s){return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("TeamsManager: updating existing instance of team "+e),s.setData(a)):(r.debug("TeamsManager: saving new instance of team "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("TeamsManager: will fetch team "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("TeamsManager: Instance was loaded at "+instanceLoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("TeamsManager: will fetch team "+a+" from server"),e.get("api/teams/"+a,{tracker:"getTeam"}).then(e=>{var a=s._retrieveInstance(e.data.TeamId,e.data);t.resolve(a)}).catch(e=>{t.reject(e)})},getTeamSchema:function(){return[{property:"Name",label:"Name",type:"text",attr:{required:!0}},{property:"Flag",label:"Flag",type:"url",attr:{required:!0}},{property:"TeamPage",label:"TeamPage",type:"url",attr:{required:!1}},{property:"Logo",label:"Logo",type:"url",attr:{required:!0}},{property:"ShortName",label:"Short Name",type:"text",attr:{ngMaxlength:3,ngMinlength:3,required:!0}},{property:"TournamentTeamId",label:"Tournament Team Id",type:"number",attr:{required:!1}}]},getEmptyTeamObject:function(){return{Name:"",Flag:"",Logo:"",ShortName:"",TournamentTeamId:null,TeamPage:null}},addTeam:function(t){var s=a.defer(),n=this;return r.debug("TeamsManager: will add new team - "+angular.toJson(t)),e.post("api/teams",t,{tracker:"addTeam"}).then(e=>{var a=n._retrieveInstance(e.data.TeamId,e.data);s.resolve(a)}).catch(e=>{s.reject(e)}),s.promise},getTeam:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},loadAllTeams:function(){var t=a.defer(),s=this;return r.debug("TeamsManager: will fetch all teams from server"),e.get("api/teams",{tracker:"getTeams",cache:!0}).then(e=>{var a=[];e.data.forEach(e=>{var t=s._retrieveInstance(e.TeamId,e);a.push(t)}),t.resolve(a)}).catch(e=>{t.reject(e)}),t.promise},setTeam:function(e){r.debug("TeamsManager: will set team "+e.TeamId+" to -"+angular.toJson(e));var a=this._search(e.TeamId);return a?a.setData(e):a=this._retrieveInstance(e.TeamId,e),a}}}]),angular.module("mundialitoApp").controller("ManageAppCtrl",["$scope","$log","Alert","users","teams","generalBets","UsersManager","players",function(e,a,t,r,s,n,i,o){e.users=r,e.generalBets=n,e.deleteUser=(a=>{var r=a;e.deleteUserPromise=a.delete().then(()=>{t.success("User was deleted successfully"),e.users.splice(e.users.indexOf(r),1)})}),e.resolveBet=(a=>{e.resolveGeneralBetPromise=a.resolve().then(()=>{t.success("General bet was resolved successfully")})}),e.makeAdmin=(e=>{e.makeAdmin().then(()=>{t.success("User is now admin"),e.Roles="Admin"})}),e.activate=(e=>{e.activate().then(()=>{t.success("User was activated successfully")})}),e.deactivate=(e=>{e.deactivate().then(()=>{t.success("User was deactivated successfully")})})}]),angular.module("mundialitoApp").factory("User",["$http","$log",function(e,a){function t(e){e&&this.setData(e)}return t.prototype={setData:function(e){angular.extend(this,e)},getUrl:function(){return"/users/"+this.Username},delete:function(){if(confirm("Are you sure you would like to delete user "+this.Username))return a.debug("User: Will delete user "+this.Username),e.delete("api/users/"+this.Id,{tracker:"deleteUser"})},makeAdmin:function(){if(confirm("Are you sure you would like to make "+this.Name+" Admin?"))return a.debug("User: Will make user "+this.Username+" admin"),e.post("api/users/makeadmin/"+this.Id,{tracker:"makeAdmin"})},activate:function(){if(confirm("Are you sure you would like to activate "+this.Name))return a.debug("User: Will actiavte user "+this.Username),e.post("api/users/"+this.Id+"/activate")},deactivate:function(){if(confirm("Are you sure you would like to deactiavte "+this.Name))return a.debug("User: Will deactiavte user "+this.Username),e.delete("api/users/"+this.Id+"/activate")}},t}]),angular.module("mundialitoApp").controller("UserProfileCtrl",["$scope","$log","UsersManager","Alert","GeneralBetsManager","profileUser","userGameBets","teams","generalBetsAreOpen","players",function(e,a,t,r,s,n,i,o,l,u){e.profileUser=n,e.userGameBets=i,e.teams=o,e.players=u,e.noGeneralBetWasSubmitted=!1,e.generalBetsAreOpen=!0===l,a.debug("UserProfileCtrl: generalBetsAreOpen = "+l),e.alreadyFollow=e.security.user.Followees.includes(e.profileUser.Username),e.isLoggedUserProfile=(()=>{var t=null!=e.security.user&&e.security.user.Username===e.profileUser.Username;return a.debug("UserProfileCtrl: isLoggedUserProfile = "+t),null!=e.security.user&&e.security.user.Username===e.profileUser.Username}),e.isGeneralBetClosed=(()=>{var t=!e.generalBetsAreOpen;return a.debug("UserProfileCtrl: isGeneralBetClosed = "+t),t}),e.isGeneralBetReadOnly=(()=>{var t=!e.isLoggedUserProfile()||e.isGeneralBetClosed();return a.debug("UserProfileCtrl: isGeneralBetReadOnly = "+t),t}),e.shoudLoadGeneralBet=(()=>{var t=e.isLoggedUserProfile()||e.isGeneralBetClosed();return a.debug("UserProfileCtrl: shoudLoadGeneralBet = "+t),t}),e.shoudLoadGeneralBet()&&(e.generalBetsPromise=s.hasGeneralBet(e.profileUser.Username).then(t=>{if(a.debug("UserProfileCtrl: hasGeneralBet = "+t),!0===t)s.getUserGeneralBet(e.profileUser.Username).then(t=>{a.info("UserProfileCtrl: got user general bet - "+angular.toJson(t)),e.generalBet=t});else{if(e.generalBet={},e.isGeneralBetClosed())return void(e.noGeneralBetWasSubmitted=!0);if(e.isLoggedUserProfile()&&!e.isGeneralBetClosed())return;e.noGeneralBetWasSubmitted=!0}})),e.saveGeneralBet=(()=>{angular.isDefined(e.generalBet.GeneralBetId)?e.generalBetsPromise=e.generalBet.update().then(()=>{r.success("General Bet was updated successfully")},()=>{r.error("Failed to update General Bet, please try again")}):e.generalBetsPromise=s.addGeneralBet(e.generalBet).then(t=>{a.log("UserProfileCtrl: General Bet "+t.GeneralBetId+" was added"),e.generalBet=t,r.success("General Bet was added successfully")},()=>{r.error("Failed to add General Bet, please try again")})}),e.social=(()=>{e.alreadyFollow?t.unfollow(e.profileUser.Username).then(()=>{e.alreadyFollow=!1;const a=e.security.user.Followees.indexOf(e.profileUser.Username);e.security.user.Followees.splice(a,1),r.success("You no longer following "+e.profileUser.Username)}).catch(a=>{r.error("Failed to unfollow "+e.profileUser.Username+": "+a)}):t.follow(e.profileUser.Username).then(()=>{e.alreadyFollow=!0,e.security.user.Followees.push(e.profileUser.Username),r.success("You are now following "+e.profileUser.Username)}).catch(a=>{r.error("Failed to follow "+e.profileUser.Username+": "+a)})}),e.getSocialPromise=t.getSocial(e.profileUser.Username).then(t=>{a.log("UserProfileCtrl: Got social response"),e.followers=t.followers,e.followees=t.followees}),e.isLoggedUserProfile()?e.getStatsPromise=t.getMyStats().then(a=>{e.performance=a}).catch(e=>{a.error("Failed to get user slef statistics",e),r.error("Failed to fetch user statistics: "+e)}):e.getStatsPromise=t.getStats(e.profileUser.Username).then(a=>{e.performance=a}).catch(e=>{a.error("Failed to get user statistics",e),r.error("Failed to fetch user statistics: "+e)}),e.security.user.Username===e.profileUser.Username?e.compareUsersPromise=t.getUserProgess(e.security.user.Username):e.compareUsersPromise=t.compareUsers(e.security.user.Username,e.profileUser.Username),e.compareUsersPromise.then(a=>{if(a.length>0){let r=_.map(a[0].Entries,e=>e.Name);var t=_.map(r,e=>({id:e,label:e,type:"number"}));t.unshift({id:"date",label:"Date",type:"date"});let s=_.map(a,e=>{var a={c:[{v:new Date(e.Date)}]};return _.each(e.Entries,e=>{a.c.push({v:e.Place})}),a});e.chart={type:"LineChart",data:{cols:t,rows:s},options:{colors:["#0000FF","#009900","#CC0000","#DD9900"],defaultColors:["#0000FF","#009900","#CC0000","#DD9900"],displayExactValues:!0,is3D:!0,backgroundColor:{fill:"transparent"},vAxis:{title:"Place"},hAxis:{title:"Date"}}}}}).catch(e=>{a.error("Failed to compare users",e),r.error("Failed to compare users: "+e)}),e.capture=(()=>{html2canvas(document.body).then(a=>{var t=a.toDataURL("image/png"),r=document.createElement("a");r.href=t,r.download=e.profileUser.Username+".png",document.body.appendChild(r),r.click(),document.body.removeChild(r)})})}]),angular.module("mundialitoApp").factory("UsersManager",["$http","$q","User","$log","MundialitoUtils",function(e,a,t,r,s){var n=void 0;return{_pool:{},_retrieveInstance:function(e,a){var s=this._pool[e];return s?(r.debug("UsersManager: updating existing instance of user "+e),s.setData(a)):(r.debug("UsersManager: saving new instance of user "+e),s=new t(a),this._pool[e]=s),s.LoadTime=new Date,s},_search:function(e){r.debug("UsersManager: will fetch user "+e+" from local pool");var a=this._pool[e];if(!angular.isDefined(a)||!s.shouldRefreshInstance(a))return a;r.debug("UsersManager: Instance was loaded at "+a,LoadTime+", will reload it from server")},_load:function(a,t){var s=this;r.debug("UsersManager: will fetch user "+a+" from server"),e.get("api/users/"+a,{tracker:"getUser"}).then(e=>{var a=s._retrieveInstance(e.data.Username,e.data);t.resolve(a)}).catch(e=>{t.reject(e)})},getUser:function(e,t){var r=a.defer(),s=void 0;return angular.isDefined(t)&&t||(s=this._search(e)),s?r.resolve(s):this._load(e,r),r.promise},getSocial:a=>(r.debug("UsersManager: will fetch followers and followees of user "+a),e.get("api/users/"+a+"/followees",{tracker:"getSocial"}).then(t=>e.get("api/users/"+a+"/followers",{tracker:"getSocial"}).then(e=>({followers:e.data,followees:t.data})))),compareUsers:(a,t)=>(r.debug("UsersManager: will compare users: "+a+" and "+t),e.get("api/users/compare/"+a+"/"+t).then(e=>e.data)),getUserProgess:()=>(r.debug("UsersManager: will get user progress"),e.get("api/users/me/progress").then(e=>e.data)),getMyStats:()=>(r.debug("UsersManager: will the stats of logged user"),e.get("api/stats/me",{tracker:"getStats"}).then(e=>e.data)),getStats:a=>(r.debug("UsersManager: will the stats of "+a),e.get("api/stats/"+a,{tracker:"getStats"}).then(e=>e.data)),follow:a=>(r.debug("UsersManager: will follow "+a),e.post("api/users/follow/"+a,void 0,{tracker:"follow"})),unfollow:a=>(r.debug("UsersManager: will unfollow "+a),e.delete("api/users/follow/"+a,void 0,{tracker:"unfollow"})),loadAllUsers:function(){if(n)return n;var t=a.defer(),s=this;return r.debug("UsersManager: will fetch all users from server"),e.get("api/users",{tracker:"getUsers"}).then(e=>{var a=[];e.data.forEach(function(e){var t=s._retrieveInstance(e.Username,e);a.push(t)}),t.resolve(a)}).catch(e=>{t.reject(e)}),n=t.promise,t.promise},setUser:function(e){r.debug("UsersManager: will set user "+e.Username+" to -"+angular.toJson(e));var a=this._search(e.Username);return a?a.setData(e):a=this._retrieveInstance(e.Username,e),a}}}]),angular.module("mundialitoApp").factory("FootballDataGamePlugin",["$q","$rootScope","GenericProxyService",function(e,a,t){var r="https://api.football-data.org/v4/matches/";const s="football-data";return{getGameDetails:function(n){var i=r+n.IntegrationsData[s];return a.mundialitoApp.clientConfig&&a.mundialitoApp.clientConfig["football-data-api-key"]?t.proxyRequest("GET",i,void 0,{"X-Auth-Token":a.mundialitoApp.clientConfig["football-data-api-key"]}).then(e=>({data:e,property:"odds",template:"App/General/Plugins/FootballDataGameTemplate.html"})).catch(a=>e.reject(a)):e.reject("Skipping football-data as no api key provided")},integrationKey:s}}]),angular.module("mundialitoApp").factory("FootballDataTeamStatsPlugin",["$q","$rootScope","GenericProxyService",function(e,a,t){var r="https://api.football-data.org/v4/teams/";const s="football-data";function n(e){return(new Date).getFullYear()-parseInt(e.substring(0,4),10)}return{getTeamDetails:function(i){var o=r+i.IntegrationsData[s];return a.mundialitoApp.clientConfig&&a.mundialitoApp.clientConfig["football-data-api-key"]?t.proxyRequest("GET",o,void 0,{"X-Auth-Token":a.mundialitoApp.clientConfig["football-data-api-key"]}).then(e=>(e.coach.age=n(e.coach.dateOfBirth),e.squad.forEach(e=>{e.age=n(e.dateOfBirth),e.icon="goalkeeper"===e.position.toLowerCase()?"goalkeeper":"player"}),{data:e,property:"team-squad",template:"App/General/Plugins/FootballDataTeamStatsTemplate.html"})).catch(a=>e.reject(a)):e.reject("Skipping football-data as no api key provided")},integrationKey:s}}]),angular.module("mundialitoApp").factory("GenericProxyService",["$http","$q",function(e,a){var t="api/genericproxy";return{proxyRequest:function(r,s,n,i){var o=a.defer();return e({method:r,url:t+"?url="+s,data:n,headers:i,ignoreError:!0}).then(e=>{o.resolve(e.data)}).catch(e=>{o.reject(e)}),o.promise}}}]),angular.module("mundialitoApp").factory("PluginsProvider",["$q","$log",function(e,a){var t=[],r=[];return{getGameDetailsFromAll:function(r){let s=[];r.IntegrationsData&&(s=_.filter(t,e=>void 0!==r.IntegrationsData[e.integrationKey]));var n=s.map(e=>e.getGameDetails(r));return e.all(n).then(e=>e).catch(t=>(a.warn("Error fetching game details: "+t),e.reject(t)))},getTeamDetailsFromAll:function(t){let s=[];t.IntegrationsData&&(s=_.filter(r,e=>void 0!==t.IntegrationsData[e.integrationKey]));var n=s.map(e=>e.getTeamDetails(t));return e.all(n).then(e=>e).catch(t=>(a.warn("Error fetching team details: "+t),e.reject(t)))},registerGameFactory:e=>{t.push(e)},registerTeamFactory:e=>{r.push(e)}}}]); \ No newline at end of file diff --git a/Mundialito/wwwroot/sentry/angular.min.js b/Mundialito/wwwroot/sentry/angular.min.js new file mode 100644 index 0000000..1ce2d84 --- /dev/null +++ b/Mundialito/wwwroot/sentry/angular.min.js @@ -0,0 +1,3 @@ +/*! @sentry/integrations 6.19.7 (5b3a175) | https://github.com/getsentry/sentry-javascript */ +!function(n){var t={},i=function(){return i=Object.assign||function(n){for(var t,i=1,r=arguments.length;i=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")}function u(t,n){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var e,i,o=r.call(t),u=[];try{for(;(void 0===n||n-- >0)&&!(e=o.next()).done;)u.push(e.value)}catch(t){i={error:t}}finally{try{e&&!e.done&&(r=o.return)&&r.call(o)}finally{if(i)throw i.error}}return u}function a(){for(var t=[],n=0;n ".length,a=void 0;r&&i++<5&&!("html"===(a=_(r,n))||i>1&&o+e.length*u+a.length>=80);)e.push(a),o+=a.length,r=r.parentNode;return e.reverse().join(" > ")}catch(t){return""}}function _(t,n){var r,e,i,o,u,a=t,s=[];if(!a||!a.tagName)return"";s.push(a.tagName.toLowerCase());var c=n&&n.length?n.filter((function(t){return a.getAttribute(t)})).map((function(t){return[t,a.getAttribute(t)]})):null;if(c&&c.length)c.forEach((function(t){s.push("["+t[0]+'="'+t[1]+'"]')}));else if(a.id&&s.push("#"+a.id),(r=a.className)&&p(r))for(e=r.split(/\s+/),u=0;u1&&(h=d.slice(0,-1).join("/"),v=d.pop()),v){var l=v.match(/^\d+/);l&&(v=l[0])}return T({host:s,pass:a,path:h,projectId:v,port:f,protocol:e,publicKey:i})}(t):T(t)}var D=["fatal","error","warning","log","info","debug","critical"],N=(c(),["debug","info","warn","error","log","assert"]);function q(t){var n=c();if(!("console"in n))return t();var r=n.console,e={};N.forEach((function(t){var i=r[t]&&r[t].__sentry_original__;t in n.console&&i&&(e[t]=r[t],r[t]=i)}));try{return t()}finally{Object.keys(e).forEach((function(t){r[t]=e[t]}))}}function M(){var t={enable:function(){!0},disable:function(){!1}};return N.forEach((function(n){t[n]=function(){}})),t}function I(t,n){return void 0===n&&(n=0),"string"!=typeof t||0===n||t.length<=n?t:t.substr(0,n)+"..."}function A(t,n){if(!Array.isArray(t))return"";for(var r=[],e=0;e"}var n}function z(t){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n}function B(t,n){void 0===n&&(n=40);var r=Object.keys(X(t));if(r.sort(),!r.length)return"[object has no keys]";if(r[0].length>=n)return I(r[0],n);for(var e=r.length;e>0;e--){var i=r.slice(0,e).join(", ");if(!(i.length>n))return e===r.length?i:I(i,n)}return""}function $(t){var n,r;if(b(t)){var e={};try{for(var i=o(Object.keys(t)),u=i.next();!u.done;u=i.next()){var a=u.value;void 0!==t[a]&&(e[a]=$(t[a]))}}catch(t){n={error:t}}finally{try{u&&!u.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return e}return Array.isArray(t)?t.map($):t}M();function W(t){if(!t.length)return[];var n=t,r=n[0].function||"",e=n[n.length-1].function||"";return-1===r.indexOf("captureMessage")&&-1===r.indexOf("captureException")||(n=n.slice(1)),-1!==e.indexOf("sentryWrapped")&&(n=n.slice(0,-1)),n.slice(0,50).map((function(t){return i(i({},t),{filename:t.filename||n[0].filename,function:t.function||"?"})})).reverse()}var J="";function K(t){try{return t&&"function"==typeof t&&t.name||J}catch(t){return J}}function G(){if(!("fetch"in c()))return!1;try{return new Headers,new Request(""),new Response,!0}catch(t){return!1}}function V(t){return t&&/^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(t.toString())}function Q(){if(!G())return!1;try{return new Request("_",{referrerPolicy:"origin"}),!0}catch(t){return!1}}var Y,Z=c(),tt={},nt={};function rt(t){if(!nt[t])switch(nt[t]=!0,t){case"console":!function(){if(!("console"in Z))return;N.forEach((function(t){t in Z.console&&L(Z.console,t,(function(n){return function(){for(var r=[],e=0;e2?n[2]:void 0;if(e){var i=Y,o=String(e);Y=o,it("history",{from:i,to:o})}return t.apply(this,n)}}Z.onpopstate=function(){for(var n=[],r=0;r":r||""}function pt(t,n,r){var e=t.exception=t.exception||{},i=e.values=e.values||[],o=i[0]=i[0]||{};o.value||(o.value=n||""),o.type||(o.type=r||"Error")}function mt(t,n){var r=lt(t);if(r){var e=r.mechanism;if(r.mechanism=i(i(i({},{type:"generic",handled:!0}),e),n),n&&"data"in n){var o=i(i({},e&&e.data),n.data);r.mechanism.data=o}}}function bt(t){if(t&&t.__sentry_captured__)return!0;try{U(t,"__sentry_captured__",!0)}catch(t){}return!1}function wt(t,n,r){void 0===n&&(n=1/0),void 0===r&&(r=1/0);try{return xt("",t,n,r)}catch(t){return{ERROR:"**non-serializable** ("+t+")"}}}function gt(t,n,r){void 0===n&&(n=3),void 0===r&&(r=102400);var e,i=wt(t,n);return e=i,function(t){return~-encodeURI(t).split(/%..|./).length}(JSON.stringify(e))>r?gt(t,n-1,r):i}function xt(t,n,r,e,i){var o,a;void 0===r&&(r=1/0),void 0===e&&(e=1/0),void 0===i&&(o="function"==typeof WeakSet,a=o?new WeakSet:[],i=[function(t){if(o)return!!a.has(t)||(a.add(t),!1);for(var n=0;n=e){y[g]="[MaxProperties ~]";break}var x=m[g];y[g]=xt(g,x,r-1,e,i),p+=1}return h(n),y}function Et(t){return new St((function(n){n(t)}))}function _t(t){return new St((function(n,r){r(t)}))}var St=function(){function t(t){var n=this;this.i=0,this.o=[],this.u=function(t){n.h(1,t)},this.v=function(t){n.h(2,t)},this.h=function(t,r){0===n.i&&(g(r)?r.then(n.u,n.v):(n.i=t,n.l=r,n.p()))},this.p=function(){if(0!==n.i){var t=n.o.slice();n.o=[],t.forEach((function(t){t[0]||(1===n.i&&t[1](n.l),2===n.i&&t[2](n.l),t[0]=!0)}))}};try{t(this.u,this.v)}catch(t){this.v(t)}}return t.prototype.then=function(n,r){var e=this;return new t((function(t,i){e.o.push([!1,function(r){if(n)try{t(n(r))}catch(t){i(t)}else t(r)},function(n){if(r)try{t(r(n))}catch(t){i(t)}else i(n)}]),e.p()}))},t.prototype.catch=function(t){return this.then((function(t){return t}),t)},t.prototype.finally=function(n){var r=this;return new t((function(t,e){var i,o;return r.then((function(t){o=!1,i=t,n&&n()}),(function(t){o=!0,i=t,n&&n()})).then((function(){o?e(i):t(i)}))}))},t}();function kt(t){var n=[];function r(t){return n.splice(n.indexOf(t),1)[0]}return{$:n,add:function(e){if(!(void 0===t||n.length0&&r(!1)}),t);n.forEach((function(t){Et(t).then((function(){--i||(clearTimeout(o),r(!0))}),e)}))}))}}}function jt(n){return"warn"===n?t.Severity.Warning:function(t){return-1!==D.indexOf(t)}(n)?n:t.Severity.Log}function Ot(t){return t>=200&&t<300?"success":429===t?"rate_limit":t>=400&&t<500?"invalid":t>=500?"failed":"unknown"}var Tt={nowSeconds:function(){return Date.now()/1e3}};var Rt=function(){var t=c().performance;if(t&&t.now)return{now:function(){return t.now()},timeOrigin:Date.now()-t.now()}}(),Dt=void 0===Rt?Tt:{nowSeconds:function(){return(Rt.timeOrigin+Rt.now())/1e3}},Nt=Tt.nowSeconds.bind(Tt),qt=Dt.nowSeconds.bind(Dt);function Mt(t,n){return void 0===n&&(n=[]),[t,n]}function It(t){var n=u(t,2),r=n[0],e=n[1],i=JSON.stringify(r);return e.reduce((function(t,n){var r=u(n,2),e=r[0],i=r[1],o=m(i)?String(i):JSON.stringify(i);return t+"\n"+JSON.stringify(e)+"\n"+o}),i)}!function(){var t=c().performance;if(t&&t.now){var n=36e5,r=t.now(),e=Date.now(),i=t.timeOrigin?Math.abs(t.timeOrigin+r-e):n,o=ir}function Lt(t,n,r){var e,u,a,s;void 0===r&&(r=Date.now());var c=i({},t),f=n["x-sentry-rate-limits"],h=n["retry-after"];if(f)try{for(var v=o(f.trim().split(",")),d=v.next();!d.done;d=v.next()){var l=d.value.split(":",2),y=parseInt(l[0],10),p=1e3*(isNaN(y)?60:y);if(l[1])try{for(var m=(a=void 0,o(l[1].split(";"))),b=m.next();!b.done;b=m.next()){c[b.value]=r+p}}catch(t){a={error:t}}finally{try{b&&!b.done&&(s=m.return)&&s.call(m)}finally{if(a)throw a.error}}else c.all=r+p}}catch(t){e={error:t}}finally{try{d&&!d.done&&(u=v.return)&&u.call(v)}finally{if(e)throw e.error}}else h&&(c.all=r+function(t,n){void 0===n&&(n=Date.now());var r=parseInt(""+t,10);if(!isNaN(r))return 1e3*r;var e=Date.parse(""+t);return isNaN(e)?6e4:e-n}(h,r));return c}var Ut=function(){function t(){this.m=!1,this.g=[],this._=[],this.S=[],this.k={},this.j={},this.O={},this.T={},this.R={}}return t.clone=function(n){var r=new t;return n&&(r.S=a(n.S),r.j=i({},n.j),r.O=i({},n.O),r.T=i({},n.T),r.k=n.k,r.D=n.D,r.N=n.N,r.q=n.q,r.M=n.M,r.I=n.I,r._=a(n._),r.A=n.A),r},t.prototype.addScopeListener=function(t){this.g.push(t)},t.prototype.addEventProcessor=function(t){return this._.push(t),this},t.prototype.setUser=function(t){return this.k=t||{},this.q&&this.q.update({user:t}),this.C(),this},t.prototype.getUser=function(){return this.k},t.prototype.getRequestSession=function(){return this.A},t.prototype.setRequestSession=function(t){return this.A=t,this},t.prototype.setTags=function(t){return this.j=i(i({},this.j),t),this.C(),this},t.prototype.setTag=function(t,n){var r;return this.j=i(i({},this.j),((r={})[t]=n,r)),this.C(),this},t.prototype.setExtras=function(t){return this.O=i(i({},this.O),t),this.C(),this},t.prototype.setExtra=function(t,n){var r;return this.O=i(i({},this.O),((r={})[t]=n,r)),this.C(),this},t.prototype.setFingerprint=function(t){return this.I=t,this.C(),this},t.prototype.setLevel=function(t){return this.D=t,this.C(),this},t.prototype.setTransactionName=function(t){return this.M=t,this.C(),this},t.prototype.setTransaction=function(t){return this.setTransactionName(t)},t.prototype.setContext=function(t,n){var r;return null===n?delete this.T[t]:this.T=i(i({},this.T),((r={})[t]=n,r)),this.C(),this},t.prototype.setSpan=function(t){return this.N=t,this.C(),this},t.prototype.getSpan=function(){return this.N},t.prototype.getTransaction=function(){var t=this.getSpan();return t&&t.transaction},t.prototype.setSession=function(t){return t?this.q=t:delete this.q,this.C(),this},t.prototype.getSession=function(){return this.q},t.prototype.update=function(n){if(!n)return this;if("function"==typeof n){var r=n(this);return r instanceof t?r:this}return n instanceof t?(this.j=i(i({},this.j),n.j),this.O=i(i({},this.O),n.O),this.T=i(i({},this.T),n.T),n.k&&Object.keys(n.k).length&&(this.k=n.k),n.D&&(this.D=n.D),n.I&&(this.I=n.I),n.A&&(this.A=n.A)):b(n)&&(n=n,this.j=i(i({},this.j),n.tags),this.O=i(i({},this.O),n.extra),this.T=i(i({},this.T),n.contexts),n.user&&(this.k=n.user),n.level&&(this.D=n.level),n.fingerprint&&(this.I=n.fingerprint),n.requestSession&&(this.A=n.requestSession)),this},t.prototype.clear=function(){return this.S=[],this.j={},this.O={},this.k={},this.T={},this.D=void 0,this.M=void 0,this.I=void 0,this.A=void 0,this.N=void 0,this.q=void 0,this.C(),this},t.prototype.addBreadcrumb=function(t,n){var r="number"==typeof n?Math.min(n,100):100;if(r<=0)return this;var e=i({timestamp:Nt()},t);return this.S=a(this.S,[e]).slice(-r),this.C(),this},t.prototype.clearBreadcrumbs=function(){return this.S=[],this.C(),this},t.prototype.applyToEvent=function(t,n){if(this.O&&Object.keys(this.O).length&&(t.extra=i(i({},this.O),t.extra)),this.j&&Object.keys(this.j).length&&(t.tags=i(i({},this.j),t.tags)),this.k&&Object.keys(this.k).length&&(t.user=i(i({},this.k),t.user)),this.T&&Object.keys(this.T).length&&(t.contexts=i(i({},this.T),t.contexts)),this.D&&(t.level=this.D),this.M&&(t.transaction=this.M),this.N){t.contexts=i({trace:this.N.getTraceContext()},t.contexts);var r=this.N.transaction&&this.N.transaction.name;r&&(t.tags=i({transaction:r},t.tags))}return this.L(t),t.breadcrumbs=a(t.breadcrumbs||[],this.S),t.breadcrumbs=t.breadcrumbs.length>0?t.breadcrumbs:void 0,t.sdkProcessingMetadata=this.R,this.U(a(Pt(),this._),t,n)},t.prototype.setSDKProcessingMetadata=function(t){return this.R=i(i({},this.R),t),this},t.prototype.U=function(t,n,r,e){var o=this;return void 0===e&&(e=0),new St((function(u,a){var s=t[e];if(null===n||"function"!=typeof s)u(n);else{var c=s(i({},n),r);g(c)?c.then((function(n){return o.U(t,n,r,e+1).then(u)})).then(null,a):o.U(t,c,r,e+1).then(u).then(null,a)}}))},t.prototype.C=function(){var t=this;this.m||(this.m=!0,this.g.forEach((function(n){n(t)})),this.m=!1)},t.prototype.L=function(t){t.fingerprint=t.fingerprint?Array.isArray(t.fingerprint)?t.fingerprint:[t.fingerprint]:[],this.I&&(t.fingerprint=t.fingerprint.concat(this.I)),t.fingerprint&&!t.fingerprint.length&&delete t.fingerprint},t}();function Pt(){return f("globalEventProcessors",(function(){return[]}))}function Ht(t){Pt().push(t)}var Xt=function(){function t(t){this.errors=0,this.sid=vt(),this.duration=0,this.status="ok",this.init=!0,this.ignoreDuration=!1;var n=qt();this.timestamp=n,this.started=n,t&&this.update(t)}return t.prototype.update=function(t){if(void 0===t&&(t={}),t.user&&(!this.ipAddress&&t.user.ip_address&&(this.ipAddress=t.user.ip_address),this.did||t.did||(this.did=t.user.id||t.user.email||t.user.username)),this.timestamp=t.timestamp||qt(),t.ignoreDuration&&(this.ignoreDuration=t.ignoreDuration),t.sid&&(this.sid=32===t.sid.length?t.sid:vt()),void 0!==t.init&&(this.init=t.init),!this.did&&t.did&&(this.did=""+t.did),"number"==typeof t.started&&(this.started=t.started),this.ignoreDuration)this.duration=void 0;else if("number"==typeof t.duration)this.duration=t.duration;else{var n=this.timestamp-this.started;this.duration=n>=0?n:0}t.release&&(this.release=t.release),t.environment&&(this.environment=t.environment),!this.ipAddress&&t.ipAddress&&(this.ipAddress=t.ipAddress),!this.userAgent&&t.userAgent&&(this.userAgent=t.userAgent),"number"==typeof t.errors&&(this.errors=t.errors),t.status&&(this.status=t.status)},t.prototype.close=function(t){t?this.update({status:t}):"ok"===this.status?this.update({status:"exited"}):this.update()},t.prototype.toJSON=function(){return $({sid:""+this.sid,init:this.init,started:new Date(1e3*this.started).toISOString(),timestamp:new Date(1e3*this.timestamp).toISOString(),status:this.status,errors:this.errors,did:"number"==typeof this.did||"string"==typeof this.did?""+this.did:void 0,duration:this.duration,attrs:{release:this.release,environment:this.environment,ip_address:this.ipAddress,user_agent:this.userAgent}})},t}(),Ft=function(){function t(t,n,r){void 0===n&&(n=new Ut),void 0===r&&(r=4),this.P=r,this.H=[{}],this.getStackTop().scope=n,t&&this.bindClient(t)}return t.prototype.isOlderThan=function(t){return this.P=t&&(clearInterval(i),r(!1)))}),1)}))},t.prototype.tt=function(){return this.G},t.prototype.rt=function(){return!1!==this.getOptions().enabled&&void 0!==this.Y},t.prototype.ut=function(t,n,r){var e=this,o=this.getOptions(),u=o.normalizeDepth,a=void 0===u?3:u,s=o.normalizeMaxBreadth,c=void 0===s?1e3:s,f=i(i({},t),{event_id:t.event_id||(r&&r.event_id?r.event_id:vt()),timestamp:t.timestamp||Nt()});this.at(f),this.st(f);var h=n;r&&r.captureContext&&(h=Ut.clone(h).update(r.captureContext));var v=Et(f);return h&&(v=h.applyToEvent(f,r)),v.then((function(t){return t&&(t.sdkProcessingMetadata=i(i({},t.sdkProcessingMetadata),{normalizeDepth:wt(a)+" ("+typeof a+")"})),"number"==typeof a&&a>0?e.ct(t,a,c):t}))},t.prototype.ct=function(t,n,r){if(!t)return null;var e=i(i(i(i(i({},t),t.breadcrumbs&&{breadcrumbs:t.breadcrumbs.map((function(t){return i(i({},t),t.data&&{data:wt(t.data,n,r)})}))}),t.user&&{user:wt(t.user,n,r)}),t.contexts&&{contexts:wt(t.contexts,n,r)}),t.extra&&{extra:wt(t.extra,n,r)});return t.contexts&&t.contexts.trace&&(e.contexts.trace=t.contexts.trace),e.sdkProcessingMetadata=i(i({},e.sdkProcessingMetadata),{baseClientNormalized:!0}),e},t.prototype.at=function(t){var n=this.getOptions(),r=n.environment,e=n.release,i=n.dist,o=n.maxValueLength,u=void 0===o?250:o;"environment"in t||(t.environment="environment"in n?r:"production"),void 0===t.release&&void 0!==e&&(t.release=e),void 0===t.dist&&void 0!==i&&(t.dist=i),t.message&&(t.message=I(t.message,u));var a=t.exception&&t.exception.values&&t.exception.values[0];a&&a.value&&(a.value=I(a.value,u));var s=t.request;s&&s.url&&(s.url=I(s.url,u))},t.prototype.st=function(t){var n=Object.keys(this.J);n.length>0&&(t.sdk=t.sdk||{},t.sdk.integrations=a(t.sdk.integrations||[],n))},t.prototype.ft=function(t){this.tt().sendEvent(t)},t.prototype.nt=function(t,n,r){return this.ht(t,n,r).then((function(t){return t.event_id}),(function(t){}))},t.prototype.ht=function(t,n,r){var e=this,i=this.getOptions(),o=i.beforeSend,u=i.sampleRate,a=this.getTransport();function s(t,n){a.recordLostEvent&&a.recordLostEvent(t,n)}if(!this.rt())return _t(new k("SDK not enabled, will not capture event."));var c="transaction"===t.type;return!c&&"number"==typeof u&&Math.random()>u?(s("sample_rate","event"),_t(new k("Discarding event because it's not included in the random sample (sampling rate = "+u+")"))):this.ut(t,r,n).then((function(r){if(null===r)throw s("event_processor",t.type||"event"),new k("An event processor returned null, will not send event.");return n&&n.data&&!0===n.data.__sentry__||c||!o?r:function(t){var n="`beforeSend` method has to return `null` or a valid event.";if(g(t))return t.then((function(t){if(!b(t)&&null!==t)throw new k(n);return t}),(function(t){throw new k("beforeSend rejected with "+t)}));if(!b(t)&&null!==t)throw new k(n);return t}(o(r,n))})).then((function(n){if(null===n)throw s("before_send",t.type||"event"),new k("`beforeSend` returned `null`, will not send event.");var i=r&&r.getSession&&r.getSession();return!c&&i&&e.ot(i,n),e.ft(n),n})).then(null,(function(t){if(t instanceof k)throw t;throw e.captureException(t,{data:{__sentry__:!0},originalException:t}),new k("Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: "+t)}))},t.prototype.Z=function(t){var n=this;this.K+=1,t.then((function(t){return n.K-=1,t}),(function(t){return n.K-=1,t}))},t}();function an(t){if(t.metadata&&t.metadata.sdk){var n=t.metadata.sdk;return{name:n.name,version:n.version}}}function sn(t,n){return n?(t.sdk=t.sdk||{},t.sdk.name=t.sdk.name||n.name,t.sdk.version=t.sdk.version||n.version,t.sdk.integrations=a(t.sdk.integrations||[],n.integrations||[]),t.sdk.packages=a(t.sdk.packages||[],n.packages||[]),t):t}function cn(t,n){var r=an(n),e="aggregates"in t?"sessions":"session";return[Mt(i(i({sent_at:(new Date).toISOString()},r&&{sdk:r}),!!n.tunnel&&{dsn:O(n.dsn)}),[[{type:e},t]]),e]}var fn=function(){function t(){}return t.prototype.sendEvent=function(t){return Et({reason:"NoopTransport: Event has been skipped because no Dsn is configured.",status:"skipped"})},t.prototype.close=function(t){return Et(!0)},t}(),hn=function(){function t(t){this.V=t,this.vt=this.dt()}return t.prototype.eventFromException=function(t,n){throw new k("Backend has to implement `eventFromException` method")},t.prototype.eventFromMessage=function(t,n,r){throw new k("Backend has to implement `eventFromMessage` method")},t.prototype.sendEvent=function(t){if(this.lt&&this.V.dsn&&this.V._experiments&&this.V._experiments.newTransport){var n=function(t,n){var r=an(n),e=t.type||"event",o=(t.sdkProcessingMetadata||{}).transactionSampling||{},u=o.method,a=o.rate;return sn(t,n.metadata.sdk),t.tags=t.tags||{},t.extra=t.extra||{},t.sdkProcessingMetadata&&t.sdkProcessingMetadata.baseClientNormalized||(t.tags.skippedNormalization=!0,t.extra.normalizeDepth=t.sdkProcessingMetadata?t.sdkProcessingMetadata.normalizeDepth:"unset"),delete t.sdkProcessingMetadata,Mt(i(i({event_id:t.event_id,sent_at:(new Date).toISOString()},r&&{sdk:r}),!!n.tunnel&&{dsn:O(n.dsn)}),[[{type:e,sample_rates:[{id:u,rate:a}]},t]])}(t,Vt(this.V.dsn,this.V.yt,this.V.tunnel));this.lt.send(n).then(null,(function(t){}))}else this.vt.sendEvent(t).then(null,(function(t){}))},t.prototype.sendSession=function(t){if(this.vt.sendSession)if(this.lt&&this.V.dsn&&this.V._experiments&&this.V._experiments.newTransport){var n=u(cn(t,Vt(this.V.dsn,this.V.yt,this.V.tunnel)),1)[0];this.lt.send(n).then(null,(function(t){}))}else this.vt.sendSession(t).then(null,(function(t){}))},t.prototype.getTransport=function(){return this.vt},t.prototype.dt=function(){return new fn},t}();function vn(t,n,r){void 0===r&&(r=kt(t.bufferSize||30));var e={};return{send:function(t){var i=function(t){var n=u(t,2),r=u(n[1],1);return u(r[0],1)[0].type}(t),o="event"===i?"error":i,a={category:o,body:It(t)};return Ct(e,o)?_t({status:"rate_limit",reason:dn(e,o)}):r.add((function(){return n(a).then((function(t){var n=t.body,r=t.headers,i=t.reason,u=Ot(t.statusCode);return r&&(e=Lt(e,r)),"success"===u?Et({status:u,reason:i}):_t({status:u,reason:i||n||("rate_limit"===u?dn(e,o):"Unknown transport error")})}))}))},flush:function(t){return r.drain(t)}}}function dn(t,n){return"Too many "+n+" requests, backing off until: "+new Date(At(t,n)).toISOString()}var ln,yn="6.19.7",pn=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(){ln=Function.prototype.toString,Function.prototype.toString=function(){for(var t=[],n=0;n=0;n--){var r=t[n];if(r&&""!==r.filename&&"[native code]"!==r.filename)return r.filename||null}return null}function gn(t){try{if(t.stacktrace)return wn(t.stacktrace.frames);var n;try{n=t.exception.values[0].stacktrace.frames}catch(t){}return n?wn(n):null}catch(t){return null}}var xn=Object.freeze({__proto__:null,FunctionToString:pn,InboundFilters:bn}),En="?";function _n(t,n,r,e){var i={filename:t,function:n,in_app:!0};return void 0!==r&&(i.lineno=r),void 0!==e&&(i.colno=e),i}var Sn=/^\s*at (?:(.*?) ?\((?:address at )?)?((?:file|https?|blob|chrome-extension|address|native|eval|webpack||[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,kn=/\((\S*)(?::(\d+))(?::(\d+))\)/,jn=[30,function(t){var n=Sn.exec(t);if(n){if(n[2]&&0===n[2].indexOf("eval")){var r=kn.exec(n[2]);r&&(n[2]=r[1],n[3]=r[2],n[4]=r[3])}var e=u(Cn(n[1]||En,n[2]),2),i=e[0];return _n(e[1],i,n[3]?+n[3]:void 0,n[4]?+n[4]:void 0)}}],On=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|capacitor).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i,Tn=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,Rn=[50,function(t){var n,r=On.exec(t);if(r){if(r[3]&&r[3].indexOf(" > eval")>-1){var e=Tn.exec(r[3]);e&&(r[1]=r[1]||"eval",r[3]=e[1],r[4]=e[2],r[5]="")}var i=r[3],o=r[1]||En;return o=(n=u(Cn(o,i),2))[0],_n(i=n[1],o,r[4]?+r[4]:void 0,r[5]?+r[5]:void 0)}}],Dn=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,Nn=[40,function(t){var n=Dn.exec(t);return n?_n(n[2],n[1]||En,+n[3],n[4]?+n[4]:void 0):void 0}],qn=/ line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i,Mn=[10,function(t){var n=qn.exec(t);return n?_n(n[2],n[3]||En,+n[1]):void 0}],In=/ line (\d+), column (\d+)\s*(?:in (?:]+)>|([^)]+))\(.*\))? in (.*):\s*$/i,An=[20,function(t){var n=In.exec(t);return n?_n(n[5],n[3]||n[4]||En,+n[1],+n[2]):void 0}],Cn=function(t,n){var r=-1!==t.indexOf("safari-extension"),e=-1!==t.indexOf("safari-web-extension");return r||e?[-1!==t.indexOf("@")?t.split("@")[0]:En,r?"safari-extension:"+n:"safari-web-extension:"+n]:[t,n]};function Ln(t){var n=Pn(t),r={type:t&&t.name,value:Xn(t)};return n.length&&(r.stacktrace={frames:n}),void 0===r.type&&""===r.value&&(r.value="Unrecoverable error caught"),r}function Un(t){return{exception:{values:[Ln(t)]}}}function Pn(t){var n=t.stacktrace||t.stack||"",r=function(t){if(t){if("number"==typeof t.framesToPop)return t.framesToPop;if(Hn.test(t.message))return 1}return 0}(t);try{return function(){for(var t=[],n=0;n0}function sr(){ur+=1,setTimeout((function(){ur-=1}))}function cr(t,n,r){if(void 0===n&&(n={}),"function"!=typeof t)return t;try{var e=t.__sentry_wrapped__;if(e)return e;if(H(t))return t}catch(n){return t}var sentryWrapped=function(){var e=Array.prototype.slice.call(arguments);try{r&&"function"==typeof r&&r.apply(this,arguments);var o=e.map((function(t){return cr(t,n)}));return t.apply(this,o)}catch(t){throw sr(),Gt((function(r){r.addEventProcessor((function(t){return n.mechanism&&(pt(t,void 0,void 0),mt(t,n.mechanism)),t.extra=i(i({},t.extra),{arguments:e}),t})),captureException(t)})),t}};try{for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(sentryWrapped[o]=t[o])}catch(t){}P(sentryWrapped,t),U(t,"__sentry_wrapped__",sentryWrapped);try{Object.getOwnPropertyDescriptor(sentryWrapped,"name").configurable&&Object.defineProperty(sentryWrapped,"name",{get:function(){return t.name}})}catch(t){}return sentryWrapped}function fr(t){if(void 0===t&&(t={}),or.document&&t.eventId&&t.dsn){var n=or.document.createElement("script");n.async=!0,n.src=function(t,n){var r=R(t),e=Qt(r)+"embed/error-page/",i="dsn="+O(r);for(var o in n)if("dsn"!==o)if("user"===o){if(!n.user)continue;n.user.name&&(i+="&name="+encodeURIComponent(n.user.name)),n.user.email&&(i+="&email="+encodeURIComponent(n.user.email))}else i+="&"+encodeURIComponent(o)+"="+encodeURIComponent(n[o]);return e+"?"+i}(t.dsn,t),t.onLoad&&(n.onload=t.onLoad);var r=or.document.head||or.document.body;r&&r.appendChild(n)}}var hr=function(){function t(n){this.name=t.id,this.Tt={onerror:vr,onunhandledrejection:dr},this.V=i({onerror:!0,onunhandledrejection:!0},n)}return t.prototype.setupOnce=function(){Error.stackTraceLimit=50;var t=this.V;for(var n in t){var r=this.Tt[n];r&&t[n]&&(n,r(),this.Tt[n]=void 0)}},t.id="GlobalHandlers",t}();function vr(){et("error",(function(n){var r=u(pr(),2),e=r[0],i=r[1];if(e.getIntegration(hr)){var o=n.msg,a=n.url,s=n.line,c=n.column,f=n.error;if(!(ar()||f&&f.__sentry_own_request__)){var h=void 0===f&&p(o)?function(t,n,r,e){var i=/^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i,o=l(t)?t.message:t,u="Error",a=o.match(i);a&&(u=a[1],o=a[2]);return lr({exception:{values:[{type:u,value:o}]}},n,r,e)}(o,a,s,c):lr(Bn(f||o,void 0,i,!1),a,s,c);h.level=t.Severity.Error,yr(e,f,h,"onerror")}}}))}function dr(){et("unhandledrejection",(function(n){var r=u(pr(),2),e=r[0],i=r[1];if(e.getIntegration(hr)){var o=n;try{"reason"in n?o=n.reason:"detail"in n&&"reason"in n.detail&&(o=n.detail.reason)}catch(t){}if(ar()||o&&o.__sentry_own_request__)return!0;var a=m(o)?{exception:{values:[{type:"UnhandledRejection",value:"Non-Error promise rejection captured with value: "+String(o)}]}}:Bn(o,void 0,i,!0);a.level=t.Severity.Error,yr(e,o,a,"onunhandledrejection")}}))}function lr(t,n,r,e){var i=t.exception=t.exception||{},o=i.values=i.values||[],u=o[0]=o[0]||{},a=u.stacktrace=u.stacktrace||{},s=a.frames=a.frames||[],f=isNaN(parseInt(e,10))?void 0:e,h=isNaN(parseInt(r,10))?void 0:r,v=p(n)&&n.length>0?n:function(){var t=c();try{return t.document.location.href}catch(t){return""}}();return 0===s.length&&s.push({colno:f,filename:v,function:"?",in_app:!0,lineno:h}),t}function yr(t,n,r,e){mt(r,{handled:!1,type:e}),t.captureEvent(r,{originalException:n})}function pr(){var t=$t(),n=t.getClient();return[t,n&&n.getOptions().attachStacktrace]}var mr=["EventTarget","Window","Node","ApplicationCache","AudioTrackList","ChannelMergerNode","CryptoOperation","EventSource","FileReader","HTMLUnknownElement","IDBDatabase","IDBRequest","IDBTransaction","KeyOperation","MediaController","MessagePort","ModalWindow","Notification","SVGElementInstance","Screen","TextTrack","TextTrackCue","TextTrackList","WebSocket","WebSocketWorker","Worker","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload"],br=function(){function t(n){this.name=t.id,this.V=i({XMLHttpRequest:!0,eventTarget:!0,requestAnimationFrame:!0,setInterval:!0,setTimeout:!0},n)}return t.prototype.setupOnce=function(){var t=c();this.V.setTimeout&&L(t,"setTimeout",wr),this.V.setInterval&&L(t,"setInterval",wr),this.V.requestAnimationFrame&&L(t,"requestAnimationFrame",gr),this.V.XMLHttpRequest&&"XMLHttpRequest"in t&&L(XMLHttpRequest.prototype,"send",xr);var n=this.V.eventTarget;n&&(Array.isArray(n)?n:mr).forEach(Er)},t.id="TryCatch",t}();function wr(t){return function(){for(var n=[],r=0;r"}0!==r.length&&$t().addBreadcrumb({category:"ui."+n.name,message:r},{event:n.event,name:n.name,global:n.global})}return n}(this.V.dom)),this.V.xhr&&et("xhr",kr),this.V.fetch&&et("fetch",jr),this.V.history&&et("history",Or)},t.id="Breadcrumbs",t}();function Sr(t){var n={category:"console",data:{arguments:t.args,logger:"console"},level:jt(t.level),message:A(t.args," ")};if("assert"===t.level){if(!1!==t.args[0])return;n.message="Assertion failed: "+(A(t.args.slice(1)," ")||"console.assert"),n.data.arguments=t.args.slice(1)}$t().addBreadcrumb(n,{input:t.args,level:t.level})}function kr(t){if(t.endTimestamp){if(t.xhr.__sentry_own_request__)return;var n=t.xhr.__sentry_xhr__||{},r=n.method,e=n.url,i=n.status_code,o=n.body;$t().addBreadcrumb({category:"xhr",data:{method:r,url:e,status_code:i},type:"http"},{xhr:t.xhr,input:o})}else;}function jr(n){n.endTimestamp&&(n.fetchData.url.match(/sentry_key/)&&"POST"===n.fetchData.method||(n.error?$t().addBreadcrumb({category:"fetch",data:n.fetchData,level:t.Severity.Error,type:"http"},{data:n.error,input:n.args}):$t().addBreadcrumb({category:"fetch",data:i(i({},n.fetchData),{status_code:n.response.status}),type:"http"},{input:n.args,response:n.response})))}function Or(t){var n=c(),r=t.from,e=t.to,i=dt(n.location.href),o=dt(r),u=dt(e);o.path||(o=i),i.protocol===u.protocol&&i.host===u.host&&(e=u.relative),i.protocol===o.protocol&&i.host===o.host&&(r=o.relative),$t().addBreadcrumb({category:"navigation",data:{from:r,to:e}})}var Tr=function(){function t(n){void 0===n&&(n={}),this.name=t.id,this.Rt=n.key||"cause",this.Dt=n.limit||5}return t.prototype.setupOnce=function(){Ht((function(n,r){var e=$t().getIntegration(t);return e?function(t,n,r,e){if(!(r.exception&&r.exception.values&&e&&x(e.originalException,Error)))return r;var i=Rr(n,e.originalException,t);return r.exception.values=a(i,r.exception.values),r}(e.Rt,e.Dt,n,r):n}))},t.id="LinkedErrors",t}();function Rr(t,n,r,e){if(void 0===e&&(e=[]),!x(n[r],Error)||e.length+1>=t)return e;var i=Ln(n[r]);return Rr(t,n[r],r,a([i],e))}var Dr=c(),Nr=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(){Ht((function(n){if($t().getIntegration(t)){if(!Dr.navigator&&!Dr.location&&!Dr.document)return n;var r=n.request&&n.request.url||Dr.location&&Dr.location.href,e=(Dr.document||{}).referrer,o=(Dr.navigator||{}).userAgent,u=i(i(i({},n.request&&n.request.headers),e&&{Referer:e}),o&&{"User-Agent":o}),a=i(i({},r&&{url:r}),{headers:u});return i(i({},n),{request:a})}return n}))},t.id="UserAgent",t}(),qr=function(){function t(){this.name=t.id}return t.prototype.setupOnce=function(n,r){n((function(n){var e=r().getIntegration(t);if(e){try{if(function(t,n){if(!n)return!1;if(function(t,n){var r=t.message,e=n.message;if(!r&&!e)return!1;if(r&&!e||!r&&e)return!1;if(r!==e)return!1;if(!Ir(t,n))return!1;if(!Mr(t,n))return!1;return!0}(t,n))return!0;if(function(t,n){var r=Ar(n),e=Ar(t);if(!r||!e)return!1;if(r.type!==e.type||r.value!==e.value)return!1;if(!Ir(t,n))return!1;if(!Mr(t,n))return!1;return!0}(t,n))return!0;return!1}(n,e.Nt))return null}catch(t){return e.Nt=n}return e.Nt=n}return n}))},t.id="Dedupe",t}();function Mr(t,n){var r=Cr(t),e=Cr(n);if(!r&&!e)return!0;if(r&&!e||!r&&e)return!1;if(r=r,(e=e).length!==r.length)return!1;for(var i=0;i