{"version":3,"sources":["app.js","blob.js","config.js","exo.js","iosfix.js","markers.js","mdcontent.js","routes.js","run.js","tivoliarrow.js","filters/schoolCategoryString.js","services/adminAuthService.js","services/analyticsService.js","services/appService.js","services/authService.js","services/exerciseService.js","services/freeGameService.js","services/gameDayAuthService.js","services/gameService.js","services/keyboardService.js","services/locationService.js","services/logoutService.js","services/mdContentService.js","services/messageService.js","services/navService.js","services/pushService.js","services/simulatorService.js","services/stopwatchService.js","services/teacherAppService.js","services/welcomeService.js","controllers/administration/administrationIndexCtrl.js","controllers/app/appCtrl.js","controllers/config/configIndexCtrl.js","controllers/cookie/cookieCtrl.js","controllers/exercises/exercisesAddCtrl.js","controllers/exercises/exercisesAddEvaluationAnswerCtrl.js","controllers/exercises/exercisesIndexCtrl.js","controllers/freegame/freeGameIndexCtrl.js","controllers/home/homeIndexCtrl.js","controllers/profile/profileIndexCtrl.js","controllers/rides/ridesAddCtrl.js","controllers/rides/ridesIndexCtrl.js","controllers/simulator/simulatorCtrl.js","controllers/stats/ridesIndexCtrl.js","controllers/stats/statsIndexCtrl.js","controllers/student/studentIndexCtrl.js","controllers/teacher/teacher.js","controllers/teacher/teacherEvaluationCtrl.js","controllers/teacher/teacherGroupDetailsCtrl.js","controllers/teacher/teacherGroupsCtrl.js","controllers/teacher/teacherIndexCtrl.js","controllers/teacher/teacherInfoCtrl.js","controllers/teacher/teacherLoginCtrl.js","controllers/teacher/teacherSetupExercisesCtrl.js","controllers/teacher/teacherSetupGroupsCtrl.js","controllers/teacher/teacherSignupCtrl.js","controllers/teacherapp/teacherAppIndexCtrl.js","controllers/testticket/testTicketIndexCtrl.js","controllers/preview/exercisebegin/previewExerciseBeginCtrl.js","controllers/preview/exercisedone/previewExerciseDoneCtrl.js","controllers/preview/exerciseevalbegin/previewExerciseEvalBeginCtrl.js","controllers/preview/exerciseevalperform/previewExerciseEvalPerformCtrl.js","controllers/preview/exerciseperform/previewExercisePerformCtrl.js","controllers/shared/partials/headerCtrl.js","controllers/shared/partials/navCtrl.js","controllers/shared/partials/shellCtrl.js","controllers/student/carousel/studentCarouselCtrl.js","controllers/student/exercisebegin/studentExerciseBeginCtrl.js","controllers/student/exercisedone/studentExerciseDoneCtrl.js","controllers/student/exerciseevalbegin/studentExerciseEvalBeginCtrl.js","controllers/student/exerciseevalperform/studentExerciseEvalPerformCtrl.js","controllers/student/exercisemap/studentExerciseMapCtrl.js","controllers/student/exerciseperform/studentExercisePerformCtrl.js","controllers/student/exercises/studentExercisesCtrl.js","controllers/student/freegameperform/studentFreeGamePerformCtrl.js","controllers/student/login/studentLoginCtrl.js","controllers/student/messages/studentMessagesCtrl.js","controllers/student/trophy/trophyIndexCtrl.js","controllers/student/welcome1/studentWelcome1Ctrl.js","controllers/student/welcome2/studentWelcome2Ctrl.js","controllers/student/welcome3/studentWelcome3Ctrl.js","controllers/student/welcome3/studentWelcome3CtrlOrig.js","controllers/student/welcome4/studentWelcome4Ctrl.js","controllers/student/welcome5/studentWelcome5Ctrl.js","controllers/student/worthknowing/studentWorthKnowingCtrl.js","controllers/teacherapp/exercisebegin/teacherAppExerciseBeginCtrl.js","controllers/teacherapp/exercisedone/teacherAppExerciseDoneCtrl.js","controllers/teacherapp/exerciseevalbegin/teacherAppExerciseEvalBeginCtrl.js","controllers/teacherapp/exerciseevalperform/teacherAppExerciseEvalPerformCtrl.js","controllers/teacherapp/exercisemap/studentExerciseMapCtrl.js","controllers/teacherapp/exerciseperform/teacherAppExercisePerformCtrl.js","controllers/teacherapp/exercises/teacherAppExercisesCtrl.js","controllers/teacherapp/groupmap/teacherAppGroupMapCtrl.js","controllers/teacherapp/groupstatus/teacherAppGroupStatusCtrl.js","controllers/teacherapp/groupstatus/teacherAppGroupStatusDetailsCtrl.js","controllers/teacherapp/groupstatus/teacherAppGroupStatusDetailsMapCtrl.js","controllers/teacherapp/messages/teacherAppMessagesCtrl.js","controllers/teacherapp/welcome/teacherAppWelcomeCtrl.js"],"names":["app","angular","module","window","FD","BlobToDataURL","blob","Promise","resolve","reject","fr","FileReader","onload","evt","target","result","readAsDataURL","config","$breadcrumbProvider","$mdThemingProvider","$logProvider","setOptions","templateUrl","global","version","custom","extendPalette","hue-1","300","500","600","A100","A200","A400","A700","definePalette","theme","primaryPalette","accentPalette","debugEnabled","exo","listeners","broadcast","name","args","_i","listeners_1","length","listener","addBroadcastListener","callback","push","removeBroadcastListener","newListeners","listeners_2","currentUniqueIdentifierCounter","generateUniqueIdentifier","uniqueIdentifierNumber","concat","performOperation","arguments","uniqueIdentifier","obj","cb","operationCompleteArgs","typeName","jsonData","failedWithErrorArgs","errorMessage","webkit","exoAndroid","operation","JSON","stringify","messageHandlers","postMessage","inAppPurchase","list","identifiers","then","productList","parse","err","purchase","identifier","status","syncPurchases","videoPlayer","play","url","iosOnFocus","undefined","__shouldiOSFix","navigator","userAgent","indexOf","triggerMdContentScroll","elems","element","i","elem","os","attributes","value","onMdContentScroll","orTarget","className","totalHeight","scrollHeight","scrollTop","containerHeight","clientHeight","scrollBottom","scrollDelta","pct","cls","split","asdf","join","$locationProvider","$stateProvider","html5Mode","hashPrefix","state","controller","me","authService","ncyBreadcrumb","label","redirectTo","template","run","$q","$timeout","$transitions","$rootScope","navService","gameService","freeGameService","gameDayAuthService","adminAuthService","locationService","mdContentService","pushService","onStart","transition","to","isAuthenticated","router","stateService","setupFreeGame","authStatus","ensureRunning","ensureGameDataIsLoaded","isWelcomeNotFinished","isGameDone","console","log","location","onSuccess","close","$on","event","triggerSyntheticScrollEvent","TivoliArrow","parent","this","running","start","canvas","document","createElement","appendChild","redraw","bind","stop","ctx","getContext","devicePixelRatio","backingStoreRatio","webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio","canvasScalingRatio","Math","max","w","parentElement","clientWidth","h","width","height","style","scale","scaledh","arrowHead","Path2D","arrowEnd1","arrowEnd2","xofs","yofs","save","translate","fill","restore","beginPath","x1","round","y1","moveTo","x2","y2","lineTo","lineWidth","stroke","requestAnimationFrame","filter","input","factory","$window","service","authCookie","cookie","idx","sub","substring","end","key","substr","$http","params","post","$state","isApp","pathname","isStudentApp","isTeacherApp","isTeacherBackendSystem","isAdminSystem","isiOS","isiPhoneX","isAndroid","clearCookies","handler","tuAndroid","setCookieState","showCookieDialog","$broadcast","showCookieRemoveDialog","welcomeService","teacherAppService","messageService","appService","get","resp","dir","data","isTeacher","restart","response","tempPin","cookiePinCode","pin","cookiePin","ok","authenticateWithPin","pinCode","setCookie","headers","setInitialState","permission","startAndSyncImmediately","ready","$mdMedia","$mdDialog","$mdToast","exercises","loaded","id","load","items","askDelete","exercise","ev","preventDefault","confirm","title","textContent","ariaLabel","targetEvent","cancel","show","simple","position","hideDelay","reload","indexify","collection","forEachFunc","item","index","game","copy","questions","question","answers","evaluationQuestions","exerciseWithIndex","exerciseIndex","lookupQuestion","questionIndex","keyString","startTime","Date","teamName","teamImageURL","teamMembers","rides","gameState","finishedWelcome","evaluationQuestionIndex","score","evaluationAnswers","titleCaseTeamName","out","doUpper","ch","toUpperCase","toLowerCase","setTeacherAppState","gameConfig","gameDayInfo","year","parseInt","startDayYMD","month","day","lookupEvaluationQuestion","setTeamInfo","setPushToken","token","pushToken","uploadTeamImage","fileObj","setWelcomeFinished","finished","put","setGameState","newState","getGameState","resetGameState","cleanSlate","mediaQuery","matchMedia","addListener","isShown","matches","shown","lastPosition","useFakeLocation","fakeLocation","lng","lat","onLocationUpdated","forceSyncLocation","loc","getLocation","exoPosition","latitude","longitude","pos","lastLocation","lastLocationUpdateTime","getTime","distanceInKM","pos1","pos2","deg2rad","deg","PI","R","dLat","dLon","a","sin","cos","c","atan2","sqrt","d","go","logout","$interval","analyticsService","unreadCount","lastRead","started","paused","fullSync","messageServiceUpdateIntervalSecs","opts","messages","updateUnreadCount","message","timestamp","setLastRead","sendMessage","msgObj","showButtons","toggle","open","$log","isIE","showWithExercise","debug","alert","localStorage","setItem","showWithEvalExercise","showFullExerciseFlowWithExercise","stopwatches","serialize","deserialize","stopwatchesJson","getItem","e","timeUnix","getKey","entry","elapsed","gameInfo","hasImage","currentGroup","currentGameInfo","groupPickerScrollOffset","isReady","setCurrentGroup","noImage","teacherAppUpdateIntervalSecs","w1imageStyle","background-image","background-size","$scope","user-select","vm","categories","configOptions","category","description","type","defaultValue","defaultvalue","prettyCategoryName","parseHierarchy","hier","options","j","configOption","categoryCopy","hierarchy","loading","configData","href","currentCookieState","cookieStateIsSupported","mode","functional","statistics","hide","$event","onlyFunctional","accept","toggleChanged","$stateParams","Upload","exerciseService","simulatorService","maxTimeMinutes","minutes","schoolCategories","tivoliCenter","form","submitting","model","schoolCategory","number","imageUrl","timeMinutes","teacherInfoShortText","teacherInfoLongText","mapPos","mapText","goalsText","goals","q","hidden","hideQuestion","showQuestion","addQuestion","container","questionObj","text","extraButtonText","extraHtml","wrongAnswerText","correct","listOrderChanged","$apply","removeQuestion","newQuestions","iterQuestion","pop","newQ","uploading","upload","file","dataUrl","removeImage","map","maptalks","Map","center","zoom","bearing","attribution","dragPitch","dragRotate","dragRotatePitch","baseLayer","TileLayer","urlTemplate","subdomains","getCenter","mapOverlayLayer","VectorLayer","addTo","targetMarker","Marker","symbol","markerFile","origin","markerWidth","markerHeight","markerDx","markerDy","markerOpacity","on","setCoordinates","coordinate","x","y","$watch","resetMap","setCenter","setZoom","setBearing","previewQuestion","$valid","Content-Type","$setValidity","allExercises","selectedExercise","getExercise","onExerciseSelected","exerciseCopy","removeExercise","newExercises","freeGameData","created","modified","timeImageURL","email","password","passwordAgain","markerImage","markerScaleFactor","markerZIndex","enabled","ride","exerciseSet","nested","srcUrl","src","onMessageReceived","addEventListener","$locale","$filter","NUMBER_FORMATS","GROUP_SEP","DECIMAL_SEP","chosenWeek","chosenSchoolCategory","fetchData","stats","weeks","exerciseComplete","makeChart","completedExercises","teacherMsg","teacherMessages","popularExercises","makeExerciseChart","exerciseTime","makeExerciseTimeChart","averageTimeSpentPerExercise","exerciseStats","questionStats","numberOfTriesChart","makeNumberOfTriesChart","numTriesGroups","completionTimeGroupsChart","makeCompletionTimeChart","completionTimeGroups","statsData","chart","labels","datasetOverride","yAxisID","scales","yAxes","display","series","xAxes","ticks","beginAtZero","tooltips","callbacks","tooltipItem","datasets","datasetIndex","xLabel","num0to15","num15to30","num30orGreater","numberOfTriesGroups","firstTry","secondTry","thirdTry","fourthTry","games","gameStates","gameDay","gameIndex","setGameIndex","print","members","Array","iterGame","min","sanitizedMembers","newMembers","member","trimmedMember","trim","done","includeExercisesInPrint","selectedExercises","exerciseTooltipShown","exerciseTooltipExpand","previewExercise","ids","isSelected","gdpe","add","edit","next","ymdZeroPadNumber","num","str","getYMD","date","getYear","m","getMonth","getDate","genTeacherName","minLen","maxLen","Cstart","charCodeAt","Cend","Clen","Lstart","Lend","Llen","len","floor","random","String","fromCharCode","genTeacherFullName","firstName","lastName","genRandom","Nstart","Nend","Nlen","kind","genUrl","ymd","visualId","orderNo","teacherName","encodeURIComponent","regenWithKey","testTicket46","testTicket79","regen","setupExercise","fullFlow","initialize","progressIndex","progressCount","progressArray","exerciseJson","questionIndexStr","ebimageStyle","arrow","confetti","TG","Confetti","viewport","getElementsByClassName","texture","particleCount","particleScale","fireConfettiLoop","fireCenterCannon","initiateConfettiLoop","dispose","points","activeAnswers","popupShown","answer","answerIndex","helpAvailable","firstRun","helpShown","showMathLoader","performAnswer","answerObj","reduce","acc","val","hidePopup","MathJax","Hub","Queue","showHelp","hideHelp","elements","scrollTo","openNav","closeNav","isLogin","isCurrentPage","isFreeGame","isPreview","current","isStateOrAncestor","goHome","goLogin","goTeacherMessages","goStudentMessages","logoutService","isActualPage","studentItemsFiltered","teacherItems","teacherAppItems","tivoliItems","displayName","iconClass","bigIcon","iconUrl","showRemoveButton","isContainedInMdContent","child","tagName","touchStartPoint","touchStartContentOffset","contentOffset","disablePanning","enabledPages","onTouchStart","numPages","children","performance","now","touch","touches","screenX","screenY","onTouchEnd","lastX","snap","onTouchCancel","lastT","velocity","animationStartT","animationDuration","animationLastT","animateFromX","animateToX","moveDelta","onTouchMove","vw","documentElement","innerWidth","point","dx","dy","dpoint","newOffsetX","maxOffsetX","page","abs","transform","dt","ofs","innerHeight","prevPage","ceilPage","ceil","floorPage","animateSnap","newPage","lastRequestedAnimationFrameId","onAnimationFrame","onAnimationUpdate","EaseOutSine","t","b","v","pageNav","offset","nextPage","indexOfPage","pageScope","n","ce","scope","stopwatchService","evaluationQuestionAnswers","evaluationQuestionAnswerArray","exercise_id","exercise_version","question_idx","answer_idx","numTries","stopwatch","start_time","end_time","elapsed_time","num_tries","curPos","targetPos","targetOKDistanceKM","closeEnough","nonInteractive","mapCenter","layer","rideMarkers","marker","youMarker","_intervalPromise","distanceKM","allowMapClickThrough","lastQuestion","keyboardService","keyboardShown","loggingIn","pin1","pin2","pin3","pin4","resetPin","pin1change","focus","pin1keydown","pin2change","pin2keydown","keyCode","pin3change","pin3keydown","pin4change","pin4keydown","error","login","goFreeGame","trimmedTeamName","trophyTeamName","fireLeftCannon","fireRightCannon","timeRemainingMsecs","timeRemainingSecs","onTeamInfoUpdated","updateClockDisplay","trs","hr","mr","daysRemain","hoursRemain","minutesRemain","secondsRemain","countdownId","onTeamNameChanged","$parent","prev","canProceed","showPlaceHolder","allowSkipIntroMovie","skipPercentage","introMoviePassPercentage","isPlaying","playVideo","video","$","onVideoTimeUpdated","pause","percentage","duration","currentTime","onCanProceedChanged","updateCanProceed","updateMarkerLocations","gameMarkers","createGameMarkers","gameInfos","locationState","setZIndex","countGameStateProgress","count","gameInverseProgressStyle","gameProgress","showDetails","updateStateFromTeacherAppService","totalItems","gi","progress","countTotalItemsForGameInfo","nitems","itemsPerExerciseForGameInfo","itemsPerExercise","percentagePerExerciseForGameInfo","percentagePerExercise","gameExercisePercentages","gameExerciseListStyle","filterExercises","switchGroup","groupPickerElement","scrollLeft","goMap","goBack","goExercise","qeustion","gameExercisePercentage","styles","exercisePercentage","flex","msFlex","gameMarker","createGameMarker","messageText","from","timestmap","temporaryConfigNoRealTeacherName","tn"],"mappings":"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","file":"app.js","sourcesContent":["var app = angular.module('app', [\r\n\t\t\"ngSanitize\",\r\n 'ui.router',\r\n 'ngAnimate',\r\n 'ncy-angular-breadcrumb',\r\n 'ngMaterial',\r\n 'ngMessages',\r\n 'ngFileUpload',\r\n 'ui.sortable',\r\n 'chart.js'\r\n]);\r\n","window.FD = {}\n\nwindow.FD.BlobToDataURL = function(blob) {\n\treturn new Promise(function(resolve, reject) {\n\t\tif (!blob) {\n\t\t\treject(\"null blob\");\n\t\t\treturn;\n\t\t}\n\t\tvar fr = new FileReader();\n\t\tfr.onload = function(evt) {\n\t\t\tresolve(evt.target.result);\n\t\t}\n\t\tfr.readAsDataURL(blob);\n\t});\n}\n","app.config(['$breadcrumbProvider', '$mdThemingProvider', '$logProvider', function ($breadcrumbProvider, $mdThemingProvider, $logProvider) {\n $breadcrumbProvider.setOptions({\n templateUrl: '/ng-views/shared/partials/breadcrumbslist.html?v=' + global.version\n });\n\n var custom = $mdThemingProvider.extendPalette('indigo', {\n 'hue-1': '300',\n '300': '#728097',\n '500': '#3777bc',\n '600': '#303543',\n 'A100': '#ff8a80',\n 'A200': '#303543',\n 'A400': '#ff1744',\n 'A700': '#d50000'\n });\n // Register the new color palette map with the name neonRed\n $mdThemingProvider.definePalette('custom', custom);\n // Use that theme for the primary intentions\n $mdThemingProvider.theme('default')\n .primaryPalette('custom')\n .accentPalette('custom');\n\n $logProvider.debugEnabled(true);\n\n}]);\n","\"use strict\";\n// Exoskeleton JS interface\n// Copyright 2015-2024 Interitsement ApS\n// REMOVED: This refers to exports which tsc does not emit: Object.defineProperty(exports, \"__esModule\", { value: true });\nwindow.exo = {\n listeners: []\n};\nwindow.exo.broadcast = function (name, args) {\n var listeners = window.exo.listeners;\n for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) {\n var listener = listeners_1[_i];\n if (listener != null) {\n listener(name, args);\n }\n }\n};\nwindow.exo.addBroadcastListener = function (callback) {\n window.exo.listeners.push(callback);\n};\nwindow.exo.removeBroadcastListener = function (callback) {\n var newListeners = [];\n var listeners = window.exo.listeners;\n for (var _i = 0, listeners_2 = listeners; _i < listeners_2.length; _i++) {\n var listener = listeners_2[_i];\n if (listener == callback) {\n continue;\n }\n newListeners.push(listener);\n }\n window.exo.listeners = newListeners;\n};\nwindow.exo.currentUniqueIdentifierCounter = 0;\nwindow.exo.generateUniqueIdentifier = function () {\n var uniqueIdentifierNumber = window.exo.currentUniqueIdentifierCounter;\n window.exo.currentUniqueIdentifierCounter += 1;\n return \"exo:\".concat(uniqueIdentifierNumber);\n};\nwindow.exo.performOperation = function (name) {\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n var uniqueIdentifier = window.exo.generateUniqueIdentifier();\n return new Promise(function (resolve, reject) {\n var obj = {\n name: name,\n uniqueIdentifier: uniqueIdentifier,\n arguments: args\n };\n var cb = function (name, args) {\n if (name == \"Exo.OperationComplete\") {\n var operationCompleteArgs = args;\n if (operationCompleteArgs.uniqueIdentifier != uniqueIdentifier) {\n return;\n }\n resolve({\n typeName: operationCompleteArgs.typeName,\n jsonData: operationCompleteArgs.jsonData\n });\n window.exo.removeBroadcastListener(cb);\n }\n else if (name == \"Exo.OperationFailedWithError\") {\n var failedWithErrorArgs = args;\n if (failedWithErrorArgs.uniqueIdentifier != uniqueIdentifier) {\n return;\n }\n reject({\n errorMessage: failedWithErrorArgs.errorMessage\n });\n window.exo.removeBroadcastListener(cb);\n }\n };\n window.exo.addBroadcastListener(cb);\n if (window.webkit == null) {\n window.exoAndroid.operation(JSON.stringify(obj));\n }\n else {\n window.webkit.messageHandlers.operation.postMessage(obj);\n }\n });\n};\nwindow.exo.inAppPurchase = {};\nwindow.exo.inAppPurchase.list = function (identifiers) {\n return new Promise(function (resolve, reject) {\n window.exo.performOperation(\"Exo.InAppPurchase.List\", identifiers).then(function (result) {\n var productList = JSON.parse(result.jsonData);\n resolve(productList);\n }, function (err) {\n reject(err);\n });\n });\n};\nwindow.exo.inAppPurchase.purchase = function (identifier) {\n return new Promise(function (resolve, reject) {\n window.exo.performOperation(\"Exo.InAppPurchase.Purchase\", identifier).then(function (result) {\n var status = JSON.parse(result.jsonData);\n resolve(status);\n }, function (err) {\n reject(err);\n });\n });\n};\nwindow.exo.inAppPurchase.syncPurchases = function () {\n return new Promise(function (resolve, reject) {\n window.exo.performOperation(\"Exo.InAppPurchase.SyncPurchases\").then(function () {\n resolve();\n }, function (err) {\n reject(err);\n });\n });\n};\nwindow.exo.videoPlayer = {};\nwindow.exo.videoPlayer.play = function (url) {\n return new Promise(function (resolve, reject) {\n window.exo.performOperation(\"Exo.VideoPlayer.Play\", url).then(function () {\n resolve();\n }, function (err) {\n reject(err);\n });\n });\n};\n","window.__shouldiOSFix = undefined;\r\n\r\nfunction iosOnFocus() {\r\n\tif (window.__shouldiOSFix === undefined) {\r\n\t\tif (window.navigator.userAgent.indexOf(\"FagligeDageiOS\") !== -1) {\r\n\t\t\twindow.__shouldiOSFix = true;\r\n\t\t} else {\r\n\t\t\twindow.__shouldiOSFix = false;\r\n\t\t}\r\n\t}\r\n\r\n\tif (window.__shouldiOSFix) {\r\n\t\t//window.scrollTo(0, 0);\r\n\t\t//document.body.scrollTop = 0;\r\n\t}\r\n}\r\n","","function triggerMdContentScroll() {\r\n\tvar elems = angular.element(\"[onscroll]\");\r\n\tfor (var i = 0; i < elems.length; i++) {\r\n\t\tvar elem = elems[i];\r\n\t\tvar os = elem.attributes[\"onscroll\"];\r\n\t\tif (!os) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (os.value.indexOf(\"onMdContentScroll\") != 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tonMdContentScroll(null, elem);\r\n\t}\r\n}\r\n\r\nfunction onMdContentScroll(evt, orTarget) {\r\n\tvar target;\r\n\r\n\tif (evt) {\r\n\t\ttarget = evt.target;\r\n\t}\r\n\tif (orTarget) {\r\n\t\ttarget = orTarget;\r\n\t}\r\n\r\n\tif (target.className.indexOf(\"autofade\") === -1) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tvar totalHeight = target.scrollHeight;\r\n\tvar scrollTop = target.scrollTop;\r\n\tvar containerHeight = target.clientHeight;\r\n\tvar scrollBottom = totalHeight - scrollTop - containerHeight;\r\n\r\n\tvar scrollDelta = totalHeight - containerHeight;\r\n\tvar pct = 0.0;\r\n\t// Only calculate this for scrollDelta > 0, not scrollDelta == 0.\r\n\t// Otherwise we'll divide by zero. Also, scrollDelta == 0 means that\r\n\t// we don't scroll at all, so our percentage should be 0%.\r\n\tif (scrollDelta > 0) {\r\n\t\tpct = (scrollBottom*4) / scrollDelta;\r\n\t}\r\n\r\n\tvar cls = target.className.split(\" \");\r\n\r\n\t// Find original classNames.\r\n\tvar asdf = [];\r\n\tfor (var i = 0; i < cls.length; i++) {\r\n\t\tvar kls = cls[i];\r\n\t\tif (cls[i].indexOf(\"__mdfade\") === 0) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tasdf.push(cls[i]);\r\n\t}\r\n\r\n\tif (pct >= 0.99) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_100\";\r\n\t} else if (pct >= 0.9) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_90\";\r\n\t} else if (pct >= 0.8) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_80\";\r\n\t} else if (pct >= 0.7) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_70\";\r\n\t} else if (pct >= 0.6) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_60\";\r\n\t} else if (pct >= 0.5) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_50\";\r\n\t} else if (pct >= 0.4) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_40\";\r\n\t} else if (pct >= 0.3) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_30\";\r\n\t} else if (pct >= 0.2) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_20\";\r\n\t} else if (pct >= 0.1) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_10\";\r\n\t} else if (pct < 0.1) {\r\n\t\ttarget.className = asdf.join(\" \") + \" __mdfade_bottom_0\";\r\n\t}\r\n}\r\n","app.config(['$locationProvider', '$stateProvider', function ($locationProvider, $stateProvider) {\r\n $locationProvider.html5Mode(true);\r\n $locationProvider.hashPrefix('!');\r\n $stateProvider\r\n .state('home',\r\n {\r\n url: '/',\r\n templateUrl: '/ng-views/home/index.html?v=' + global.version,\r\n controller: 'homeIndexCtrl',\r\n resolve: { \r\n 'me': [\r\n 'authService', function (authService) {\r\n return authService.me();\r\n }\r\n ]\r\n },\r\n ncyBreadcrumb: {\r\n label: 'Hjem'\r\n }\r\n })\r\n .state('exercises',\r\n {\r\n url: '/exercises',\r\n templateUrl: '/ng-views/exercises/index.html?v=' + global.version,\r\n controller: 'exercisesIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Opgaver'\r\n }\r\n })\r\n .state('exercises.add',\r\n {\r\n url: '/add',\r\n templateUrl: '/ng-views/exercises/add.html?v=' + global.version,\r\n controller: 'exercisesAddCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Tilføj opgave'\r\n }\r\n })\r\n .state('exercises.details',\r\n {\r\n url: '/details/{id}',\r\n templateUrl: '/ng-views/exercises/add.html?v=' + global.version,\r\n controller: 'exercisesAddCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: '{{exercise.name}}'\r\n }\r\n })\r\n .state('config',\r\n {\r\n url: '/config',\r\n templateUrl: '/ng-views/config/index.html?v=' + global.version,\r\n controller: 'configIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Config'\r\n }\r\n })\r\n .state('testticket',\r\n {\r\n url: '/testticket',\r\n templateUrl: '/ng-views/testticket/index.html?v=' + global.version,\r\n controller: 'testTicketIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Test-billeter'\r\n }\r\n })\r\n .state('rides',\r\n {\r\n url: '/rides',\r\n templateUrl: '/ng-views/rides/index.html?v=' + global.version,\r\n controller: 'ridesIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Forlystelser'\r\n }\r\n })\r\n .state('rides.add',\r\n {\r\n url: '/add',\r\n templateUrl: '/ng-views/rides/add.html?v=' + global.version,\r\n controller: 'ridesAddCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Tilføj forlystelse'\r\n }\r\n })\r\n .state('rides.details',\r\n {\r\n url: '/details/{id}',\r\n templateUrl: '/ng-views/rides/add.html?v=' + global.version,\r\n controller: 'ridesAddCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: '{{ride.name}}'\r\n }\r\n })\r\n .state('stats',\r\n {\r\n url: '/stats',\r\n templateUrl: '/ng-views/stats/index.html?v=' + global.version,\r\n controller: 'statsIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Statistik'\r\n }\r\n })\r\n .state('freegame',\r\n {\r\n url: '/freegame',\r\n templateUrl: '/ng-views/freegame/index.html?v=' + global.version,\r\n controller: 'freeGameIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Den åbne opgave'\r\n }\r\n })\r\n .state('administration',\r\n {\r\n url: '/administration',\r\n templateUrl: '/ng-views/administration/index.html?v=' + global.version,\r\n controller: 'administrationIndexCtrl',\r\n ncyBreadcrumb: {\r\n label: 'Administration'\r\n }\r\n })\r\n .state('teacher',\r\n {\r\n url: '/teacher',\r\n redirectTo: 'teacher.signup',\r\n templateUrl: '/ng-views/teacher/index.html?v=' + global.version,\r\n ncyBreadcrumb: {\r\n label: 'Lærer'\r\n },\r\n\r\n })\r\n .state('teacher.login',\r\n {\r\n url: '/login',\r\n templateUrl: '/ng-views/teacher/login/index.html?=v' + global.version,\r\n controller: 'teacherLoginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Login'\r\n }\r\n })\r\n .state('teacher.signup',\r\n {\r\n url: '/welcome',\r\n templateUrl: '/ng-views/teacher/signup/index.html?v=' + global.version,\r\n controller: 'teacherSignupCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Velkommen til Faglige Dage'\r\n }\r\n })\r\n .state('teacher.setupexercises',\r\n {\r\n url: '/setupexercises',\r\n templateUrl: '/ng-views/teacher/setupexercises/index.html?v=' + global.version,\r\n controller: 'teacherSetupExercisesCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Vælg opgaver'\r\n }\r\n })\r\n .state('teacher.setupgroups',\r\n {\r\n url: '/setupgroups',\r\n templateUrl: '/ng-views/teacher/setupgroups/index.html?v=' + global.version,\r\n controller: 'teacherSetupGroupsCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Opret grupper'\r\n }\r\n })\r\n .state('teacher.groupdetails',\r\n {\r\n url: '/groupdetails/:id',\r\n templateUrl: '/ng-views/teacher/groupdetails/index.html?v=' + global.version,\r\n controller: 'teacherGroupDetailsCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Redigér gruppe'\r\n }\r\n })\r\n .state('teacher.groups',\r\n {\r\n url: '/groups',\r\n templateUrl: '/ng-views/teacher/groups/index.html?v=' + global.version,\r\n controller: 'teacherGroupsCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Gruppeoversigt'\r\n }\r\n })\r\n .state('teacher.evaluation',\r\n {\r\n url: '/evaluation',\r\n templateUrl: '/ng-views/teacher/evaluation/index.html?v=' + global.version,\r\n controller: 'teacherEvaluationCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Evaluering'\r\n }\r\n })\r\n .state('teacher.info',\r\n {\r\n url: '/info',\r\n templateUrl: '/ng-views/teacher/info/index.html?=v' + global.version,\r\n controller: 'teacherInfoCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Vigtig info'\r\n }\r\n })\r\n .state('profile',\r\n {\r\n url: '/profile',\r\n templateUrl: '/ng-views/profile/index.html?v=' + global.version,\r\n resolve: { \r\n 'me': [\r\n 'authService', function (authService) {\r\n return authService.me();\r\n }\r\n ]\r\n },\r\n controller: 'profileIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Min Profil'\r\n }\r\n })\r\n .state('teacherapp',\r\n {\r\n url: '/teacherapp',\r\n templateUrl: '/ng-views/teacherapp/index.html?v=' + global.version,\r\n controller: 'teacherAppIndexCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'LærerApp'\r\n }\r\n })\r\n .state('teacherapp.welcome',\r\n {\r\n url: '/welcome',\r\n templateUrl: '/ng-views/teacherapp/welcome/index.html?v=' + global.version,\r\n controller: 'teacherAppWelcomeCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Velkommen'\r\n }\r\n })\r\n .state('teacherapp.groupstatus',\r\n {\r\n url: '/groupstatus',\r\n templateUrl: '/ng-views/teacherapp/groupstatus/index.html?v=' + global.version,\r\n controller: 'teacherAppGroupStatusDetailsCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Groupstatus'\r\n }\r\n })\r\n .state('teacherapp.groupstatus.details',\r\n {\r\n url: '/details/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/groupstatus/details.html?v=' + global.version,\r\n controller: 'teacherAppGroupStatusDetailsCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Detaljer'\r\n }\r\n })\r\n .state('teacherapp.groupstatus.detailsmap',\r\n {\r\n url: '/detailsmap/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/groupstatus/detailsmap.html?v=' + global.version,\r\n controller: 'teacherAppGroupStatusDetailsMapCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Detaljer'\r\n }\r\n })\r\n .state('teacherapp.exercises',\r\n {\r\n url: '/exercises',\r\n templateUrl: '/ng-views/teacherapp/exercises/index.html?v=' + global.version,\r\n controller: 'teacherAppExercisesCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Opgaveliste'\r\n }\r\n })\r\n .state('teacherapp.exercisemap',\r\n {\r\n url: '/exercisemap/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/exercisemap/index.html?v=' + global.version,\r\n controller: 'teacherAppExerciseMapCtrl',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveKort'\r\n }\r\n })\r\n .state('teacherapp.exercisebegin',\r\n {\r\n url: '/exercisebegin/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/exercisebegin/index.html?v=' + global.version,\r\n controller: 'teacherAppExerciseBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveBegynd'\r\n }\r\n })\r\n .state('teacherapp.exerciseperform',\r\n {\r\n url: '/exerciseperform/{id:int}/{question:int}',\r\n templateUrl: '/ng-views/teacherapp/exerciseperform/index.html?v=' + global.version,\r\n controller: 'teacherAppExercisePerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDo'\r\n }\r\n })\r\n .state('teacherapp.exerciseevalbegin',\r\n {\r\n url: '/exerciseevalbegin/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/exerciseevalbegin/index.html?v=' + global.version,\r\n controller: 'teacherAppExerciseEvalBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalBegynd'\r\n }\r\n })\r\n .state('teacherapp.exerciseevalperform',\r\n {\r\n url: '/exerciseevalperform/{id:int}/{question:int}',\r\n templateUrl: '/ng-views/teacherapp/exerciseevalperform/index.html?v=' + global.version,\r\n controller: 'teacherAppExerciseEvalPerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalDo'\r\n }\r\n })\r\n .state('teacherapp.exercisedone',\r\n {\r\n url: '/exercisedone/{id:int}',\r\n templateUrl: '/ng-views/teacherapp/exercisedone/index.html?v=' + global.version,\r\n controller: 'teacherAppExerciseDoneCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDone'\r\n }\r\n })\r\n .state('teacherapp.groupmap',\r\n {\r\n url: '/groupmap',\r\n templateUrl: '/ng-views/teacherapp/groupmap/index.html?v=' + global.version,\r\n controller: 'teacherAppGroupMapCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Group Map'\r\n }\r\n })\r\n .state('teacherapp.messages',\r\n {\r\n url: '/messages',\r\n templateUrl: '/ng-views/teacherapp/messages/index.html?v=' + global.version,\r\n controller: 'teacherAppMessagesCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Beskeder'\r\n }\r\n })\r\n .state('student',\r\n {\r\n url: '/student',\r\n templateUrl: '/ng-views/student/index.html?v=' + global.version,\r\n ncyBreadcrumb: {\r\n label: 'Elev'\r\n }\r\n }\r\n )\r\n .state('student.login',\r\n {\r\n url: '/login',\r\n templateUrl: '/ng-views/student/login/index.html?=v' + global.version,\r\n controller: 'studentLoginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Login'\r\n }\r\n })\r\n .state('student.welcome',\r\n {\r\n url: '/welcome',\r\n templateUrl: '/ng-views/student/carousel/index.html?v=' + global.version,\r\n controller: 'studentCarouselCtrl',\r\n ncyBreadcrumb: {\r\n label: 'Velkommen'\r\n }\r\n })\r\n .state('student.exercises',\r\n {\r\n url: '/exercises',\r\n templateUrl: '/ng-views/student/exercises/index.html?v=' + global.version,\r\n controller: 'studentExercisesCtrl',\r\n ncyBreadcrumb: {\r\n label: 'Velkommen'\r\n }\r\n })\r\n .state('student.exercisemap',\r\n {\r\n url: '/exercisemap/{id:int}',\r\n templateUrl: '/ng-views/student/exercisemap/index.html?v=' + global.version,\r\n controller: 'studentExerciseMapCtrl',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveKort'\r\n }\r\n })\r\n .state('student.exercisecarousel',\r\n {\r\n url: '/exercise/{id:int}',\r\n template: function() {\r\n return '
\\n' +\r\n '
\\n' + \r\n '
\\n' +\r\n '
\\n' +\r\n '
\\n';\r\n },\r\n controller: 'studentCarouselCtrl',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveKarusel'\r\n }\r\n }) \r\n .state('student.exercisebegin',\r\n {\r\n url: '/exercisebegin/{id:int}',\r\n templateUrl: '/ng-views/student/exercisebegin/index.html?v=' + global.version,\r\n controller: 'studentExerciseBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveBegynd'\r\n }\r\n })\r\n .state('student.exerciseperform',\r\n {\r\n url: '/exerciseperform/{id:int}/{question:int}',\r\n templateUrl: '/ng-views/student/exerciseperform/index.html?v=' + global.version,\r\n controller: 'studentExercisePerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDo'\r\n }\r\n })\r\n .state('student.freegameperform',\r\n {\r\n url: '/freegameperform/{id:int}/{question:int}',\r\n templateUrl: '/ng-views/student/freegameperform/index.html?v=' + global.version,\r\n controller: 'studentFreeGamePerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'FreeGameDo'\r\n }\r\n })\r\n .state('student.exerciseevalbegin',\r\n {\r\n url: '/exerciseevalbegin/{id:int}',\r\n templateUrl: '/ng-views/student/exerciseevalbegin/index.html?v=' + global.version,\r\n controller: 'studentExerciseEvalBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalBegynd'\r\n }\r\n })\r\n .state('student.exerciseevalperform',\r\n {\r\n url: '/exerciseevalperform/{id:int}/{question:int}',\r\n templateUrl: '/ng-views/student/exerciseevalperform/index.html?v=' + global.version,\r\n controller: 'studentExerciseEvalPerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalDo'\r\n }\r\n })\r\n .state('student.exercisedone',\r\n {\r\n url: '/exercisedone/{id:int}',\r\n templateUrl: '/ng-views/student/exercisedone/index.html?v=' + global.version,\r\n controller: 'studentExerciseDoneCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDone'\r\n }\r\n })\r\n .state('student.trophy',\r\n {\r\n url: '/trophy',\r\n templateUrl: '/ng-views/trophy/index.html?v=' + global.version,\r\n controller: 'trophyIndexCtrl',\r\n ncyBreadcrumb: {\r\n label: 'Pokal'\r\n }\r\n })\r\n .state('student.worthknowing',\r\n {\r\n url: '/worthknowing',\r\n templateUrl: '/ng-views/student/worthknowing/index.html?v=' + global.version,\r\n controller: 'studentWorthKnowingIndexCtrl',\r\n ncyBreadcrumb: {\r\n label: 'WorthKnowing'\r\n }\r\n })\r\n .state('student.messages',\r\n {\r\n url: '/messages',\r\n templateUrl: '/ng-views/student/messages/index.html?v=' + global.version,\r\n controller: 'studentMessagesCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'Beskeder'\r\n }\r\n })\r\n .state('preview',\r\n {\r\n url: '/preview',\r\n templateUrl: '/ng-views/preview/index.html?v=' + global.version,\r\n ncyBreadcrumb: {\r\n label: 'Preview'\r\n }\r\n }\r\n )\r\n .state('preview.exercisebegin',\r\n {\r\n url: '/exercisebegin',\r\n templateUrl: '/ng-views/preview/exercisebegin/index.html?v=' + global.version,\r\n controller: 'previewExerciseBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveBegynd'\r\n }\r\n })\r\n .state('preview.exerciseperform',\r\n {\r\n url: '/exerciseperform',\r\n templateUrl: '/ng-views/preview/exerciseperform/index.html?v=' + global.version,\r\n controller: 'previewExercisePerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDo'\r\n }\r\n })\r\n .state('preview.exerciseevalbegin',\r\n {\r\n url: '/exerciseevalbegin',\r\n templateUrl: '/ng-views/preview/exerciseevalbegin/index.html?v=' + global.version,\r\n controller: 'previewExerciseEvalBeginCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalBegynd'\r\n }\r\n })\r\n .state('preview.exerciseevalperform',\r\n {\r\n url: '/exerciseevalperform',\r\n templateUrl: '/ng-views/preview/exerciseevalperform/index.html?v=' + global.version,\r\n controller: 'previewExerciseEvalPerformCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveEvalDo'\r\n }\r\n })\r\n .state('preview.exercisedone',\r\n {\r\n url: '/exercisedone',\r\n templateUrl: '/ng-views/preview/exercisedone/index.html?v=' + global.version,\r\n controller: 'previewExerciseDoneCtrl as vm',\r\n ncyBreadcrumb: {\r\n label: 'OpgaveDone'\r\n }\r\n })\r\n .state('404', {\r\n url: '/page-not-found',\r\n templateUrl: '/ng-views/shared/404.html?v=' + global.version,\r\n controller: 'notFoundCtrl'\r\n })\r\n .state('500', {\r\n url: '/an-error-occured',\r\n templateUrl: '/ng-views/shared/500.html?v=' + global.version,\r\n controller: 'errorCtrl'\r\n });\r\n}]);\r\n","app.run(['$q', '$timeout', '$transitions', '$rootScope', 'navService', 'authService', 'gameService', 'freeGameService', 'gameDayAuthService', 'adminAuthService', 'locationService', 'mdContentService', 'pushService', function ($q, $timeout, $transitions, $rootScope, navService, authService, gameService, freeGameService, gameDayAuthService, adminAuthService, locationService, mdContentService, pushService) {\r\n\t$transitions.onStart({}, function(transition) {\r\n\t\tif (transition.to().name.indexOf(\"teacher.\") === 0) {\r\n\t\t\tif (!gameDayAuthService.isAuthenticated()) {\r\n\t\t\t\treturn transition.router.stateService.target('404');\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t} else if (transition.to().name.indexOf(\"student\") === 0 || transition.to().name.indexOf(\"teacherapp\") === 0) {\r\n\t\t\tif (transition.to().name === \"student.login\") {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\r\n\t\t\tif (transition.to().name === \"student.freegameperform\") {\r\n\t\t\t\treturn $q(function(resolve, reject) {\r\n\t \tfreeGameService.setupFreeGame().then(function() {\r\n\t \t\tresolve(true);\r\n\t \t}, function() {\r\n\t \t\treject(false);\r\n\t \t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tif (transition.to().name === \"teacherapp\") {\r\n\t\t\t\treturn transition.router.stateService.target('teacherapp.welcome');\r\n\t\t\t}\r\n\r\n\t\t\treturn $q(function(resolve, reject) {\r\n\t\t\t\tauthService.isAuthenticated().then(function(authStatus) {\r\n\t\t\t\t\tif (authStatus == false) {\r\n\t\t\t\t\t\tresolve(transition.router.stateService.target('student.login'));\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tlocationService.ensureRunning().then(function() {\r\n\t\t\t\t\t\tpushService.ensureRunning();\r\n\t\t\t\t\t}, function() {\r\n\t\t\t\t\t\tpushService.ensureRunning();\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tauthService.ensureGameDataIsLoaded().then(function() {\r\n\t\t\t\t\t\tif (transition.to().name === \"student\") {\r\n\t if (gameService.isWelcomeNotFinished()) {\r\n\t resolve(transition.router.stateService.target('student.welcome'));\r\n\t return;\r\n\t } else if (gameService.isGameDone()) {\r\n\t resolve(transition.router.stateService.target('student.trophy'));\r\n\t return;\r\n\t } else {\r\n\t resolve(transition.router.stateService.target('student.exercises'));\r\n\t return;\r\n\t }\r\n\t\t\t\t\t\t} else if (transition.to().name === \"student.welcome\") {\r\n\t\t\t\t\t\t\tif (!gameService.isWelcomeNotFinished()) {\r\n\t\t\t\t\t\t\t\tif (!gameService.isGameDone()) {\r\n\t\t\t\t\t\t\t\t\tresolve(transition.router.stateService.target('student.exercises'));\r\n\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\tresolve(transition.router.stateService.target('student.trophy'));\r\n\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else if (transition.to().name.indexOf(\"student.exercise\") === 0) {\r\n\t\t\t\t\t\t\tif (gameService.isWelcomeNotFinished()) {\r\n\t\t\t\t\t\t\t\tresolve(transition.router.stateService.target('student.welcome'));\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (gameService.isGameDone()) {\r\n\t\t\t\t\t\t\t\tresolve(transition.router.stateService.target('student.trophy'));\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else if (transition.to().name === \"student.trophy\") {\r\n\t\t\t\t\t\t\tif (!gameService.isGameDone()) {\r\n\t\t\t\t\t\t\t\tresolve(transition.router.stateService.target('student.exercises'));\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tresolve(true);\r\n\t\t\t\t\t}, function() {\r\n\t\t\t\t\t\tconsole.log(\"gameData not loaded!\");\r\n\t\t\t\t\t\treject(false);\r\n\t\t\t\t\t});\r\n\t\t\t\t}, function() {\r\n\t\t\t\t\tconsole.log(\"not authed!\");\r\n\t\t\t\t\treject(false);\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t} else if (transition.to().name.indexOf(\"preview.\") === 0) {\r\n\t\t\tif (gameDayAuthService.isAuthenticated()) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\tif (adminAuthService.isAuthenticated()) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!adminAuthService.isAuthenticated()) {\r\n\t\t\twindow.location = \"/admin\";\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t});\r\n\r\n\t$transitions.onSuccess({}, function(transition) {\r\n\t\tnavService.close();\r\n\t});\r\n\r\n\t$rootScope.$on('$viewContentLoaded', function(event) {\r\n\t\tmdContentService.triggerSyntheticScrollEvent();\r\n\t});\r\n}]);\r\n","function TivoliArrow(parent) {\r\n this.parent = parent;\r\n this.running = false;\r\n\r\n this.start = function() {\r\n this.canvas = document.createElement(\"canvas\");\r\n this.parent.appendChild(this.canvas);\r\n this.running = true;\r\n this.redraw();\r\n }.bind(this);\r\n\r\n this.stop = function() {\r\n this.canvas = null;\r\n this.parent = null;\r\n this.running = false;\r\n }.bind(this);\r\n\r\n this.redraw = function() {\r\n if (!this.running) {\r\n return;\r\n }\r\n\r\n var canvas = this.canvas;\r\n var ctx = canvas.getContext('2d');\r\n\r\n var devicePixelRatio = window.devicePixelRatio || 1;\r\n var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||\r\n ctx.mozBackingStorePixelRatio ||\r\n ctx.msBackingStorePixelRatio ||\r\n ctx.oBackingStorePixelRatio ||\r\n ctx.backingStorePixelRatio || 1;\r\n var canvasScalingRatio = Math.max(devicePixelRatio / backingStoreRatio, 1);\r\n\r\n var w = this.canvas.parentElement.clientWidth;\r\n var h = this.canvas.parentElement.clientHeight; \r\n\r\n canvas.width = w * canvasScalingRatio;\r\n canvas.height = h * canvasScalingRatio;\r\n\r\n canvas.style.width = w + \"px\";\r\n canvas.style.height = h + \"px\";\r\n\r\n var basew = 58;\r\n var scale = w / 58;\r\n var scaledh = h * (58 / w)\r\n\r\n var arrowHead = new Path2D('M27,11.1c1.7-1.9,3.4-3.7,4.6-4.9c1.2-1.2,1.9-1.7,2.7-2.3C35,3.5,35.7,3,36.5,2.5c0.8-0.4,1.7-0.8,2.6-1.1c0.9-0.3,2-0.6,2.8-0.8C43.5,0.2,44.5,0,45.8,0c1.3,0.1,2.7,0.5,4,0.8c0.9,0.8,1.6,2,1.8,3.1c0.2,1.1,0,2.2-0.4,3c-0.4,0.9-0.9,1.6-1.6,2.1c-4.6,1.4-9.1,3.1-12.1,4.5c-3,1.4-4.4,2.5-5.3,3.4c-0.9,0.9-1.4,1.5-1.8,2.2c-0.4,0.7-0.8,1.4-1.1,2.4c-0.3,1-0.6,2.4-0.7,3.8c-0.1,1.4,0,2.9-0.1,4.3c-0.1,1.4-0.3,2.8-0.5,3.6c-0.2,0.8-0.4,1.1-0.6,1.3c-0.4,0.4-0.9,0.7-1.4,0.6c-0.4-0.3-0.8-0.6-1.1-1.1c-0.3-0.4-0.5-0.9-0.6-2.1c-0.2-1.2-0.3-3.1-0.5-4.9c-0.2-1.8-0.5-3.6-0.8-4.8c-0.3-1.2-0.7-1.9-1.1-2.5c-0.4-0.6-0.9-1.2-1.5-1.8c-0.6-0.6-1.3-1.2-2.1-1.8c-0.8-0.6-1.6-1.1-2.9-1.7c-1.3-0.6-3-1.2-4.8-1.8c-1.8-0.6-3.6-1.1-4.9-1.5c-1.3-0.4-2-0.6-2.6-0.9C2.6,9.7,2,9.4,1.6,9.1c-0.8-0.8-1-1.4-1.4-2.1C0.1,6.5,0,6,0,5.4c0-0.6,0.2-1.1,0.4-1.6C0.8,3,1,2.5,1.8,1.8c0.4-0.3,0.9-0.5,1.5-0.6C4.5,0.8,6,0.7,7.5,0.8c1.5,0.2,3.1,0.5,4.8,0.9c1.6,0.4,3.3,1.4,5.2,2.6c1,0.6,1.9,1.3,2.8,2.4c1,1.2,2,2.8,2.8,4.6');\r\n var arrowEnd1 = new Path2D('M22,38.3c-0.1,0-0.3,0-0.7,0.2');\r\n var arrowEnd2 = new Path2D('M20.8,38.6c-0.1,0-0.1,0-0.4,0.1c-0.5,0.1-1-0.1-1.4-0.4c0,0,0,0,0,0c0,0,0-0.1-0.1-0.1c-0.4-0.7-0.6-1.4-0.9-2c-0.6-1.2-1.1-2.1-2.2-3.2c-0.5-0.5-1.2-1-2-1.5c-0.7-0.5-1.5-1-2.5-1.5c-1.1-0.5-2.4-1-4.1-1.3c-1.7-0.4-3.6-0.7-4.9-1.1c-1.2-0.5-1.7-1.1-2-1.6C-0.1,25.1,0,24.8,0,24.2c0.1-0.5,0.3-1,1-1.4c0.3-0.2,0.8-0.5,1.4-0.6C3,22,3.6,21.8,4.5,21.9c0.9,0,2,0.3,3.2,0.7c1.2,0.4,2.4,1.1,3.8,2.1c1.4,0.9,2.9,2.1,4.2,3.5c1.3,1.4,2.5,2.9,3.5,4.5v-8.2c-1-1.2-2.2-2.2-3.6-3.1c-1.4-0.9-3.2-1.7-5.1-2.4c-1.9-0.7-4.1-1.3-5.6-1.6c-1.5-0.4-2.3-0.6-2.9-0.9c-1.2-0.7-1.9-2-1.7-3c0.1-0.5,0.3-0.9,0.5-1.2C0.8,12.1,0.9,12,1,11.9c0.1-0.1,0.2-0.2,0.4-0.2c0.5-0.2,1-0.3,1-0.3c0.9-0.1,1.8,0.1,1.8,0.1c1.9,0.4,2.8,0.5,3.5,0.8c1.2,0.4,2.1,0.8,2.8,1.2c0.8,0.4,1.6,0.9,2.4,1.4c2.3,1.5,4,3.3,6,5.5v-4.6c-0.4-0.7-0.8-1.5-1.3-2.1c-0.5-0.7-1-1.3-1.5-1.8c-0.5-0.5-1.1-1-1.7-1.4C13.9,9.9,13.2,9.4,12,9c-1.2-0.5-2.9-1.1-4.6-1.5C5.7,7,4,6.6,3,6.3c-1-0.3-1.3-0.7-1.5-1C1.2,5,0.9,4.6,0.8,4.3C0.7,4,0.8,3.8,0.8,3.5c0-0.3,0-0.5,0.1-0.8C1,2.3,1.3,1.9,1.7,1.6c1.2-1,3.3-0.9,5.1-0.3c0.5,0.2,1,0.3,1.9,0.8c0.8,0.4,2,1.1,3.2,1.9c1.1,0.8,2.3,1.5,3.1,2.3c0.9,0.7,1.5,1.4,2,2c0.5,0.6,0.9,1.2,1.2,1.6c0.3,0.4,0.4,0.6,0.5,0.8c0-1.5,0-3,0-4.6c0-1.5-0.1-3.1,0-4.1c0.1-1,0.3-1.3,0.5-1.6c0.3-0.3,0.6-0.4,1-0.4c0.4,0,0.9,0.2,1.1,0.5c0.3,0.4,0.4,0.9,0.4,1.5c0,0.6,0,1.3,0,2.7c0,1.4,0,3.6,0,5.8c0.8-1.5,1.9-2.8,3.3-4.2c1.5-1.4,3.4-2.8,5-3.8c1.6-1,2.9-1.5,3.8-1.8c0.9-0.3,1.3-0.4,1.7-0.5c0.4-0.1,0.9-0.1,1.3,0c0.4,0.1,0.8,0.2,1.2,0.3c0.3,0.2,0.7,0.4,0.9,0.6c0.5,0.5,0.8,1.2,0.8,1.9c0,0.4-0.2,0.7-0.4,1c-0.4,0.7-0.9,1-1.4,1.4c-0.3,0.2-0.6,0.3-1.2,0.5c-0.6,0.2-1.6,0.4-2.6,0.7c-0.9,0.3-1.8,0.6-2.6,0.8c-1.5,0.4-2.2,0.6-3.3,1.2c-1,0.6-2.3,1.3-3.4,2.4c-0.5,0.5-1,1.1-1.5,1.8c-0.5,0.7-0.9,1.4-1.1,2.2c-0.5,1.6-0.5,3.5-0.4,5.2c1.2-1.6,2.6-3.1,4.1-4.3c1.5-1.2,3-2.3,4.1-2.9c1.1-0.7,1.8-0.9,2.5-1.2c1.3-0.6,2.6-1,3.8-1.1c0.6-0.1,1.2-0.2,1.6-0.2c0.8,0,1.2,0.2,1.7,0.5c0.2,0.1,0.4,0.4,0.7,0.6c0.2,0.3,0.5,0.5,0.6,1.1c0.1,0.5,0,1.3-0.4,1.8c-0.4,0.5-1.1,0.9-1.5,1.1c-0.5,0.3-0.8,0.4-1.6,0.7c-0.8,0.2-2.1,0.5-3.3,0.9c-1.2,0.4-2.5,0.8-3.8,1.4c-1.4,0.6-2.9,1.3-4.2,2.2c-1.3,0.9-2.4,1.9-3.1,2.5c-0.6,0.6-0.8,0.8-0.9,1.1v8c1.3-2,2.7-3.8,4.2-5.3c1.5-1.5,3.1-2.7,4.2-3.5c1.1-0.8,1.7-1.1,2.3-1.4c1.2-0.6,2.4-1,3.5-1c0.5,0,1.1-0.1,1.8,0c0.7,0.1,1.4,0.3,2,0.7c0.6,0.4,1,0.9,1.1,1.6c0.1,0.6-0.2,1.4-0.5,1.9c-0.3,0.6-0.7,1-1.6,1.3c-0.9,0.3-2.2,0.6-3.5,0.9c-1.3,0.3-2.6,0.6-3.7,1c-1,0.4-1.8,0.8-2.6,1.2c-0.7,0.5-1.4,1-2,1.4c-0.6,0.4-1.1,0.8-1.5,1.2c-0.4,0.4-0.8,0.9-1.2,1.4c-0.4,0.6-0.7,1.2-1,2c-0.3,0.7-0.5,1.5-0.6,2.3');\r\n\r\n var xofs = 0;\r\n var yofs = 0;\r\n\r\n ctx.scale(canvasScalingRatio, canvasScalingRatio);\r\n\r\n ctx.save();\r\n ctx.scale(scale, scale);\r\n ctx.translate(xofs + 4, yofs+ scaledh - 35);\r\n ctx.fill(arrowHead);\r\n ctx.restore();\r\n\r\n ctx.beginPath();\r\n var x1 = Math.round(xofs + (29 * scale));\r\n var y1 = Math.round(yofs + (35 * scale));\r\n ctx.moveTo(x1, y1);\r\n var x2 = Math.round(xofs + (29 * scale));\r\n var y2 = Math.round(yofs + h - (20 * scale));\r\n ctx.lineTo(x2, y2);\r\n\r\n ctx.lineWidth = Math.round(4 * scale);\r\n ctx.stroke();\r\n\r\n ctx.save();\r\n ctx.translate(xofs, yofs);\r\n ctx.scale(scale, scale);\r\n ctx.scale(1.4, 1.4);\r\n ctx.fill(arrowEnd1);\r\n ctx.fill(arrowEnd2);\r\n ctx.restore();\r\n\r\n window.requestAnimationFrame(this.redraw.bind(this));\r\n }.bind(this);\r\n}\r\n","app.filter('schoolCategoryString', function () {\r\n return function (input) {\r\n \tif (input === 0) {\r\n \t\treturn \"1. - 3. klasse\";\r\n \t}\r\n \tif (input === 1) {\r\n \t\treturn \"4. - 6. klasse\";\r\n \t}\r\n \tif (input === 2) {\r\n \t\treturn \"7. - 10. klasse\";\r\n \t} else if (input === 3) {\r\n\t\treturn \"Ungdomsuddannelser\";\r\n\t}\r\n \treturn \"Ukendt\";\r\n }\r\n});\r\n","app.factory('adminAuthService', ['$window',function ($window) {\r\n\tvar service = this;\r\n\r\n\tservice.authCookie = function() {\r\n\t\tvar cookie = $window.document.cookie;\r\n\t\tif (!cookie) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tvar idx = cookie.indexOf(\".FDAUTH=\");\r\n\t\tif (idx < 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tvar sub = cookie.substring(idx);\r\n\t\tvar end = sub.indexOf(\"; \");\r\n\t\tvar key = sub;\r\n\t\tif (end != -1) {\r\n\t\t\tkey = key.substring(0, end);\r\n\t\t}\r\n\t\treturn key.substr(\".FDAUTH=\".length);\r\n\t}\r\n\r\n\tservice.isAuthenticated = function() {\r\n\t\treturn service.authCookie() != null;\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('analyticsService', ['$http', function ($http) {\r\n\tvar service = this;\r\n\r\n\tservice.event = function(event, params) {\r\n\t\tif (params == null) {\r\n\t\t\tparams = {};\r\n\t\t}\r\n\t\tparams.event = event;\r\n\t\t$http.post('/api/analytics/event', params).then(function() {\r\n\t\t\tconsole.log(\"analytics ok!\");\r\n\t\t}).catch(function() {\r\n\t\t\tconsole.log(\"analytics bad!\");\r\n\t\t});\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('appService', ['$rootScope', '$window', '$state', function ($rootScope, $window, $state) {\r\n\tvar service = this;\r\n\r\n\tservice.userAgent = $window.navigator.userAgent;\r\n\r\n\tconsole.log('appService: initializing app service with userAgent: ' + service.userAgent);\r\n\r\n\tservice.isApp = function() {\r\n\t\t// Treat the user agent as an app if it contains our\r\n\t\t// special user agent.\r\n\t\tif (service.userAgent.indexOf(\"FagligeDage/\") !== -1) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\t// Treat all /student pages as being an \"app\".\r\n\t\tif (window.location.pathname.indexOf(\"/student\") === 0) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\t// Treat all /teacherapp pages as being an \"app\".\r\n\t\tif (window.location.pathname.indexOf(\"/teacherapp\") === 0) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}();\r\n\r\n\t// These two are filled out on login via authService.\r\n\tservice.isStudentApp = false;\r\n\tservice.isTeacherApp = false;\r\n\r\n\tservice.isTeacherBackendSystem = function() {\r\n\t\tif (window.location.pathname.indexOf(\"/teacher\") === 0 && window.location.pathname.indexOf(\"/teacherapp\") !== 0) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tservice.isAdminSystem = function() {\r\n\t\treturn !service.isTeacherBackendSystem() && !service.isApp;\r\n\t}\r\n\r\n\tservice.isiOS = function() {\r\n\t\tif (service.userAgent.indexOf(\"FagligeDageiOS/\") !== -1) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tservice.isiPhoneX = function() {\r\n\t\tif (service.userAgent.indexOf(\"FageligeDageiPhoneX/\") !== -1) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tservice.isAndroid = function() {\r\n\t\tif (service.userAgent.indexOf(\"FagligeDageAndroid/\") !== -1) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tservice.clearCookies = function() {\r\n\t\tif (service.isiOS()) {\r\n\t\t\tvar handler = window.webkit.messageHandlers[\"clearCookies\"];\r\n\t\t\tif (handler != null) {\r\n\t\t\t\thandler.postMessage({});\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (service.isAndroid()) {\r\n\t\t\twindow.tuAndroid.clearCookies();\r\n\t\t}\r\n\t}\r\n\r\n\tservice.setCookieState = function(state) {\r\n\t\tif (service.isiOS()) {\r\n\t\t\tvar handler = window.webkit.messageHandlers[\"setCookieState\"];\r\n\t\t\tif (handler != null) {\r\n\t\t\t\thandler.postMessage(state);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (service.isAndroid()) {\r\n\t\t\twindow.tuAndroid.setCookieState(state);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconsole.log('appService: setCookieState: ' + state);\r\n\t}\r\n\r\n\tservice.showCookieDialog = function() {\r\n\t\t$rootScope.$broadcast('cookieDialogForceShow');\r\n\t}\r\n\r\n\tservice.showCookieRemoveDialog = function() {\r\n\t\t$rootScope.$broadcast('cookieDialogForceShowRemove');\r\n\t}\r\n\r\n\treturn service;\r\n}]);\r\n","\tapp.factory('authService', ['$http', '$q', '$window', 'gameService', 'welcomeService', 'teacherAppService', 'messageService', 'appService', '$rootScope', function ($http, $q, $window, gameService, welcomeService, teacherAppService, messageService, appService, $rootScope) {\n\t\tvar service = this;\n\n\t\tservice.me = function() {\n\t\t\treturn $http.get('api/me')\n\t\t\t\t.then(function (resp) {\n\t\t\t\t\tconsole.dir(resp.data);\n\t\t\t\t\treturn resp.data;\n\t\t\t\t}, function (err) {\n\t\t\t\t\tconsole.log('api me error');\n\t\t\t\t});\n\t\t};\n\n\t\tservice.authStatus = false;\n\t\tservice.isTeacher = false;\n\n\t\tservice.restart = function() {\n\t\t\t$http.post('/api/gameauth/logout').then(function(response) {\n\t\t\t\tservice.tempPin = null;\n\t\t\t\tservice.authStatus = false;\n\t\t\t});\n\t\t}\n\n\t\tservice.tempPin = undefined;\n\t\tservice.cookiePinCode = function() {\n\t\t\tif (service.tempPin != null) {\n\t\t\t\treturn service.tempPin;\n\t\t\t}\n\n\t\t\tvar cookie = $window.document.cookie;\n\t\t\tif (!cookie) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar idx = cookie.indexOf(\".FDGAME=\");\n\t\t\tif (idx < 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar sub = cookie.substring(idx);\n\t\t\tvar end = sub.indexOf(\"; \");\n\t\t\tvar pin = sub;\n\t\t\tif (end != -1) {\n\t\t\t\tpin = pin.substring(0, end);\n\t\t\t}\n\t\t\treturn pin.substr(\".FDGAME=\".length);\n\t\t}\n\n\t\tservice.isAuthenticated = function() {\n\t\t\treturn $q(function(resolve, reject) {\n\t\t\t\tvar cookiePin = service.cookiePinCode();\n\t\t\t\tvar ok = cookiePin != null || (service.authStatus == true);\n\t\t\t\tresolve(ok);\n\t\t\t});\n\t\t}\n\n\t\tservice.authenticateWithPin = function(pinCode) {\n\t\t\treturn $q(function(resolve, reject) {\n\t\t\t\t$http.post('/api/gameauth/login', {'pin': pinCode}).then(function(response) {\n\t\t\t\t\tvar obj = response.data;\n\n\t\t\t\t\tvar setCookie = response.headers('Set-Cookie');\n\t\t\t\t\t$window.document.cookie = setCookie;\n\n\t\t\t\t\tconsole.log(\"setting initial state\");\n\t\t\t\t\tgameService.setInitialState(obj);\n\t\t\t\t\twelcomeService.setInitialState(obj);\n\t\t\t\t\tconsole.log(\"done setting initial state\");\n\n\t\t\t\t\tservice.authStatus = true;\n\t\t\t\t\tservice.isTeacher = response.data.permission.isTeacher;\n\n\t\t\t\t\t$rootScope.$broadcast('authServiceIsAuthenticated');\n\n\t\t\t\t\t// Update isTeacherApp/isStudentApp in appService\n\t\t\t\t\t// to reflect our currently login-status.\n\t\t\t\t\tif (service.isTeacher) {\n\t\t\t\t\t\tappService.isTeacherApp = true;\n\t\t\t\t\t\tappService.isStudentApp = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tappService.isTeacherApp = false;\n\t\t\t\t\t\tappService.isStudentApp = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set a temp pin. This overrides the cookie\n\t\t\t\t\t// in cases where our page hasn't been reloaded\n\t\t\t\t\t// to set the cookie in window.cookies.\n\t\t\t\t\tservice.tempPin = pinCode;\n\n\t\t\t\t\tmessageService.startAndSyncImmediately().then(function() {\n\t\t\t\t\t\tconsole.log(\"started messageService...\");\n\t\t\t\t\t\tif (service.isTeacher) {\n\t\t\t\t\t\t\tconsole.log(\"attempting to start teacherService...\");\n\t\t\t\t\t\t\tteacherAppService.startAndSyncImmediately().then(function() {\n\t\t\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t\t\t}, function() {\n\t\t\t\t\t\t\t\tresolve(false);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, function() {\n\t\t\t\t\t\tresolve(false);\n\t\t\t\t\t});\n\t\t\t\t}, function() {\n\t\t\t\t\tresolve(false);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tservice.ensureGameDataIsLoaded = function() {\n\t\t\treturn $q(function(resolve, reject) {\n\t\t\t\tif (gameService.ready) {\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar pin = service.cookiePinCode();\n\t\t\t\tif (!pin) {\n\t\t\t\t\treject(\"no pin\");\n\t\t\t\t}\n\t\t\t\tservice.authenticateWithPin(pin).then(function() {\n\t\t\t\t\tresolve();\n\t\t\t\t}, function() {\n\t\t\t\t\treject();\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\treturn service;\n\t}]);","app.factory('exerciseService', ['$mdMedia', '$mdDialog', '$mdToast', '$http', '$state', 'mdContentService', function ($mdMedia, $mdDialog, $mdToast, $http, $state, mdContentService) {\r\n\tvar service = this;\r\n\r\n\tservice.exercises = []\r\n\tservice.loaded = false;\r\n\r\n\tservice.get = function(id) {\r\n\t\treturn $http.get('api/exercise/' + id) // XXX: XSRF\r\n\t\t.then(function (resp) {\r\n\t\t return resp.data;\r\n\t\t}, function (err) {\r\n\t\t return null;\r\n\t\t});\r\n\t}\r\n\r\n\tservice.load = function() {\r\n\t\treturn $http.get('api/exercise').then(function(resp) {\r\n\t\t\tservice.exercises = resp.data.items;\r\n\t\t\tservice.loaded = true;\r\n\r\n\t\t\t// XXX: this is a bit of a hack, but it'll do.\r\n\t\t\tmdContentService.triggerSyntheticScrollEvent();\r\n\t\t}, function(err) {\r\n\t\t\tconsole.log(\"exerciseService: unable to load exercises\");\r\n\t\t\tservice.exercises = []; // errr!\r\n\t\t});\r\n\t}\r\n\r\n\tservice.askDelete = function(exercise, ev) {\r\n\t\tev.preventDefault();\r\n\r\n\t\tvar confirm = $mdDialog.confirm()\r\n .title('Slet opgavesæt')\r\n .textContent('Er du sikker på at du vil fjerne dette opgavesæt?')\r\n .ariaLabel('Slet opgavesæt')\r\n .targetEvent(ev)\r\n .ok('Slet')\r\n .cancel('Anullér');\r\n $mdDialog.show(confirm).then(function () {\r\n\t\t\treturn $http.delete('api/exercise/' + exercise.id).then(function(resp) {\r\n\t\t\t\t$mdToast.show(\r\n\t\t\t\t\t$mdToast.simple()\r\n\t\t\t\t\t\t.textContent(\"Opgavesæt slettet\")\r\n\t\t\t\t\t\t.position('top right')\r\n\t\t\t\t\t\t.hideDelay(3000));\r\n\t\t\t\t$state.reload();\r\n \t}, function () {\r\n \t});\r\n\t\t});\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('freeGameService', ['$q', '$timeout', '$http', function ($q, $timeout, $http) {\r\n\tvar service = this;\r\n\r\n\tservice.ready = false;\r\n\tservice.exercises = [];\r\n\r\n\tfunction indexify(collection, forEachFunc) {\r\n\t\tfor (var i = 0; i < collection.length; i++) {\r\n\t\t\tvar item = collection[i];\r\n\t\t\titem.index = i;\r\n\t\t\tif (forEachFunc) {\r\n\t\t\t\tforEachFunc(item);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tservice.setupFreeGame = function() {\r\n\t\tif (service.ready) {\r\n\t\t\treturn $q(function(resolve, reject) {\r\n\t\t\t\tresolve();\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\t$http.get('/api/freegame').then(function(response) {\r\n\t\t\t\tvar game = response.data;\r\n\t\t\t\tvar exercises = angular.copy(game.exercises);\r\n\t\t\t\tindexify(exercises, function(exercise) {\r\n\t\t\t\t\tindexify(exercise.questions, function(question) {\r\n\t\t\t\t\t\tindexify(question.answers);\r\n\t\t\t\t\t});\r\n\t\t\t\t\tindexify(exercise.evaluationQuestions, function(question) {\r\n\t\t\t\t\t\tindexify(question.answers);\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t\tservice.exercises = exercises;\r\n\t\t\t\tservice.ready = true;\r\n\t\t\t\tresolve();\r\n\t\t\t}, function() {\r\n\t\t\t\treject();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tservice.exerciseWithIndex = function(exerciseIndex) {\r\n\t\tfor (var i = 0; i < service.exercises.length; i++) {\r\n\t\t\tvar exercise = service.exercises[i];\r\n\t\t\tif (exercise.index === exerciseIndex) {\r\n\t\t\t\treturn exercise;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tservice.lookupQuestion = function(exerciseIndex, questionIndex) {\r\n\t\tvar exercise = service.exerciseWithIndex(exerciseIndex);\r\n\t\tfor (var i = 0; i < exercise.questions.length; i++) {\r\n\t\t\tvar question = exercise.questions[i];\r\n\t\t\tif (question.index === questionIndex) {\r\n\t\t\t\treturn question;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\treturn service;\r\n}]);\r\n","app.factory('gameDayAuthService', ['$window',function ($window) {\r\n\tvar service = this;\r\n\r\n\tservice.keyString = function() {\r\n\t\tvar cookie = $window.document.cookie;\r\n\t\tif (!cookie) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tvar idx = cookie.indexOf(\".FDGAMEDAY=\");\r\n\t\tif (idx < 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tvar sub = cookie.substring(idx);\r\n\t\tvar end = sub.indexOf(\"; \");\r\n\t\tvar key = sub;\r\n\t\tif (end != -1) {\r\n\t\t\tkey = key.substring(0, end);\r\n\t\t}\r\n\t\treturn key.substr(\".FDGAMEDAY=\".length);\r\n\t}\r\n\r\n\tservice.isAuthenticated = function() {\r\n\t\treturn service.keyString() != null;\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('gameService', ['$q', '$timeout', '$http', function ($q, $timeout, $http, teacherAppService) {\r\n\tvar service = this;\r\n\r\n\tservice.restart = function() {\r\n\t\tservice.startTime = new Date();\r\n\t\tservice.teamName = undefined;\r\n\t\tservice.teamImageURL = undefined;\r\n\t\tservice.teamMembers = [];\r\n\t\tservice.config = {};\r\n\t\tservice.rides = [];\r\n\t\tservice.exercises = [];\r\n\t\tservice.gameState = {\r\n\t\t\tfinishedWelcome: false,\r\n\t\t\texerciseIndex: 0,\r\n\t\t\tquestionIndex: 0,\r\n\t\t\tevaluationQuestionIndex: 0,\r\n\t\t\tscore: 0,\r\n\t\t\tevaluationAnswers: {}\r\n\t\t};\r\n\t}\r\n\r\n\tservice.ready = false;\r\n\tservice.isTeacher= false;\r\n\tservice.startTime = new Date();\r\n\tservice.teamName = undefined;\r\n\tservice.teamImageURL = undefined;\r\n\tservice.teamMembers = [];\r\n\tservice.config = {};\r\n\tservice.rides = [];\r\n\tservice.exercises = [];\r\n\tservice.gameState = {\r\n\t\tfinishedWelcome: false,\r\n\t\texerciseIndex: 0,\r\n\t\tquestionIndex: 0,\r\n\t\tevaluationQuestionIndex: 0,\r\n\t\tscore: 0\r\n\t};\r\n\r\n\tservice.titleCaseTeamName = function(name) {\r\n \tvar out = \"\";\r\n\r\n \tif (name === undefined) {\r\n \t\treturn undefined;\r\n \t}\r\n\r\n var doUpper = true;\r\n for (var i = 0; i < name.length; i++) {\r\n var ch = name[i];\r\n if (doUpper) {\r\n out += ch.toUpperCase();\r\n doUpper = false;\r\n } else {\r\n out += ch.toLowerCase();\r\n }\r\n\r\n if (ch == ' ') {\r\n doUpper = true;\r\n }\r\n }\r\n\r\n return out;\r\n\t}\r\n\r\n\tfunction indexify(collection, forEachFunc) {\r\n\t\tfor (var i = 0; i < collection.length; i++) {\r\n\t\t\tvar item = collection[i];\r\n\t\t\titem.index = i;\r\n\t\t\tif (forEachFunc) {\r\n\t\t\t\tforEachFunc(item);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tservice.setTeacherAppState = function(game, gameState) {\r\n\t\tvar exercises = angular.copy(game.exercises);\r\n\t\tindexify(exercises, function(exercise) {\r\n\t\t\tindexify(exercise.questions, function(question) {\r\n\t\t\t\tindexify(question.answers);\r\n\t\t\t});\r\n\t\t\tindexify(exercise.evaluationQuestions, function(question) {\r\n\t\t\t\tindexify(question.answers);\r\n\t\t\t});\r\n\t\t});\r\n\t\tservice.exercises = exercises;\r\n\t\tservice.gameState = gameState;\r\n\t\tservice.isTeacher = true;\r\n\t}\r\n\r\n\tservice.setInitialState = function(obj) {\r\n\t\tvar game = obj.game;\r\n\t\tvar gameState = obj.gameState;\r\n\t\tvar gameConfig = obj.gameConfig;\r\n\t\tvar rides = obj.rides;\r\n\t\tvar gameDayInfo = obj.gameDayInfo;\r\n\r\n\t\tvar exercises = angular.copy(game.exercises);\r\n\t\tindexify(exercises, function(exercise) {\r\n\t\t\tindexify(exercise.questions, function(question) {\r\n\t\t\t\tindexify(question.answers);\r\n\t\t\t});\r\n\t\t\tindexify(exercise.evaluationQuestions, function(question) {\r\n\t\t\t\tindexify(question.answers);\r\n\t\t\t});\r\n\t\t});\r\n\t\tservice.exercises = exercises;\r\n\r\n\t\tservice.teamName = game.teamName;\r\n\t\tservice.teamMembers = game.teamMembers;\r\n\r\n\t\tvar year = parseInt(gameDayInfo.startDayYMD.substr(0, 4), 10);\r\n\t\tvar month = parseInt(gameDayInfo.startDayYMD.substr(4, 2), 10);\r\n\t\tvar day = parseInt(gameDayInfo.startDayYMD.substr(6, 2), 10);\r\n\r\n\t\tservice.startTime = new Date(year, month - 1, day, 8, 0, 0, 0);\r\n\r\n\t\tservice.gameState = gameState;\r\n\t\tservice.config = gameConfig;\r\n\t\tservice.rides = rides;\r\n\t\tservice.gameDayInfo = gameDayInfo;\r\n\r\n\t\tservice.ready = true;\r\n\t}\r\n\r\n\tservice.exerciseWithIndex = function(exerciseIndex) {\r\n\t\tfor (var i = 0; i < service.exercises.length; i++) {\r\n\t\t\tvar exercise = service.exercises[i];\r\n\t\t\tif (exercise.index === exerciseIndex) {\r\n\t\t\t\treturn exercise;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tservice.lookupQuestion = function(exerciseIndex, questionIndex) {\r\n\t\tvar exercise = service.exerciseWithIndex(exerciseIndex);\r\n\t\tfor (var i = 0; i < exercise.questions.length; i++) {\r\n\t\t\tvar question = exercise.questions[i];\r\n\t\t\tif (question.index === questionIndex) {\r\n\t\t\t\treturn question;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tservice.lookupEvaluationQuestion = function(exerciseIndex, evaluationQuestionIndex) {\r\n\t\tvar exercise = service.exerciseWithIndex(exerciseIndex);\r\n\t\tfor (var i = 0; i < exercise.evaluationQuestions.length; i++) {\r\n\t\t\tvar question = exercise.evaluationQuestions[i];\r\n\t\t\tif (question.index === evaluationQuestionIndex) {\r\n\t\t\t\treturn question;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tservice.setTeamInfo = function(obj) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tservice.teamName = service.titleCaseTeamName(obj.teamName);\r\n\t\t\tservice.teamImageURL = obj.teamImageURL;\r\n\r\n\t\t\tvar data = {\r\n\t\t\t\tteamName: service.teamName,\r\n\t\t\t\tteamImageURL: service.teamImageURL\r\n\t\t\t};\r\n\t\t\t$http.post('/api/game/teaminfo', data).then(function() {\r\n\t\t\t\tresolve();\r\n\t\t\t}).catch(function() {\r\n\t\t\t\treject();\r\n\t\t\t})\r\n\t\t});\r\n\t}\r\n\r\n\tservice.setPushToken = function(token) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tvar data = {\r\n\t\t\t\tpushToken: token\r\n\t\t\t};\r\n\t\t\t$http.post('/api/game/pushtoken', data).then(function() {\r\n\t\t\t\tresolve();\r\n\t\t\t}).catch(function() {\r\n\t\t\t\treject();\r\n\t\t\t})\r\n\t\t});\r\n\t}\r\n\r\n\tservice.uploadTeamImage = function(fileObj) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\t$timeout(function() {\r\n\t\t\t\tvar url = window.FD.BlobToDataURL(fileObj);\r\n\t\t\t\tservice.teamImageURL = url;\r\n\t\t\t\tresolve(url);\r\n\t\t\t}, 1000);\r\n\t\t});\r\n\t}\r\n\r\n\tservice.setWelcomeFinished = function(finished) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tservice.gameState.finishedWelcome = finished;\r\n\t\t\t$http.put('/api/game/gamestate', service.gameState).then(function() {\r\n\t\t\t\tresolve(true);\r\n\t\t\t}, function() {\r\n\t\t\t\tresolve(false);\r\n\t\t\t}).catch(function() {\r\n\t\t\t\tresolve(false);\r\n\t\t\t});\r\n\t\t});\r\n\t\tservice.gameState.finishedWelcome = finished;\r\n\t}\r\n\r\n\tservice.setGameState = function(newState) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tservice.gameState = JSON.parse(JSON.stringify(newState));\r\n\r\n\t\t\t// Don't post updated state to the service.\r\n\t\t\tif (service.isTeacher) {\r\n\t\t\t\tresolve(true);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t$http.put('/api/game/gamestate', service.gameState).then(function() {\r\n\t\t\t\tresolve(true);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tservice.getGameState = function() {\r\n\t\treturn JSON.parse(JSON.stringify(service.gameState));\r\n\t}\r\n\r\n\tservice.isWelcomeNotFinished = function() {\r\n\t\treturn !service.gameState.finishedWelcome;\r\n\t}\r\n\r\n\tservice.isGameDone = function() {\r\n\t\tif (service.gameState.exerciseIndex >= service.exercises.length) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tservice.resetGameState = function() {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tvar cleanSlate = {\r\n\t\t\t\tfinishedWelcome: false,\r\n\t\t\t\texerciseIndex: 0,\r\n\t\t\t\tquestionIndex: 0,\r\n\t\t\t\tevaluationQuestionIndex: 0,\r\n\t\t\t\tscore: 0\r\n\t\t\t};\r\n\t\t\tservice.setGameState(cleanSlate).then(function() {\r\n\t\t\t\tresolve(true);\r\n\t\t\t}, function() {\r\n\t\t\t\treject();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treturn service;\r\n}]);\r\n","app.factory('keyboardService', ['$rootScope', function ($rootScope) {\r\n\tvar service = this;\r\n\r\n\tservice.mediaQuery = window.matchMedia(\"only screen and (max-height: 500px)\");\r\n\tservice.mediaQuery.addListener(function(mediaQuery) {\r\n\t\tservice.isShown = mediaQuery.matches;\r\n\t\t$rootScope.$broadcast('keyboardShownChanged', {shown: service.isShown});\r\n\t});\r\n\r\n\tservice.isShown = service.mediaQuery.matches;\r\n\t$rootScope.$broadcast('keyboardShownChanged', {shown: service.isShown});\r\n\r\n\treturn service;\r\n}]);","app.factory('locationService', ['$q', 'authService', '$http', '$rootScope', function ($q, authService, $http, $rootScope) {\r\n\tvar service = this;\r\n\r\n\tservice.lastPosition = undefined;\r\n\r\n\tservice.useFakeLocation = false;\r\n\tservice.fakeLocation = { lng: 12.5706879 + 0.00091, lat: 55.6733068 } ; // near DgT\r\n\tservice.running = false;\r\n\r\n\tservice.ensureRunning = function() {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tif (service.running) {\r\n\t\t\t\tresolve();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\twindow.exo.performOperation('Exo.Location.ListenForLocationUpdates').then(function() {\r\n\t\t\t\tconsole.log('locationService: initialized');\r\n\t\t\t\twindow.exo.addBroadcastListener(function(name, args) {\r\n\t\t\t\t\tif (name == 'Exo.Location.LocationUpdate') {\r\n\t\t\t\t\t\tservice.onLocationUpdated(args.position);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tservice.running = true;\r\n\t\t\t\tresolve();\r\n\t\t\t}, function(err) {\r\n\t\t\t\tconsole.log('locationService: failed to initialize: ' + err);\r\n\t\t\t\treject(err);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tservice.forceSyncLocation = function() {\r\n\t\tvar loc = service.getLocation();\r\n\t\tif (loc == null) {\r\n\t\t\tconsole.log(\"locationService: forceSyncLocation failed (is null)\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Convert loc to the expected format.\r\n\t\tvar exoPosition = {\r\n\t\t\tlatitude: loc.lat,\r\n\t\t\tlongitude: loc.lng\r\n\t\t};\r\n\r\n\t\tservice.onLocationUpdated(exoPosition);\r\n\t}\r\n\r\n\tservice.onLocationUpdated = function(exoPosition) {\r\n\t\tconsole.log(\"locationService: location updated!\");\r\n\t\tservice.lastPosition = { lat: exoPosition.latitude, lng: exoPosition.longitude };\r\n\r\n\t\tvar pos = service.lastPosition;\r\n\t\tauthService.isAuthenticated().then(function(authStatus) {\r\n\t\t\tif (!authStatus) {\r\n\t\t\t\tconsole.log(\"locationService: not yet authenticated... delaying...\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t$http.put('/api/game/locationstate', {\r\n\t\t\t\tlastLocation: [pos.lng, pos.lat],\r\n\t\t\t\tlastLocationUpdateTime: parseInt((new Date()).getTime() / 1000.0)\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tservice.getLocation = function() {\r\n\t\tif (!service.running) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tif (service.useFakeLocation) {\r\n\t\t\tconsole.log(\"locationService#getLocation: returning fake location: lat \" + service.fakeLocation.lat + \", lng \" + service.fakeLocation.lng);\r\n\t\t\treturn service.fakeLocation;\r\n\t\t}\r\n\r\n\t\t// XXX: add timer?\r\n\t\tif (service.lastPosition === undefined) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\treturn service.lastPosition;\r\n\t}\r\n\r\n\t// Stolen from https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula\r\n\tservice.distanceInKM = function(pos1, pos2) {\r\n\t\tfunction deg2rad(deg) {\r\n \t\t\treturn deg * (Math.PI / 180);\r\n\t\t}\r\n\r\n\t\tvar R = 6371.0; // Radius of the earth in km\r\n\t\tvar dLat = deg2rad(pos2.lat - pos1.lat);\r\n\t\tvar dLon = deg2rad(pos2.lng - pos2.lng);\r\n\t\tvar a = Math.sin(dLat/2) * Math.sin(dLat/2) +\r\n\t\t Math.cos(deg2rad(pos1.lat)) * Math.cos(deg2rad(pos2.lat)) * \r\n\t\t Math.sin(dLon/2) * Math.sin(dLon/2);\r\n\t\tvar c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); \r\n\t\tvar d = R * c; // Distance in km\r\n\t\treturn d;\r\n\t}\r\n\r\n\t$rootScope.$on('authServiceIsAuthenticated', function() {\r\n\t\tservice.forceSyncLocation();\r\n\t});\r\n\r\n\treturn service;\r\n}]);","app.factory('logoutService', ['gameService', 'authService', 'appService', '$state', function(gameService, authService, appService, $state) {\n\tvar service = this;\n\n\tservice.restart = function() {\n\t\tgameService.resetGameState().then(function() {\n\t\t\t if (authService.isTeacher) {\n\t\t\t\t$state.go('teacherapp');\n\t\t\t} else {\n\t\t\t\t$state.go('student');\n\t\t\t}\n\t\t});\n\t}\n\n\tservice.logout = function() {\n\t\tauthService.restart();\n\t\tgameService.restart();\n\n\t\t$state.go('student.login');\n\n\t\tappService.clearCookies();\n\t}\n\n\treturn service;\n}]);\n","app.factory('mdContentService', ['$timeout', function ($timeout) {\r\n\tvar service = this;\r\n\r\n\tservice.triggerSyntheticScrollEvent = function() {\r\n\t\t$timeout(function() {\r\n\t\t\ttriggerMdContentScroll();\r\n\t\t}, 0);\r\n\t\t$timeout(function() {\r\n\t\t\ttriggerMdContentScroll();\r\n\t\t}, 10);\r\n\t\t$timeout(function() {\r\n\t\t\ttriggerMdContentScroll();\r\n\t\t}, 25);\r\n\t\t$timeout(function() {\r\n\t\t\ttriggerMdContentScroll();\r\n\t\t}, 50);\r\n\t\t$timeout(function() {\r\n\t\t\ttriggerMdContentScroll();\r\n\t\t}, 100);\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('messageService', ['$q', '$interval', '$http', '$rootScope', 'gameService', 'analyticsService', function ($q, $interval, $http, $rootScope, gameService, analyticsService) {\r\n\tvar service = this;\r\n\r\n\tservice.unreadCount = 0;\r\n\tservice.lastRead = 0;\r\n\tservice.started = false;\r\n\tservice.paused = false;\r\n\r\n\tservice.startAndSyncImmediately = function() {\r\n\t\tconsole.log(\"messageService: startAndSyncImmediately called...\");\r\n\r\n\t\tif (service.started) {\r\n\t\t\treturn $q(function(resolve, reject) {\r\n\t\t\t\tresolve();\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Sync once a while, at the interval specified in the config.\r\n\t\t$interval(function() {\r\n\t\t\tif (service.paused) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tservice.fullSync();\r\n\t\t}, (gameService.config.messageServiceUpdateIntervalSecs || 30) * 1000.0);\r\n\r\n\t\tconsole.log(\"messageService: now running.\");\r\n\t\tservice.started = true;\r\n\r\n\t\t// Sync now.\r\n\t\treturn service.fullSync();\r\n\t}\r\n\r\n\tservice.fullSync = function(opts) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tvar url = \"/api/game/message\";\r\n\t\t\t$http.get(url).then(function(response) {\r\n\t\t\t\t\tservice.messages = response.data.messages;\r\n\t\t\t\t\tservice.updateUnreadCount();\r\n\t\t\t\t\t$rootScope.$broadcast('messageServiceUpdated');\r\n\t\t\t\t\tconsole.log(\"messageService: full syncc done!\");\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t},\r\n\t\t\t\tfunction() {\r\n\t\t\t\t\treject();\r\n\t\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tservice.updateUnreadCount = function() {\r\n\t\tvar unreadCount = 0;\r\n\r\n\t\tfor (var i = 0; i < service.messages.length; i++) {\r\n\t\t\tvar message = service.messages[i];\r\n\t\t\tif (service.lastRead <= message.timestamp) {\r\n\t\t\t\tunreadCount += 1;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tservice.unreadCount = unreadCount;\r\n\t}\r\n\r\n\tservice.setLastRead = function() {\r\n\t\tservice.updateUnreadCount();\r\n\t\tservice.lastRead = parseInt((new Date()).getTime() / 1000.0); // current unix timestamp\r\n\t}\r\n\r\n\tservice.sendMessage = function(msgObj) {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\t$http.post('/api/game/message', msgObj).then(function(response) {\r\n\t\t\t\tservice.messages = response.data.messages;\r\n\t\t\t\t$rootScope.$broadcast('messageServiceUpdated');\r\n\t\t\t\tanalyticsService.event(\"teacher_message_sent\");\r\n\t\t\t\tresolve();\r\n\t\t\t}, function() {\r\n\t\t\t\treject();\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\treturn $http.post('/api/game/message', msgObj);\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('navService', [function () {\r\n\tvar service = this;\r\n\r\n\tservice.shown = false;\r\n\r\n\t// Desktop media query listener.\r\n\tservice.showButtons = false;\r\n\tservice.mediaQuery = window.matchMedia(\"only screen and (min-width: 768px)\");\r\n\tservice.mediaQuery.addListener(function(mediaQuery) {\r\n\t\tservice.showButtons = !mediaQuery.matches;\r\n\t});\r\n\tservice.showButtons = !service.mediaQuery.matches;\r\n\r\n\tservice.toggle = function() {\r\n\t\tservice.shown = !service.shown;\r\n\t}\r\n\r\n\tservice.open = function() {\r\n\t\tservice.shown = true;\r\n\t}\r\n\r\n\tservice.close = function() {\r\n\t\tservice.shown = false;\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.factory('pushService', ['$q', 'authService', '$http', '$rootScope', 'gameService', '$state', function ($q, authService, $http, $rootScope, gameService, $state) {\r\n\tvar service = this;\r\n\r\n\tservice.running = false;\r\n\r\n\tservice.ensureRunning = function() {\r\n\t\treturn $q(function(resolve, reject) {\r\n\t\t\tif (service.running) {\r\n\t\t\t\tresolve();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\twindow.exo.performOperation('Exo.PushMessage.Initialize').then(function() {\r\n\t\t\t\tconsole.log('pushService: initialized');\r\n\t\t\t\twindow.exo.addBroadcastListener(function(name, args) {\r\n\t\t\t\t\tif (name == 'Exo.PushMessage.TokenUpdated') {\r\n\t\t\t\t\t\tgameService.setPushToken(args.token).then(function() {\r\n\t\t\t\t\t\t\tconsole.log('pushService: updated token via gameService');\r\n\t\t\t\t\t\t}, function(err) {\r\n\t\t\t\t\t\t\tconsole.log('pushService: token update via gameService failed');\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t} else if (name == 'Exo.PushMessage.PushMessageClicked') {\r\n\t\t\t\t\t\tconsole.log('pushService: push message clicked. url=' + args.url);\r\n\t\t\t\t\t\tif (args.url == \"fagligedage://messages\") {\r\n\t\t\t\t\t\t\t$state.go('student.messages');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tservice.running = true;\r\n\r\n\t\t\t\twindow.exo.performOperation('Exo.PushMessage.GetToken').then(function(result) {\r\n\t\t\t\t\tvar token = JSON.parse(result.jsonData);\r\n\t\t\t\t\tconsole.log('pushService: got token via Exo.PushMessage.GetToken');\r\n\t\t\t\t\tgameService.setPushToken(token).then(function() {\r\n\t\t\t\t\t\tconsole.log('pushService: updated token via gameService');\r\n\t\t\t\t\t}, function(err) {\r\n\t\t\t\t\t\tconsole.log('pushService: token update via gameService failed');\r\n\t\t\t\t\t});\r\n\t\t\t\t}, function(err) {\r\n\t\t\t\t\tconsole.log('pushService: no token available via Exo.PushMessage.GetToken');\r\n\t\t\t\t});\r\n\r\n\t\t\t\tresolve();\r\n\t\t\t}, function(err) {\r\n\t\t\t\tconsole.log('pushService: failed to initialize: ' + err);\r\n\t\t\t\treject();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treturn service;\r\n}]);\r\n","app.factory('simulatorService', ['$rootScope', '$log', '$window', function ($rootScope, $log, $window) {\r\n\tvar service = this;\r\n\r\n\tservice.isIE = function() {\r\n\t\tvar ua = $window.navigator.userAgent;\r\n\t\treturn window.navigator.userAgent.indexOf(\"Trident\") != -1\r\n\t}\r\n\r\n\tservice.showWithExercise = function(exercise, questionIndex) {\r\n\t\t$log.debug(\"simulatorService: showWithExercise...\");\r\n\r\n\t\tif (service.isIE()) {\r\n\t\t\t$log.debug(\"simulatorService: browser is IE, showing alert.\");\r\n\t\t\t$window.alert(\"Forhåndsvisning fungerer ikke i Internet Explorer\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\twindow.localStorage.setItem(\"simulatorExercise\", JSON.stringify(exercise));\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseQuestionIndex\", \"\" + questionIndex);\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseEvalQuestionIndex\", \"\" + 0);\r\n\t\twindow.localStorage.setItem(\"simulatorFullFlow\", \"false\");\r\n\r\n\t\t$rootScope.$broadcast(\"simulatorShowExercise\", {});\r\n\t}\r\n\r\n\tservice.showWithEvalExercise = function(exercise, questionIndex) {\r\n\t\t$log.debug(\"simulatorService: showWithEvalExercise...\");\r\n\r\n\t\tif (service.isIE()) {\r\n\t\t\t$log.debug(\"simulatorService: browser is IE, showing alert.\");\r\n\t\t\t$window.alert(\"Forhåndsvisning fungerer ikke i Internet Explorer\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\twindow.localStorage.setItem(\"simulatorExercise\", JSON.stringify(exercise));\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseQuestionIndex\", \"\" + 0);\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseEvalQuestionIndex\", \"\" + questionIndex);\r\n\t\twindow.localStorage.setItem(\"simulatorFullFlow\", \"false\");\r\n\r\n\t\t$rootScope.$broadcast(\"simulatorShowEvalExercise\", {});\r\n\t}\r\n\r\n\tservice.showFullExerciseFlowWithExercise = function(exercise) {\r\n\t\t$log.debug(\"simulatorService: showFullExerciseFlowWithExercise...\");\r\n\r\n\t\tif (service.isIE()) {\r\n\t\t\t$log.debug(\"simulatorService: browser is IE, showing alert.\");\r\n\t\t\t$window.alert(\"Forhåndsvisning fungerer ikke i Internet Explorer\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\twindow.localStorage.setItem(\"simulatorExercise\", JSON.stringify(exercise));\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseQuestionIndex\", \"\" + 0);\r\n\t\twindow.localStorage.setItem(\"simulatorExerciseEvalQuestionIndex\", \"\" + 0);\r\n\t\twindow.localStorage.setItem(\"simulatorFullFlow\", \"true\");\r\n\r\n\t\t$rootScope.$broadcast(\"simulatorShowFullExerciseFlowWithExercise\", {});\r\n\t}\r\n\t\r\n\treturn service;\r\n\r\n}]);\r\n","app.factory('stopwatchService', [\"$window\", function ($window) {\n\tvar service = this;\n\n\tservice.stopwatches = {};\n\n\tservice.serialize = function() {\n\t\tconsole.log(\"stopwatchService.serialize()\");\n\t\t$window.localStorage.setItem(\"stopwatchService.stopwatches\", JSON.stringify(service.stopwatches));\n\t}\n\n\tservice.deserialize = function() {\n\t\tconsole.log(\"stopwatchService.deserialize()\");\n\t\tvar stopwatchesJson = $window.localStorage.getItem(\"stopwatchService.stopwatches\");\n\t\tconsole.log(stopwatchesJson);\n\t\tif (stopwatchesJson) {\n\t\t\ttry {\n\t\t\t\tservice.stopwatches = JSON.parse(stopwatchesJson);\n\t\t\t} catch (e) {\n\t\t\t\tservice.stopwatches = {};\n\t\t\t}\n\t\t} else {\n\t\t\tservice.stopwatches = {};\n\t\t}\n\t}\n\n\t// get the current unix timestamp.\n\tservice.timeUnix = function() {\n\t\treturn parseInt((new Date()).getTime() / 1000.0);\n\t}\n\n\tservice.getKey = function(args) {\n\t\tvar key = \"\";\n\t\tfor (var i = 0; i < args.length; i++) {\n\t\t\tkey += args[i] + \":\";\n\t\t}\n\t\tkey = key.substring(0, key.length-1);\n\t\treturn key;\n\t}\n\n\t// start the timer for key.\n\tservice.start = function() {\n\t\tconsole.log(\"stopwatchService.start\");\n\t\tvar key = service.getKey(arguments);\n\t\tvar entry = service.stopwatches[key];\n\t\tif (!entry) {\n\t\t\tentry = {start:0, stop:0, elapsed:0};\n\t\t}\n\t\tif (entry.start == 0) {\n\t\t\tentry.start = service.timeUnix();\n\t\t\tservice.stopwatches[key] = entry;\n\t\t\tservice.serialize();\n\t\t} else {\n\t\t\tconsole.log(\"stopwatchService: ignored attempt to register multiple start times for key \" + key);\n\t\t}\n\t}\n\n\t// stop the timer for key.\n\tservice.stop = function() {\n\t\tconsole.log(\"stopwatchService.stop\");\n\t\tvar key = service.getKey(arguments);\n\t\tvar entry = service.stopwatches[key];\n\t\tif (!entry) {\n\t\t\tentry = {start:0, stop:0, elapsed:0};\n\t\t}\n\t\tif (entry.stop == 0) {\n\t\t\tentry.stop = service.timeUnix();\n\t\t\tentry.elapsed = entry.stop - entry.start;\n\t\t\tservice.stopwatches[key] = entry;\n\t\t\tservice.serialize();\n\t\t} else {\n\t\t\tconsole.log(\"stopwatchService: ignored attempt to register multiple stop times for key \" + key);\n\t\t}\n\t}\n\n\t// get entry for key\n\tservice.get = function() {\n\t\tvar key = service.getKey(arguments);\n\t\tvar entry = service.stopwatches[key];\n\t\treturn entry;\n\t}\n\n\tservice.deserialize();\n\n\treturn service;\n}]);","app.factory('teacherAppService', ['$http', '$q', '$window', '$interval', '$rootScope', 'gameService', function ($http, $q, $window, $interval, $rootScope, gameService) {\n\tvar service = this;\n\n\tservice.gameInfo = [];\n\tservice.gameDayInfo = {};\n\tservice.started = false;\n\tservice.hasImage = false;\n\tservice.paused = false;\n\tservice.currentGroup = 0;\n\tservice.currentGameInfo = {};\n\tservice.groupPickerScrollOffset = 0;\n\n\tservice.isReady = function() {\n\t\treturn service.gameInfo.length > 0;\n\t}\n\n\tservice.setCurrentGroup = function(idx) {\n\t\tservice.currentGroup = idx;\n\t\tservice.currentGameInfo = service.gameInfo[service.currentGroup]; \n\t}\n\n\tservice.startAndSyncImmediately = function() {\n\t\tif (service.started) {\n\t\t\treturn $q(function(resolve, reject) {\n\t\t\t\tresolve();\n\t\t\t});\n\t\t}\n\n\t\t// Sync once a while, at the interval specified in the config.\n\t\t$interval(function() {\n\t\t\tif (service.paused) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tservice.fullSync({noImage: true});\n\t\t}, (gameService.config.teacherAppUpdateIntervalSecs || 10) * 1000.0);\n\n\t\tservice.started = true;\n\n\t\t// Sync now.\n\t\treturn service.fullSync({noImage: true});\n\t}\n\n\tservice.fullSync = function(opts) {\n\t\treturn $q(function(resolve, reject) {\n\t\t\tvar url = \"/api/game/full\";\n\t\t\tif (opts !== undefined && opts.noImage !== undefined) {\n\t\t\t\tif (opts.noImage) {\n\t\t\t\t\turl += \"?noimg=1\";\n\t\t\t\t}\n\t\t\t}\n\t\t\t$http.get(url).then(function(response) {\n\t\t\t\t\tservice.gameInfo = response.data.gameInfo;\n\t\t\t\t\tservice.gameDayInfo = response.data.gameDayInfo;\n\t\t\t\t\t$rootScope.$broadcast('teacherAppServiceUpdated', service.gameInfo);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\treject();\n\t\t\t\t}).catch(function() {\n\t\t\t\t\treject();\n\t\t\t\t});\n\t\t});\n\t}\n\n\treturn service;\n}]);","app.factory('welcomeService', ['$q', '$timeout', function ($q, $timeout) {\r\n\tvar service = this;\r\n\r\n\tservice.w1imageStyle = {\r\n \"background-image\": \"url(\\\"/img/defaultteam.svg\\\")\",\r\n \"background-size\": \"cover\"\r\n };\r\n\r\n\tservice.teamName = undefined;\r\n\tservice.teamImageURL = undefined;\r\n\r\n\tservice.setInitialState = function(obj) {\r\n\t\tvar game = obj.game;\r\n\t\tvar gameState = obj.gameState;\r\n\t\tvar gameConfig = obj.gameConfig;\r\n\t\tvar rides = obj.rides;\r\n\r\n\t\tservice.teamName = game.teamName;\r\n\t\tservice.teamImageURL = game.teamImageURL;\r\n\r\n\t\tif (service.teamImageURL) {\r\n\t\t\tservice.w1imageStyle = {\r\n\t\t\t\t\"background-image\": \"url(\\\"\" + service.teamImageURL + \"\\\")\",\r\n\t\t\t\t\"background-size\": \"cover\"\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\treturn service;\r\n}]);","app.controller('administrationIndexCtrl', [\n '$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {\n }\n]);","app.controller('appCtrl', [\r\n '$scope', 'appService', function ($scope, appService) {\r\n\t\t$scope.style = {};\r\n\r\n\t\tif (appService.isApp) {\r\n\t\t\t$scope.style = {\r\n\t\t\t\t\"user-select\": \"none\",\r\n\t\t\t};\r\n\t\t}\r\n }\r\n]);","app.controller('configIndexCtrl', [\n '$scope', '$rootScope', '$http', '$mdToast', '$state', 'mdContentService', function ($scope, $rootScope, $http, $mdToast, $state, mdContentService) {\n \tvar vm = this;\n\n vm.categories = [\n \t\t{\n \t\t\tkey: \"welcome\",\n \t\t\tname: \"Velkommen-flow\"\n \t\t},\n \t\t{\n \t\t\tkey: \"exercise\",\n \t\t\tname: \"Opgave-flow\"\n \t\t},\n \t\t{\n \t\t\tkey: \"map\",\n \t\t\tname: \"Kortvisning\"\n \t\t},\n {\n key: \"teacherapp\",\n name: \"Lærer-app\"\n },\n {\n key: \"messages\",\n name: \"Beskeder\"\n },\n {\n key: \"test\",\n name: \"Test\"\n }\n \t];\n\n vm.configOptions = [\n {\n category: \"exercise\",\n key: \"targetOKDistanceKM\",\n description: \"How close a student should be to a destination before the 'Next' button is clickable.\",\n type: \"float\",\n defaultValue: 0.05\n },\n {\n category: \"welcome\",\n key: \"allowMapClickThrough\",\n description: \"Whether to allow the 'Please go to your destination' button to be clicked right away. This means that users can proceed with a given exercise without being close to the target ride.\", \n type: \"bool\",\n defaultValue: true\n },\n {\n category: \"welcome\",\n key: \"introMoviePassPercentage\",\n description: \"The percentage at which you're allowed to pass when watching the intro movie in the welcome flow of the app. This is specified as a value between 0.0 and 1.0, which is interpreted as a percentage.\",\n type: \"float\",\n defaultValue: 0.9\n },\n {\n category: \"welcome\",\n key: \"allowSkipIntroMovie\",\n description: \"Whether or not the intro movie is immediately skippable.\",\n type: \"bool\",\n defaultValue: true\n },\n {\n category: \"map\",\n key: \"mapCenter\",\n description: \"The center of the map in the app.\",\n type: \"geopoint\",\n defaultValue: [12.5680196, 55.6737266],\n },\n {\n category: \"map\",\n key: \"mapZoom\",\n description: \"The default zoom level of the map in the app\",\n type: \"float\",\n defaultValue: 16.64\n },\n {\n category: \"map\",\n key: \"mapBearing\",\n description: \"The bearing of the map\",\n type: \"float\",\n defaultValue: -30.0\n },\n {\n category: \"map\",\n key: \"mapAttribution\",\n description: \"Vis attribution streng på kortet i app'en\",\n type: \"bool\",\n defaultValue: false\n },\n {\n category: \"map\",\n key: \"mapAttributionString\",\n description: \"Attribution-strengen som app'en skal bruge på map-visningen.\",\n type: \"string\",\n defaultValue: \"\"\n },\n {\n category: \"map\",\n key: \"mapDragPitch\",\n description: \"Slå drag-pitch til for kortet\",\n type: \"bool\",\n defaultValue: false\n },\n {\n category: \"map\",\n key: \"mapDragRotate\",\n description: \"Slå drag-rotate til for kortet\",\n type: \"bool\",\n defaultValue: false\n },\n {\n category: \"map\",\n key: \"mapDragRotatePitch\",\n description: \"Slå drag-rotate-pitch til for kortet\",\n type: \"bool\",\n defaultValue: false\n },\n {\n category: \"map\",\n key: \"mapGlobalRideScaleFactor\",\n description: \"Global skaleringsfaktor for alle forlystelser på kortet\",\n type: \"float\",\n defaultvalue: 1.0\n },\n {\n category: \"teacherapp\",\n key: \"teacherAppUpdateIntervalSecs\",\n description: \"Opdateringsinterval for lærer-appen (hvor mange sekunder går der imellem lærerappen henter ny data om f.eks. børnenes lokation, opgavefremgang, mm.)\",\n type: \"int\",\n defaultValue: 10\n },\n {\n category: \"messages\",\n key: \"messageServiceUpdateIntervalSecs\",\n description: \"Opdateringsinterval for beskedservicen i lærer- og elev-app'en. Hvor ofte skal der tjekkes efter nye beskeder?\",\n type: \"int\",\n defaultValue: 30\n },\n {\n category: \"test\",\n key: \"testShowRestartButton\",\n description: \"Vis Genstart-knappen i elev-appen (Kun til test)\",\n type: \"bool\",\n defaultValue: false\n }\n ];\n\n vm.prettyCategoryName = function(key) {\n for (var i = 0; i < vm.categories.length; i++) {\n var category = vm.categories[i];\n if (category.key === key) {\n return category.name;\n }\n }\n return \"Unknown\";\n }\n\n vm.parseHierarchy = function() {\n var hier = [];\n for (var i = 0; i < vm.categories.length; i++) {\n var category = vm.categories[i];\n\n var options = [];\n for (var j = 0; j < vm.configOptions.length; j++) {\n var configOption = vm.configOptions[j];\n if (configOption.category !== category.key) {\n continue;\n }\n options.push(JSON.parse(JSON.stringify(configOption)));\n }\n\n var categoryCopy = JSON.parse(JSON.stringify(category));\n categoryCopy.options = options;\n hier.push(categoryCopy);\n }\n return hier;\n }\n\n vm.hierarchy = [];\n vm.loading = true;\n vm.configData = null;\n $http.get('/api/gameconfig').then(function(response) {\n vm.loading = false;\n vm.configData = response.data;\n vm.hierarchy = vm.parseHierarchy();\n\n mdContentService.triggerSyntheticScrollEvent();\n });\n\n vm.save = function() {\n $http.post('/api/gameconfig', vm.configData).then(function() {\n $mdToast.show(\n $mdToast.simple()\n .textContent(\"Config gemt\")\n .position('top right')\n .hideDelay(3000)\n );\n $state.reload();\n });\n }\n }\n]);","app.controller('cookieCtrl', [\r\n '$scope', '$rootScope', '$window', 'appService', function ($scope, $rootScope, $window, appService) {\r\n var isStudentApp = $window.location.href.indexOf(\"/student\") > 0;\r\n var isTeacherApp = $window.location.href.indexOf(\"/teacherapp\") > 0;\r\n var currentCookieState = $window.localStorage.getItem(\"cookieState\");\r\n var cookieStateIsSupported = (window.tuAndroid != null && window.tuAndroid.setCookieState != null) || (window.webkit != null && window.webkit.messageHandlers != null && window.webkit.messageHandlers[\"setCookieState\"] != null);\r\n\r\n \tvar vm = this;\r\n\r\n vm.mode = \"firstrun\";\r\n vm.functional = true;\r\n vm.statistics = false;\r\n \tvm.shown = cookieStateIsSupported && (isStudentApp || isTeacherApp) && currentCookieState == null;\r\n\r\n if (cookieStateIsSupported && (isStudentApp || isTeacherApp) && currentCookieState != null) {\r\n appService.setCookieState(currentCookieState);\r\n }\r\n\r\n $scope.$on('cookieDialogForceShow', function() {\r\n vm.mode = \"firstrun\";\r\n vm.shown = true;\r\n });\r\n\r\n $scope.$on('cookieDialogForceShowRemove', function() {\r\n vm.mode = \"remove\";\r\n vm.shown = true;\r\n });\r\n\r\n vm.hide = function($event) {\r\n if (vm.mode != \"remove\") {\r\n return;\r\n }\r\n vm.shown = false;\r\n }\r\n\r\n vm.onlyFunctional = function() {\r\n var state = \"functional\";\r\n $window.localStorage.setItem(\"cookieState\", state);\r\n appService.setCookieState(state);\r\n\r\n vm.shown = false;\r\n }\r\n\r\n vm.accept = function() {\r\n var state = this.statistics ? \"all\" : \"functional\";\r\n $window.localStorage.setItem(\"cookieState\", state);\r\n appService.setCookieState(state);\r\n\r\n vm.shown = false;\r\n }\r\n\r\n vm.toggleChanged = function() {\r\n var state = this.statistics ? \"all\" : \"functional\";\r\n $window.localStorage.setItem(\"cookieState\", state);\r\n appService.setCookieState(state);\r\n }\r\n }\r\n]);\r\n","app.controller('exercisesAddCtrl', ['$scope', '$rootScope', '$state', '$stateParams', '$http', '$mdDialog', '$mdMedia', '$mdToast', 'Upload', 'exerciseService', 'simulatorService',\n\tfunction ($scope, $rootScope, $state, $stateParams, $http, $mdDialog, $mdMedia, $mdToast, Upload, exerciseService, simulatorService) {\n\n\t\tvar vm = this;\n\n\t\tvm.maxTimeMinutes = function() {\n\t\t\tvar minutes = [];\n\t\t\tfor (var i = 10; i <= 60; i += 5) {\n\t\t\t\tminutes.push(i);\n\t\t\t}\n\t\t\treturn minutes;\n\t\t}\n\n\t\tvm.schoolCategories = [\n\t\t\t{ value: 1, name: \"4. - 6. klasse\" },\n\t\t\t{ value: 2, name: \"7. - 10. klasse\" },\n\t\t\t{ value: 3, name: \"Ungdomsuddannelser\"}\n\t\t];\n\n\t\tvar tivoliCenter = [12.5680196, 55.6737266];\n\n\t\tvm.form = {};\n\t\tvm.submitting = false;\n\n\t\tvm.model = {\n\t\t\tschoolCategory: 1,\n\t\t\tnumber: 0,\n\t\t\tname: \"\",\n\t\t\tdescription: \"\",\n\t\t\timageUrl: null,\n\t\t\ttimeMinutes: 5,\n\t\t\tteacherInfoShortText: \"\",\n\t\t\tteacherInfoLongText: \"\",\n\t\t\tmapPos: tivoliCenter,\n\t\t\tmapText: \"\",\n\t\t\tgoalsText: \"\",\n\t\t\tgoals: [\"\", \"\", \"\", \"\"],\n\t\t\tquestions: [],\n\t\t\tevaluationQuestions: [],\n\t\t};\n\n\t\tvm.exercise = null;\n\t\tvm.loaded = true;\n\t\tif ($stateParams.id) {\n\t\t\tvm.loaded = false;\n\t\t\texerciseService.get($stateParams.id).then(function(exercise) {\n\t\t\t\tif (exercise) {\n\t\t\t\t\tvm.model = exercise;\n\t\t\t\t\tvm.exercise = exercise;\n\n\t\t\t\t\tif (vm.model.teacherInfoShortText == null) {\n\t\t\t\t\t\tvm.model.teacherInfoShortText = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (vm.model.teacherInfoLongText == null) {\n\t\t\t\t\t\tvm.model.teacherInfoLongText = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!vm.model.questions) {\n\t\t\t\t\t\tvm.model.questions = [];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!vm.model.evaluationQuestions) {\n\t\t\t\t\t\tvm.model.evaluationQuestions = [];\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var i = 0; i < vm.model.questions.length; i++) {\n\t\t\t\t\t\tvar q = vm.model.questions[i];\n\t\t\t\t\t\tq.index = i;\n\t\t\t\t\t\tq.hidden = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var i = 0; i < vm.model.evaluationQuestions.length; i++) {\n\t\t\t\t\t\tvar q = vm.model.evaluationQuestions[i];\n\t\t\t\t\t\tq.index = i;\n\t\t\t\t\t\tq.hidden = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tvm.loaded = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvm.hideQuestion = function(question) {\n\t\t\tquestion.hidden = true;\n\t\t}\n\n\t\tvm.showQuestion = function(question) {\n\t\t\tquestion.hidden = false;\n\t\t}\n\n\t\tvm.addQuestion = function(container, evt) {\n\t\t\tevt.preventDefault();\n\n\t\t\tvar questionObj = {\n\t\t\t\t\tindex: container.length,\n\t\t\t\t\thidden: true,\n\t\t\t\t\ttext: \"\",\n\t\t\t\t\textraButtonText: \"\",\n\t\t\t\t\textraHtml: \"\",\n\t\t\t\t\tanswers: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tindex: 0,\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\twrongAnswerText: \"\",\n\t\t\t\t\t\t\tcorrect: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tindex: 1,\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\twrongAnswerText: \"\",\n\t\t\t\t\t\t\tcorrect: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tindex: 2,\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\twrongAnswerText: \"\",\n\t\t\t\t\t\t\tcorrect: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tindex: 3,\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\twrongAnswerText: \"\",\n\t\t\t\t\t\t\tcorrect: false\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\tcontainer.push(questionObj);\n\t\t}\n\n\t\tvm.listOrderChanged = function(container) {\n\t\t\t$scope.$apply(function() {\n\t\t\t\tfor (var i = 0; i < container.length; i++) {\n\t\t\t\t\tcontainer[i].index = i;\n\t\t\t\t}\n\t\t\t});\t\n\t\t}\n\n\t\tvm.removeQuestion = function(container, question, evt) {\n\t\t\tevt.preventDefault();\n\n \tvar confirm = $mdDialog.confirm()\n\t .title('Fjern spørgsmål?')\n\t .textContent('Er du sikker på at du vil fjerne spørgsmålet?')\n\t .ariaLabel('Fjern spørgsmål')\n\t .targetEvent(evt)\n\t .ok('Fjern')\n\t .cancel('Anullér');\n \t$mdDialog.show(confirm).then(function () {\n\t\t\t\tvar newQuestions = [];\n\t\t\t\tfor (var i = 0; i < container.length; i++) {\n\t\t\t\t\tvar iterQuestion = container[i];\n\t\t\t\t\tif (question == iterQuestion) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tnewQuestions.push(iterQuestion);\n\t\t\t\t}\n\n\t\t\t\t// Remove & re-add\n\t\t\t\twhile (container.length > 0) {\n\t\t\t\t\tcontainer.pop();\n\t\t\t\t}\n\t\t\t\tfor (var i = 0; i < newQuestions.length; i++) {\n\t\t\t\t\tvar newQ = newQuestions[i];\n\t\t\t\t\tnewQ.index = i;\n\t\t\t\t\tcontainer.push(newQ);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvm.uploading = false;\n\t\tvm.upload = function (file) {\n\t\t\tif (file == null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tFD.BlobToDataURL(file).then(function(dataUrl) {\n\t\t\t\tvm.model.imageUrl = dataUrl;\n\t\t\t});\n }\n\n vm.removeImage = function(evt) {\n \tevt.preventDefault();\n\n \tvar confirm = $mdDialog.confirm()\n\t .title('Fjern billede?')\n\t .textContent('Er du sikker på at du vil fjerne dette billede?')\n\t .ariaLabel('Fjern billede')\n\t .targetEvent(evt)\n\t .ok('Fjern')\n\t .cancel('Anullér');\n \t$mdDialog.show(confirm).then(function () {\n\t\t\t\tvm.model.imageUrl = null;\n\t\t\t});\n }\n\n\t\tvm.map = new maptalks.Map('maptalksc', {\n \tcenter: vm.model.mapPos,\n \tzoom: 16.64,\n \tbearing: 150.0,\n \tattribution: false,\n\n\t //allow map to drag pitching, true by default\n \tdragPitch : false,\n \t//allow map to drag rotating, true by default\n \tdragRotate : true,\n \t//enable map to drag pitching and rotating at the same time, false by default\n \tdragRotatePitch : false,\n\n \tbaseLayer: new maptalks.TileLayer('base', {\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n \t\tsubdomains: ['a','b','c','d'],\n \t\tattribution: ''\n \t})\n \t});\n\n\t\tvar center = vm.map.getCenter();\n\t\tvm.mapOverlayLayer = new maptalks.VectorLayer('vector').addTo(vm.map);\n\n // Add the go-to pos\n \tvm.targetMarker = new maptalks.Marker(\n \t\tvm.model.mapPos,\n \t{\n\t \t'symbol' : {\n\t \t'markerFile' : window.location.origin + '/img/map/MapPin.svg',\n\t \t'markerWidth' : 2*22,\n\t \t'markerHeight' : 2*35.5,\n\t \t'markerDx' : 0,\n\t \t'markerDy' : 0,\n\t \t'markerOpacity': 1\n\t \t}\n\t \t}\n \t);\n \tvm.targetMarker.addTo(vm.mapOverlayLayer);\n\n \tvm.map.on('click', function(evt) {\n \t\t$scope.$apply(function() {\n\t \t\tvm.targetMarker.setCoordinates(evt.coordinate);\n\t \t\tvm.model.mapPos = [evt.coordinate.x, evt.coordinate.y];\n\t \t});\n \t});\n\n \t$scope.$watch('vm.model.mapPos', angular.bind(vm, function() {\n \t\tvm.targetMarker.setCoordinates(vm.model.mapPos);\n \t}), true);\n\n \tvm.resetMap = function() {\n \t\tvm.map.setCenter(tivoliCenter);\n \t\tvm.map.setZoom(16.64);\n \t\tvm.map.setBearing(150.0);\n \t}\n\n\t\tvm.previewQuestion = function(exercise, questionIndex, evt) {\n\t\t\tevt.preventDefault();\n\n\t\t\tsimulatorService.showWithExercise(exercise, questionIndex);\n \t}\n\n \tvm.save = function () {\n \t// Ensure timeMinutes is an int.\n \tif (vm.model.timeMinutes) {\n \t\tvm.model.timeMinutes = parseInt(vm.model.timeMinutes);\n \t}\n\n if (!vm.form.$valid)\n return;\n vm.submitting = true;\n\n if (vm.exercise) {\n \tvm.model.id = vm.exercise.id; // XXX\n\t $http.post('api/exercise', vm.model, {headers: {'Content-Type': 'application/json'}})\n\t .then(function (resp) {\n\t $mdToast.show(\n\t $mdToast.simple()\n\t .textContent(\"Opgave opdateret\")\n\t .position('top right')\n\t .hideDelay(3000)\n\t );\n\t $state.go('exercises.details', {'id': resp.data.id}, { reload: true });\n\t }, function (err) {\n\t vm.submitting = false;\n\t if (err.status === 409) {\n\t vm.form.name.$setValidity(\"taken\", false);\n\t }\n\t });\n } else {\n\t $http.put('api/exercise', vm.model, {headers: {'Content-Type': 'application/json'}})\n\t .then(function (resp) {\n\t $mdToast.show(\n\t $mdToast.simple()\n\t .textContent(\"Opgave tilføjet\")\n\t .position('top right')\n\t .hideDelay(3000)\n\t );\n\t $state.go('exercises.details', {'id': resp.data.id}, {reload: true});\n\t }, function (err) {\n\t vm.submitting = false;\n\n\t if (err.status === 409) {\n\t vm.form.name.$setValidity(\"taken\", false);\n\t }\n\t });\n\t }\n }\n\t}\n]);","app.controller('exercisesAddEvaluationAnswerCtrl', ['$scope', '$rootScope', '$mdDialog',\n\tfunction ($scope, $rootScope, $mdDialog) {\n\t\t$scope.close = function() {\n\t\t\t$mdDialog.cancel();\n\t\t}\n\t}\n]);","app.controller('exercisesIndexCtrl', [\n '$scope', '$rootScope', '$http', 'exerciseService', function ($scope, $rootScope, $http, exerciseService) {\n \tvar vm = this;\n\n \tvm.exerciseService = exerciseService;\n \tvm.exerciseService.load();\n\n \tvm.delete = function(exercise, $event) {\n \t\tvm.exerciseService.askDelete(exercise, $event);\n \t}\n }\n]);","app.controller('freeGameIndexCtrl', [\n '$scope', '$rootScope', '$http', '$mdToast', '$state', 'mdContentService', function ($scope, $rootScope, $http, $mdToast, $state, mdContentService) {\n \tvar vm = this;\n\n vm.loaded = false;\n vm.game = null;\n vm.allExercises = [];\n vm.selectedExercise = -1;\n vm.exercises = [];\n\n vm.getExercise = function(id) {\n for (var i = 0; i < vm.allExercises.length; i++) {\n var exercise = vm.allExercises[i];\n if (exercise.id === id) {\n return exercise;\n }\n }\n return null;\n }\n\n vm.onExerciseSelected = function() {\n if (vm.selectedExercise === -1) {\n return;\n }\n\n var exercise = vm.getExercise(vm.selectedExercise);\n var exerciseCopy = angular.copy(exercise);\n vm.exercises = [exerciseCopy];\n\n vm.selectedExercise = -1;\n }\n\n vm.removeExercise = function(idx) {\n var newExercises = [];\n for (var i = 0; i < vm.exercises.length; i++) {\n if (i == idx) {\n continue;\n }\n newExercises.push(vm.exercises[i]);\n }\n vm.exercises = newExercises;\n }\n\n $http.get('/api/freegame').then(function(response) {\n var freeGameData = response.data;\n $http.get('/api/exercise').then(function(response) {\n vm.loaded = true;\n vm.game = freeGameData;\n vm.exercises = vm.game.exercises;\n if (!vm.exercises) {\n vm.exercises = [];\n }\n for (var i = 0; i < vm.exercises.length; i++) {\n vm.exercises[i].index = i;\n }\n vm.allExercises = response.data.items;\n\n mdContentService.triggerSyntheticScrollEvent();\n });\n });\n\n vm.save = function() {\n var model = {\n key: \"main\",\n created: 0,\n modified: 0,\n startTime: 0,\n timeImageURL: \"\",\n teamMembers: [],\n teamName: \"\",\n exercises: vm.exercises\n };\n $http.post('/api/freegame', model).then(function() {\n $mdToast.show(\n $mdToast.simple()\n .textContent(\"Øvelsesopgave gemt\")\n .position('top right')\n .hideDelay(3000)\n );\n $state.reload();\n });\n }\n }\n]);","app.controller('homeIndexCtrl', [\n '$scope', '$rootScope', '$http', 'me', function ($scope, $rootScope, $http, me) {\n \t$rootScope.me = me;\n }\n]);","app.controller('profileIndexCtrl', [\n '$scope', '$rootScope', '$http', '$state', 'authService', 'me', '$mdToast', function ($scope, $rootScope, $http, $state, authService, me, $mdToast) {\n var vm = this;\n\n \tvm.model = {\n\t\t\tname: me.name,\t\t\n\t\t\temail: me.email,\n\t\t\tpassword: '',\n\t\t\tpasswordAgain: '',\n\t\t\tform: {}\n\t\t};\n\n\t\tvm.save = function () {\n if (!vm.model.form.$valid) {\n return;\n }\n\n vm.model.submitting = true;\n\n $http.post('api/me', vm.model)\n .then(function (resp) {\n $mdToast.show(\n $mdToast.simple()\n .textContent(\"Profil opdateret\")\n .position('top right')\n .hideDelay(3000)\n );\n $state.go('profile');\n }, function (err) {\n vm.model.submitting = false;\n if (err.status === 409) {\n vm.model.form.name.$setValidity(\"taken\", false);\n }\n });\n }\n }\n]);","app.controller('ridesAddCtrl', ['$scope', '$rootScope', '$state', '$stateParams', '$http', '$mdDialog', '$mdMedia', '$mdToast', 'Upload', 'exerciseService',\n\tfunction ($scope, $rootScope, $state, $stateParams, $http, $mdDialog, $mdMedia, $mdToast, Upload, exerciseService) {\n\t\tvar vm = this;\n\n\t\tvar tivoliCenter = [12.5680196, 55.6737266];\n\n\t\tvm.form = {};\n\t\tvm.submitting = false;\n\n\t\tvm.model = {\n\t\t\tkey: \"\",\n\t\t\tname: \"\",\n\t\t\tlocation: tivoliCenter,\n\t\t\tmarkerImage: null,\n\t\t\tmarkerWidth: 0,\n\t\t\tmarkerHeight: 0,\n\t\t\tmarkerScaleFactor: 0,\n\t\t\tmarkerZIndex: 0,\n\t\t\tenabled: false\n\t\t};\n\n\t\tvm.ride = null;\n\t\tvm.loading = false;\n\t\tif ($stateParams.id) {\n\t\t\tvm.loading = true;\n\t\t\t$http.get('/api/rides/' + $stateParams.id).then(function(response) {\n\t\t\t\tvar ride = response.data;\n\t\t\t\tif (ride) {\n\t\t\t\t\tvm.model = ride;\n\t\t\t\t\tvm.ride = ride;\n\t\t\t\t\tif (vm.ride.markerScaleFactor == 0) {\n\t\t\t\t\t\tvm.ride.markerScaleFactor = 1.0;\n\t\t\t\t\t}\n\t\t\t\t\tvm.loading = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvm.uploading = false;\n\t\tvm.upload = function (file) {\n\t\t\tif (file == null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tFD.BlobToDataURL(file).then(function(dataUrl) {\n\t\t\t\tvm.model.markerImage = dataUrl;\n\t\t\t});\n }\n\n vm.removeImage = function(evt) {\n \tevt.preventDefault();\n\n \tvar confirm = $mdDialog.confirm()\n\t .title('Fjern billede?')\n\t .textContent('Er du sikker på at du vil fjerne dette billede?')\n\t .ariaLabel('Fjern billede')\n\t .targetEvent(evt)\n\t .ok('Fjern')\n\t .cancel('Anullér');\n \t$mdDialog.show(confirm).then(function () {\n\t\t\t\tvm.model.markerImage = null;\n\t\t\t});\n }\n\n\t\tvm.map = new maptalks.Map('maptalksc', {\n \tcenter: vm.model.location,\n \tzoom: 16.64,\n \tbearing: 150.0,\n \tattribution: false,\n\n\t //allow map to drag pitching, true by default\n \tdragPitch : false,\n \t//allow map to drag rotating, true by default\n \tdragRotate : true,\n \t//enable map to drag pitching and rotating at the same time, false by default\n \tdragRotatePitch : false,\n\n \tbaseLayer: new maptalks.TileLayer('base', {\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n \t\tsubdomains: ['a','b','c','d'],\n \t\tattribution: ''\n \t})\n \t});\n\n\t\tvar center = vm.map.getCenter();\n\t\tvm.mapOverlayLayer = new maptalks.VectorLayer('vector').addTo(vm.map);\n\n // Add the go-to pos\n \tvm.targetMarker = new maptalks.Marker(\n \t\tvm.model.location,\n \t{\n\t \t'symbol' : {\n\t \t'markerFile' : window.location.origin + '/img/map/MapPin.svg',\n\t \t'markerWidth' : 2*22,\n\t \t'markerHeight' : 2*35.5,\n\t \t'markerDx' : 0,\n\t \t'markerDy' : 0,\n\t \t'markerOpacity': 1\n\t \t}\n\t \t}\n \t);\n \tvm.targetMarker.addTo(vm.mapOverlayLayer);\n\n \t$scope.$watch('vm.model.location', angular.bind(vm, function() {\n \t\tvm.targetMarker.setCoordinates(vm.model.location);\n \t}), true);\n\n \tvm.map.on('click', function(evt) {\n \t\t$scope.$apply(function() {\n\t \t\tvm.targetMarker.setCoordinates(evt.coordinate);\n\t \t\tvm.model.location = [evt.coordinate.x, evt.coordinate.y];\n\t \t});\n \t});\n\n \tvm.resetMap = function() {\n \t\tvm.map.setCenter(tivoliCenter);\n \t\tvm.map.setZoom(16.64);\n \t\tvm.map.setBearing(150.0);\n \t}\n\n \tvm.save = function () {\n if (!vm.form.$valid)\n return;\n vm.submitting = true;\n\n if (vm.exercise) {\n \tvm.model.id = vm.ride.id; // XXX\n\t $http.post('api/rides', vm.model, {headers: {'Content-Type': 'application/json'}})\n\t .then(function (resp) {\n\t $mdToast.show(\n\t $mdToast.simple()\n\t .textContent(\"Forlystelse opdateret\")\n\t .position('top right')\n\t .hideDelay(3000)\n\t );\n\t $state.go('rides.details', {'id': resp.data.key}, { reload: true });\n\t }, function (err) {\n\t vm.submitting = false;\n\t if (err.status === 409) {\n\t vm.form.name.$setValidity(\"taken\", false);\n\t }\n\t });\n } else {\n\t $http.put('api/rides', vm.model, {headers: {'Content-Type': 'application/json'}})\n\t .then(function (resp) {\n\t $mdToast.show(\n\t $mdToast.simple()\n\t .textContent(\"Forlystelse tilføjet\")\n\t .position('top right')\n\t .hideDelay(3000)\n\t );\n\t $state.go('rides.details', {'id': resp.data.key}, {reload: true});\n\t }, function (err) {\n\t vm.submitting = false;\n\n\t if (err.status === 409) {\n\t vm.form.name.$setValidity(\"taken\", false);\n\t }\n\t });\n\t }\n }\n\t}\n]);","app.controller('ridesIndexCtrl', [\n '$scope', '$rootScope', '$http', 'mdContentService', function ($scope, $rootScope, $http, mdContentService) {\n \tvar vm = this;\n\n \tvm.rides = [];\n \tvm.loaded = false;\n \t$http.get('/api/rides').then(function(response) {\n \t\tvm.loaded = true;\n \t\tvm.rides = response.data.items;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t});\n\n \t$scope.delete = function(exerciseSet, $event) {\n \t\tconsole.log(\"nyi\");\n \t}\n }\n]);","app.controller('simulatorCtrl', [\r\n '$scope', '$rootScope', '$log', '$window', function ($scope, $rootScope, $log, $window) {\r\n \tvar vm = this;\r\n\r\n \tvm.nested = window.parent != window;\r\n\r\n \tvm.srcUrl = \"\";\r\n \tvm.hidden = true;\r\n\r\n \t$scope.$on(\"simulatorShowExercise\", function() {\r\n \t\t$log.debug(\"simulatorCtrl: simulatorShowExercise received\");\r\n\r\n \t\tvm.srcUrl = \"/preview/exerciseperform\";\r\n \t\tvm.hidden = false;\r\n\r\n \t\tangular.element(\".simulator iframe.content\")[0].src = vm.srcUrl;\r\n \t});\r\n\r\n $scope.$on(\"simulatorShowFullExerciseFlowWithExercise\", function() {\r\n $log.debug(\"simulatorCtrl: simulatorShowFullExerciseFlowWithExercise received\");\r\n\r\n vm.srcUrl = \"/preview/exercisebegin\";\r\n vm.hidden = false;\r\n\r\n angular.element(\".simulator iframe.content\")[0].src = vm.srcUrl;\r\n });\r\n\r\n \t$scope.$on(\"simulatorShowEvalExercise\", function() {\r\n \t\t$log.debug(\"simulatorCtrl: simulatorShowEvalExercise received\");\r\n\r\n\t\t\tvm.srcUrl = \"/preview/exerciseevalperform\";\r\n \t\tvm.hidden = false;\r\n\r\n \t\tangular.element(\".simulator iframe.content\")[0].src = vm.srcUrl;\r\n \t});\r\n\r\n vm.onMessageReceived = function(evt) {\r\n $scope.$apply(function() {\r\n if (evt.origin != window.location.origin) {\r\n return;\r\n }\r\n\r\n var data = evt.data;\r\n if (data == \"simulator.close\") {\r\n vm.close(); \r\n }\r\n });\r\n }\r\n\r\n $window.addEventListener(\"message\", vm.onMessageReceived, false);\r\n\r\n \tvm.close = function() {\r\n \t\tvm.hidden = true;\r\n \t}\r\n }\r\n]);\r\n","app.controller('ridesIndexCtrl', [\n '$scope', '$rootScope', '$http', 'mdContentService', function ($scope, $rootScope, $http, mdContentService) {\n \tvar vm = this;\n\n \tvm.rides = [];\n \tvm.loaded = false;\n \t$http.get('/api/rides').then(function(response) {\n \t\tvm.loaded = true;\n \t\tvm.rides = response.data.items;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t});\n\n \t$scope.delete = function(exerciseSet, $event) {\n \t\tconsole.log(\"nyi\");\n \t}\n }\n]);","app.controller('statsIndexCtrl', [\n '$scope', '$rootScope', '$http', 'mdContentService', '$locale', '$filter', function ($scope, $rootScope, $http, mdContentService, $locale, $filter) {\n \tvar vm = this;\n\n $locale.NUMBER_FORMATS.GROUP_SEP = '.';\n $locale.NUMBER_FORMATS.DECIMAL_SEP = \",\";\n\n \tvm.rides = [];\n \tvm.loaded = false;\n\n vm.chosenWeek = null;\n vm.chosenSchoolCategory = null;\n\n $scope.$watch('vm.chosenWeek', function() {\n if (vm.loaded) {\n vm.fetchData();\n }\n });\n\n $scope.$watch('vm.chosenSchoolCategory', function() {\n if (vm.loaded) {\n vm.fetchData();\n }\n });\n\n vm.fetchData = function() {\n var url = '/api/analytics/stats';\n if (vm.chosenWeek != null && vm.chosenSchoolCategory != null) {\n url += \"?week=\" + vm.chosenWeek + '&schoolCategory=' + vm.chosenSchoolCategory;\n }\n $http.post(url).then(function(response) {\n vm.stats = response.data;\n \n if (vm.chosenWeek == null) {\n vm.chosenWeek = vm.stats.weeks[0].value;\n }\n if (vm.chosenSchoolCategory == null) {\n vm.chosenSchoolCategory = vm.stats.schoolCategories[0].value;\n }\n \n vm.loaded = true;\n\n mdContentService.triggerSyntheticScrollEvent();\n\n // XXX: reload graphs\n\n vm.exerciseComplete = vm.makeChart(vm.stats.completedExercises);\n vm.teacherMsg = vm.makeChart(vm.stats.teacherMessages);\n vm.popularExercises = vm.makeExerciseChart(vm.stats.popularExercises);\n vm.exerciseTime = vm.makeExerciseTimeChart(vm.stats.averageTimeSpentPerExercise);\n\n var exercises = [];\n for (var i = 0; i < vm.stats.exercises.length; i++) {\n var exerciseStats = vm.stats.exercises[i];\n var questions = [];\n\n console.dir(exerciseStats);\n\n for (var j = 0; j < exerciseStats.questionStats.length; j++) {\n var questionStats = exerciseStats.questionStats[j];\n questions.push({\n numberOfTriesChart: vm.makeNumberOfTriesChart(questionStats.numTriesGroups),\n stats: questionStats,\n });\n }\n\n exercises.push({\n completionTimeGroupsChart: vm.makeCompletionTimeChart(exerciseStats.completionTimeGroups),\n stats: exerciseStats,\n questions: questions\n });\n }\n\n vm.exerciseStats = exercises;\n });\n }\n\n vm.fetchData();\n\n vm.makeChart = function(statsData) {\n var chart = {};\n\n chart.labels = statsData.labels;\n chart.data = statsData.data;\n //chart.series = [\"Antal gennemførte opgaver\"];\n chart.datasetOverride = [{ yAxisID: 'y-axis-1' }, { yAxisID: 'y-axis-2' }];\n chart.options = {\n scales: {\n yAxes: [\n {\n id: 'y-axis-1',\n type: 'linear',\n display: true,\n position: 'left'\n },\n {\n id: 'y-axis-2',\n type: 'linear',\n display: true,\n position: 'right'\n }\n ]\n }\n };\n\n return chart;\n }\n\n vm.makeExerciseChart = function(statsData) {\n var chart = {};\n chart.labels = statsData.labels;\n chart.data = statsData.data;\n chart.series = [\"Populare opgaver\"];\n chart.datasetOverride = [];\n chart.options = {};\n return chart;\n }\n\n vm.makeExerciseTimeChart = function(statsData) {\n var chart = {};\n\n chart.labels = statsData.labels;\n chart.data = statsData.data;\n\n chart.series = [\"Tidsforbrug for opgaver (gennemsnit i minutter)\"];\n chart.datasetOverride = [];\n chart.options = {\n scales: {\n xAxes: [{\n ticks: {\n beginAtZero: true\n }\n }]\n },\n tooltips: {\n callbacks: {\n label: function(tooltipItem, data) {\n var label = data.datasets[tooltipItem.datasetIndex].label || '';\n\n if (label) {\n label += ': ';\n }\n label += $filter('number')(tooltipItem.xLabel, 2)\n return label;\n }\n }\n }\n };\n\n return chart;\n }\n\n vm.makeCompletionTimeChart = function(completionTimeGroups) {\n var chart = {};\n\n chart.labels = [\"0-15 min.\", \"15-30 min.\", \"30 min. eller mere\"]\n chart.data = [completionTimeGroups.num0to15, completionTimeGroups.num15to30, completionTimeGroups.num30orGreater];\n\n chart.series = [\"Antal forsøg før opgaven er løst\"];\n chart.datasetOverride = [];\n chart.options = {\n scales: {\n xAxes: [{\n ticks: {\n beginAtZero: true\n }\n }]\n },\n };\n\n return chart;\n }\n\n vm.makeNumberOfTriesChart = function(numberOfTriesGroups) {\n var chart = {};\n\n chart.labels = [\"Første forsøg\", \"Andet forsøg\", \"Tredje forsøg\", \"Fjerde forsøg\"]\n chart.data = [numberOfTriesGroups.firstTry, numberOfTriesGroups.secondTry, numberOfTriesGroups.thirdTry, numberOfTriesGroups.fourthTry];\n\n chart.series = [\"Antal forsøg før opgaven er løst\"];\n chart.datasetOverride = [];\n chart.options = {};\n\n return chart;\n }\n }\n]);","app.controller('studentIndexCtrl', [\r\n '$scope', '$rootScope', '$http', 'me', function ($scope, $rootScope, $http, me) {\r\n \t$rootScope.me = me;\r\n }\r\n]);","app.controller('teacherIndexCtrl', [\n '$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {\n }\n]);","app.controller('teacherEvaluationCtrl', [\n '$scope', '$rootScope', '$http', '$state', '$stateParams', 'mdContentService', function ($scope, $rootScope, $http, $state, $stateParams, mdContentService) {\n \tvar vm = this;\n\n \tvm.loaded = false;\n\n vm.games = [];\n vm.gameStates = [];\n vm.gameDay = {};\n\n vm.game = null;\n vm.gameIndex = 0;\n\n $http.get('/api/gameday/games').then(function(response) {\n vm.games = response.data.games;\n vm.gameStates = response.data.gameStates;\n\n $http.get('/api/gameday').then(function(response) {\n vm.gameDay = response.data;\n vm.loaded = true;\n\n vm.gameIndex = 0;\n vm.game = vm.games[vm.gameIndex];\n\n mdContentService.triggerSyntheticScrollEvent();\n });\n });\n\n vm.setGameIndex = function(idx) {\n vm.gameIndex = idx;\n vm.game = vm.games[vm.gameIndex];\n }\n\n vm.print = function() {\n window.print();\n }\n\n }\n]);","app.controller('teacherGroupDetailsCtrl', [\n '$scope', '$rootScope', '$http', '$state', '$stateParams', 'mdContentService', function ($scope, $rootScope, $http, $state, $stateParams, mdContentService) {\n \tvar vm = this;\n\n \tvm.loaded = false;\n \tvm.game = {}\n vm.gameIndex = 0;\n\n vm.members = new Array(6);\n for (var i = 0; i < vm.members.length; i++) {\n vm.members[i] = \"\";\n }\n\n vm.exercises = [];\n\n \t$http.get('/api/gameday/games').then(function(response) {\n var games = response.data.games;\n var game;\n var gameIndex = 0;\n for (var i = 0; i < games.length; i++) {\n var iterGame = games[i];\n if (iterGame.key == $stateParams.id) {\n game = iterGame;\n gameIndex = i;\n break;\n }\n }\n if (!game) {\n return;\n }\n\n \t\tvm.game = game;\n vm.gameIndex = gameIndex;\n\n for (var i = 0; i < Math.min(vm.game.teamMembers.length, 6); i++) {\n vm.members[i] = vm.game.teamMembers[i];\n }\n\n vm.exercises = angular.copy(vm.game.exercises);\n\n vm.loaded = true;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t});\n\n vm.sanitizedMembers = function() {\n var newMembers = [];\n\n for (var i = 0; i < vm.members.length; i++) {\n var member = vm.members[i];\n var trimmedMember = member.trim();\n if (trimmedMember.length === 0) {\n continue;\n }\n newMembers.push(trimmedMember);\n }\n\n return newMembers;\n }\n\n \tvm.save = function(evt, done) {\n evt.preventDefault();\n \n var game = angular.copy(vm.game);\n game.teamMembers = vm.sanitizedMembers();\n game.exercises = vm.exercises;\n\n \t\t$http.put('/api/gameday/game/' + $stateParams.id, game).then(function(response) {\n if (done === undefined) {\n \t\t\t $state.reload();\n } else {\n $state.go('teacher.setupgroups');\n }\n \t\t});\n \t}\n\n vm.done = function(evt) {\n vm.save(evt, true);\n }\n }\n]);","app.controller('teacherGroupsCtrl', [\n '$scope', '$rootScope', '$http', '$state', 'mdContentService', function ($scope, $rootScope, $http, $state, mdContentService) {\n \tvar vm = this;\n\n \tvm.loaded = false;\n \tvm.games = [];\n \tvm.gameDay = {};\n vm.includeExercisesInPrint = true;\n\n \t$http.get('/api/gameday/games').then(function(response) {\n \t\tvm.games = response.data.games;\n \t\t$http.get('/api/gameday').then(function(response) {\n \t\t\tvm.gameDay = response.data;\n \t\t\tvm.loaded = true;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t\t});\n \t});\n\n vm.print = function() {\n window.print();\n }\n }\n]);","app.controller('teacherIndexCtrl', [\n '$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {\n }\n]);","app.controller('teacherInfoCtrl', [\n function () {\n \tvar vm = this;\n }\n]);\n","app.controller('teacherLoginCtrl', [\n '$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {\n }\n]);","app.controller('teacherSetupExercisesCtrl', [\n '$scope', '$rootScope', '$http', '$mdToast', '$state', 'mdContentService', 'simulatorService', function ($scope, $rootScope, $http, $mdToast, $state, mdContentService, simulatorService) {\n \tvar vm = this;\n\n \tvm.selectedExercises = [];\n \tvm.allExercises = [];\n vm.gameDay = null;\n \tvm.loaded = false;\n\n vm.exerciseTooltipShown = [];\n vm.exerciseTooltipExpand = [];\n\n \t\t$http.get('/api/gameday/exercises').then(function(response) {\n \t\t\tvm.allExercises = response.data.items;\n \t\t\tvm.selectedExercises = new Array(vm.allExercises.length);\n vm.exerciseTooltipShown = new Array(vm.allExercises.length);\n \t\t\t\n \t\t\t$http.get('/api/gameday').then(function(response) {\n \t\t\t\tvar gameDay = response.data;\n \t\t\t\tfor (var i = 0; i < vm.allExercises.length; i++) {\n \t\t\t\t\tvar exercise = vm.allExercises[i];\n \t\t\t\t\tif (gameDay.exercises && gameDay.exercises.indexOf(exercise.id) !== -1) {\n \t\t\t\t\t\tvm.selectedExercises[i] = true;\n \t\t\t\t\t} else {\n \t\t\t\t\t\tvm.selectedExercises[i] = false;\n \t\t\t\t\t}\n vm.exerciseTooltipShown[i] = false;\n vm.exerciseTooltipExpand[i] = false;\n \t\t\t\t}\n vm.gameDay = gameDay;\n \t\t\t\tvm.loaded = true;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t\t\t});\n \t\t});\n\n vm.previewExercise = function(exercise) {\n simulatorService.showFullExerciseFlowWithExercise(exercise);\n }\n\n \t\tvm.save = function() {\n \t\t\tvar ids = [];\n \t\t\tfor (var i = 0; i < vm.allExercises.length; i++) {\n \t\t\t\tvar isSelected = vm.selectedExercises[i];\n \t\t\t\tif (isSelected) {\n \t\t\t\t\tvar exercise = vm.allExercises[i];\n \t\t\t\t\tids.push(exercise.id);\n \t\t\t\t}\n \t\t\t}\n\n \t\t\tvar gdpe = {\n \t\t\t\texercises: ids,\n \t\t\t}\n\n $http.post('/api/gameday/setupexercises', gdpe, {headers: {'Content-Type': 'application/json'}})\n .then(function (resp) {\n $mdToast.show(\n $mdToast.simple()\n .textContent(\"Opgaver valgt\")\n .position('top right')\n .hideDelay(3000)\n );\n $state.go('teacher.setupgroups');\n });\n \t\t}\n }\n]);","app.controller('teacherSetupGroupsCtrl', [\n '$scope', '$rootScope', '$http', '$state', 'mdContentService', function ($scope, $rootScope, $http, $state, mdContentService) {\n \tvar vm = this;\n\n \tvm.loaded = false;\n \tvm.games = [];\n\n \t$http.get('/api/gameday/games').then(function(response) {\n \t\tvm.games = response.data.games;\n \t\tvm.loaded = true;\n\n mdContentService.triggerSyntheticScrollEvent();\n \t});\n\n \tvm.add = function() {\n \t\t$http.post('/api/gameday/addgame').then(function(response) {\n \t\t\t$state.reload();\n \t\t})\n \t}\n\n\t\tvm.edit = function(id) {\n\t\t\t$state.go('teacher.groupdetails', { id: id });\t\n\t\t}\n\n \tvm.delete = function(id) {\n \t\t$http.delete('/api/gameday/game/' + id).then(function(response) {\n \t\t\t$state.reload();\n \t\t});\n \t}\n\n vm.next = function() {\n $state.go('teacher.groups');\n }\n }\n]);","app.controller('teacherSignupCtrl', [\n '$state', function ($state) {\n \tvar vm = this;\n\n \tvm.next = function() {\n \t\t$state.go('teacher.setupexercises');\n \t}\n }\n]);","app.controller('teacherAppIndexCtrl', [\r\n '$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {\r\n }\r\n]);","app.controller('testTicketIndexCtrl', [\n '$scope', '$rootScope', '$http', 'mdContentService', function ($scope, $rootScope, $http, mdContentService) {\n \tvar vm = this;\n\n vm.ymdZeroPadNumber = function(num) {\n var str = \"\" + num;\n if (str.length == 1) {\n return \"0\" + str;\n }\n return str;\n }\n\n vm.getYMD = function() {\n var date = new Date();\n var y = date.getYear() + 1900;\n var m = date.getMonth() + 1;\n var d = date.getDate();\n return \"\" + y + vm.ymdZeroPadNumber(m) + vm.ymdZeroPadNumber(d);\n }\n\n vm.genTeacherName = function(minLen, maxLen) {\n var Cstart = 'A'.charCodeAt();\n var Cend = 'Z'.charCodeAt();\n var Clen = Cend - Cstart;\n\n var Lstart = 'a'.charCodeAt();\n var Lend = 'z'.charCodeAt();\n var Llen = Lend - Lstart;\n\n var len = Math.floor(Math.random() * (maxLen - minLen)) + minLen;\n\n var name = \"\";\n for (var i = 0; i < len; i++) {\n if (i == 0) {\n var c = Cstart + Math.floor(Math.random() * Clen);\n name += String.fromCharCode(c);\n } else {\n var c = Lstart + Math.floor(Math.random() * Llen);\n name += String.fromCharCode(c);\n }\n }\n return name;\n }\n\n vm.genTeacherFullName = function() {\n var firstName = vm.genTeacherName(3, 15);\n var lastName = vm.genTeacherName(3, 10);\n return firstName + \" \" + lastName;\n }\n\n vm.genRandom = function(minLen, maxLen) {\n var Cstart = 'A'.charCodeAt();\n var Cend = 'Z'.charCodeAt();\n var Clen = Cend - Cstart;\n\n var Lstart = 'a'.charCodeAt();\n var Lend = 'z'.charCodeAt();\n var Llen = Lend - Lstart;\n\n var Nstart = '0'.charCodeAt();\n var Nend = '9'.charCodeAt();\n var Nlen = Nend - Nstart;\n\n var random = \"\";\n var len = Math.floor(Math.random() * (maxLen - minLen)) + minLen;\n for (var i = 0; i < len; i++) {\n var kind = Math.floor(Math.random() * 3);\n if (kind == 0) {\n var c = Cstart + Math.floor(Math.random() * Clen);\n random += String.fromCharCode(c);\n } else if (kind == 1) {\n var c = Lstart + Math.floor(Math.random() * Llen);\n random += String.fromCharCode(c);\n } else if (kind == 2) {\n var c = Nstart + Math.floor(Math.random() * Nlen);\n random += String.fromCharCode(c);\n }\n }\n return random;\n }\n\n vm.genUrl = function(key, schoolCategory) {\n var origin = window.location.origin;\n var ymd = vm.getYMD();\n var visualId = vm.genRandom(3, 25);\n var orderNo = vm.genRandom(3, 25);\n var teacherName = vm.genTeacherFullName();\n\n return origin +\n \"/login?key=\" + encodeURIComponent(key) + \n \"&startdayymd=\" + encodeURIComponent(ymd) +\n \"&visualid=\" + encodeURIComponent(visualId) +\n \"&orderno=\" + encodeURIComponent(orderNo) +\n \"&teacherName=\" + encodeURIComponent(teacherName) +\n \"&schoolcategory=\" + encodeURIComponent(schoolCategory);\n }\n\n vm.regenWithKey = function(key) {\n vm.testTicket46 = vm.genUrl(key, \"1\");\n vm.testTicket79 = vm.genUrl(key, \"2\");\n }\n\n vm.regen = function() {\n vm.regenWithKey(vm.key);\n }\n\n $http.get('/api/gamedayvalidationkey').then(function(response) {\n vm.loaded = true;\n vm.key = response.data.key;\n \n vm.regen();\n\n mdContentService.triggerSyntheticScrollEvent();\n });\n }\n]);","app.controller('previewExerciseBeginCtrl', [\r\n '$scope', '$interval', '$state', function ($scope, $interval, $state) {\r\n var vm = this;\r\n\r\n vm.setupExercise = function(exercise, questionIndex, fullFlow) {\r\n // Copied from gameService.js.\r\n function indexify(collection, forEachFunc) {\r\n for (var i = 0; i < collection.length; i++) {\r\n var item = collection[i];\r\n item.index = i;\r\n if (forEachFunc) {\r\n forEachFunc(item);\r\n }\r\n }\r\n }\r\n\r\n indexify(exercise.evaluationQuestions, function(question) {\r\n indexify(question.answers);\r\n });\r\n\r\n vm.exercise = exercise;\r\n vm.questionIndex = questionIndex;\r\n vm.question = exercise.evaluationQuestions[questionIndex];\r\n vm.fullFlow = fullFlow;\r\n }\r\n\r\n vm.initialize = function() {\r\n if (!vm.fullFlow) {\r\n vm.progressIndex = 0;\r\n vm.progressCount = 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n } else {\r\n vm.progressIndex = 1 + vm.questionIndex;\r\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n }\r\n }\r\n\r\n var exerciseJson = window.localStorage.getItem(\"simulatorExercise\");\r\n var exercise = JSON.parse(exerciseJson);\r\n var questionIndexStr = window.localStorage.getItem(\"simulatorExerciseEvalQuestionIndex\");\r\n var questionIndex = parseInt(questionIndexStr, 10);\r\n var fullFlow = window.localStorage.getItem(\"simulatorFullFlow\") == \"true\";\r\n vm.setupExercise(exercise, questionIndex, fullFlow);\r\n vm.initialize();\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n $state.go('preview.exerciseperform');\r\n }\r\n }\r\n]);\r\n","app.controller('previewExerciseDoneCtrl', [\r\n '$scope', '$interval', '$state', '$stateParams', '$timeout', function ($scope, $interval, $state, $stateParams, $timeout) {\r\n var vm = this;\r\n\r\n var exerciseJson = window.localStorage.getItem(\"simulatorExercise\");\r\n var exercise = JSON.parse(exerciseJson);\r\n vm.exercise = exercise;\r\n\r\n var parent = angular.element(\"#evalbeginarrow\")[0];\r\n vm.arrow = new TivoliArrow(parent);\r\n vm.arrow.start();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.arrow.stop();\r\n vm.arrow = null;\r\n })\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n window.parent.postMessage(\"simulator.close\");\r\n }\r\n\r\n // -- CONFETTI --\r\n\r\n vm.confetti = new TG.Confetti({\r\n viewport: document.getElementsByClassName(\"confetticanvas\")[0],\r\n texture: '/img/confetti-sprite.png',\r\n particleCount: 759,\r\n particleScale: 1.0\r\n });\r\n\r\n vm.fireConfettiLoop = function() {\r\n $timeout(function() {\r\n vm.confetti.fireCenterCannon();\r\n }, 750);\r\n }\r\n\r\n vm.initiateConfettiLoop = function() {\r\n vm.fireConfettiLoop();\r\n }\r\n\r\n vm.initiateConfettiLoop();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.confetti.dispose();\r\n });\r\n }\r\n]);\r\n","app.controller('previewExerciseEvalBeginCtrl', [\r\n '$scope', '$interval', '$state', '$stateParams', function ($scope, $interval, $state, $stateParams) {\r\n var vm = this;\r\n\r\n vm.setupExercise = function(exercise, questionIndex, fullFlow) {\r\n // Copied from gameService.js.\r\n function indexify(collection, forEachFunc) {\r\n for (var i = 0; i < collection.length; i++) {\r\n var item = collection[i];\r\n item.index = i;\r\n if (forEachFunc) {\r\n forEachFunc(item);\r\n }\r\n }\r\n }\r\n\r\n indexify(exercise.evaluationQuestions, function(question) {\r\n indexify(question.answers);\r\n });\r\n\r\n vm.exercise = exercise;\r\n vm.questionIndex = questionIndex;\r\n vm.question = exercise.evaluationQuestions[questionIndex];\r\n vm.fullFlow = fullFlow;\r\n }\r\n\r\n vm.initialize = function() {\r\n if (!vm.fullFlow) {\r\n vm.progressIndex = 0;\r\n vm.progressCount = 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n } else {\r\n vm.progressIndex = 1 + vm.exercise.questions.length;\r\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n }\r\n\r\n vm.points = 40;\r\n\r\n vm.activeAnswers = [ true, true, true, true ];\r\n vm.done = false;\r\n\r\n vm.popupShown = false;\r\n vm.answer = null;\r\n vm.answerIndex = 0;\r\n\r\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\r\n\r\n vm.firstRun = true;\r\n vm.helpShown = vm.helpAvailable;\r\n vm.showMathLoader = vm.helpAvailable;\r\n }\r\n\r\n var exerciseJson = window.localStorage.getItem(\"simulatorExercise\");\r\n var exercise = JSON.parse(exerciseJson);\r\n var questionIndexStr = window.localStorage.getItem(\"simulatorExerciseEvalQuestionIndex\");\r\n var questionIndex = parseInt(questionIndexStr, 10);\r\n var fullFlow = window.localStorage.getItem(\"simulatorFullFlow\") == \"true\";\r\n vm.setupExercise(exercise, questionIndex, fullFlow);\r\n vm.initialize();\r\n\r\n var parent = angular.element(\"#evalbeginarrow\")[0];\r\n vm.arrow = new TivoliArrow(parent);\r\n vm.arrow.start();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.arrow.stop();\r\n vm.arrow = null;\r\n })\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n \t$state.go('preview.exerciseevalperform');\r\n }\r\n }\r\n\r\n]);\r\n","app.controller('previewExerciseEvalPerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', '$state', '$stateParams', '$log', function ($scope, $rootScope, $http, $mdDialog, $state, $stateParams, $log) {\n var vm = this;\n\n vm.setupExercise = function(exercise, questionIndex, fullFlow) {\n // Copied from gameService.js.\n function indexify(collection, forEachFunc) {\n for (var i = 0; i < collection.length; i++) {\n var item = collection[i];\n item.index = i;\n if (forEachFunc) {\n forEachFunc(item);\n }\n }\n }\n\n indexify(exercise.evaluationQuestions, function(question) {\n indexify(question.answers);\n });\n\n vm.exercise = exercise;\n vm.questionIndex = questionIndex;\n vm.question = exercise.evaluationQuestions[questionIndex];\n vm.fullFlow = fullFlow;\n }\n\n vm.initialize = function() {\n if (!vm.fullFlow) {\n vm.progressIndex = 0;\n vm.progressCount = 1;\n vm.progressArray = new Array(vm.progressCount);\n } else {\n vm.progressIndex = 1 + vm.exercise.questions.length + 1 + vm.questionIndex;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n }\n\n vm.points = 40;\n\n vm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.firstRun = true;\n vm.helpShown = vm.helpAvailable;\n vm.showMathLoader = vm.helpAvailable;\n }\n\n var exerciseJson = window.localStorage.getItem(\"simulatorExercise\");\n var exercise = JSON.parse(exerciseJson);\n var questionIndexStr = window.localStorage.getItem(\"simulatorExerciseEvalQuestionIndex\");\n var questionIndex = parseInt(questionIndexStr, 10);\n var fullFlow = window.localStorage.getItem(\"simulatorFullFlow\") == \"true\";\n vm.setupExercise(exercise, questionIndex, fullFlow);\n vm.initialize();\n\n var parent = angular.element(\"#eearrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n vm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.performAnswer = function(idx) {\n var answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n if (vm.question.answers[idx].correct) {\n\n var numTries = vm.activeAnswers.reduce(function(acc, val) {\n if (val == false) {\n acc += 1;\n }\n return acc;\n }, 0);\n\n vm.activeAnswers = [ false, false, false, false ];\n vm.next();\n return;\n }\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n vm.popupShown = true;\n }\n\n vm.hidePopup = function() {\n var idx = vm.answerIndex;\n\n vm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n }\n\n vm.next = function() {\n if (!fullFlow) {\n return;\n }\n\n // Go next evaluation question?\n if (vm.questionIndex < vm.exercise.evaluationQuestions.length - 1) {\n var questionIndex = vm.questionIndex + 1;\n window.localStorage.setItem(\"simulatorExerciseEvalQuestionIndex\", \"\" + questionIndex);\n $state.go('preview.exerciseevalperform', {}, {reload: \"preview.exerciseevalperform\"});\n // Go done?\n } else if (vm.questionIndex === vm.exercise.evaluationQuestions.length - 1) {\n $state.go('preview.exercisedone');\n }\n }\n }\n]);","app.controller('previewExercisePerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', '$state', '$stateParams', '$timeout', '$log', function ($scope, $rootScope, $http, $mdDialog, $state, $stateParams, $timeout, $log) {\n var vm = this;\n\n console.log(\"previewExercisePerformCtrl...\");\n\n $scope.$on('$viewContentLoaded', function () {\n $timeout(function() {\n if (window.MathJax != null) {\n $log.debug(\"previewExercisePerformCtrl: viewContentLoaded typeset\");\n window.MathJax.Hub.Queue(\n [\"Typeset\",MathJax.Hub],\n [function() { $scope.$apply(function() {\n vm.showMathLoader = false;\n }); }]\n );\n } else {\n $log.debug(\"previewExercisePerformCtrl: no window.MathJax, skipping typeset\");\n }\n }, 1);\n });\n\n vm.setupExercise = function(exercise, questionIndex, fullFlow) {\n // Copied from gameService.js.\n function indexify(collection, forEachFunc) {\n for (var i = 0; i < collection.length; i++) {\n var item = collection[i];\n item.index = i;\n if (forEachFunc) {\n forEachFunc(item);\n }\n }\n }\n\n indexify(exercise.questions, function(question) {\n indexify(question.answers);\n });\n\n vm.exercise = exercise;\n vm.questionIndex = questionIndex;\n vm.question = exercise.questions[questionIndex];\n vm.fullFlow = fullFlow;\n }\n\n vm.initialize = function() {\n if (!vm.fullFlow) {\n vm.progressIndex = 0;\n vm.progressCount = 1;\n vm.progressArray = new Array(vm.progressCount);\n } else {\n vm.progressIndex = 1 + vm.questionIndex;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n }\n\n vm.points = 40;\n\n vm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.firstRun = true;\n vm.helpShown = vm.helpAvailable;\n vm.showMathLoader = vm.helpAvailable;\n }\n\n var exerciseJson = window.localStorage.getItem(\"simulatorExercise\");\n var exercise = JSON.parse(exerciseJson);\n var questionIndexStr = window.localStorage.getItem(\"simulatorExerciseQuestionIndex\");\n var questionIndex = parseInt(questionIndexStr, 10);\n var fullFlow = window.localStorage.getItem(\"simulatorFullFlow\") == \"true\";\n vm.setupExercise(exercise, questionIndex, fullFlow);\n vm.initialize();\n\n var parent = angular.element(\"#performarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n \tvm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.showMathLoader = vm.helpAvailable;\n\n \tvm.performAnswer = function(idx) {\n \t\tvar answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n if (vm.question.answers[idx].correct) {\n var numTries = vm.activeAnswers.reduce(function(acc, val) {\n if (val == false) {\n acc += 1;\n }\n return acc;\n }, 0);\n\n vm.activeAnswers = [ false, false, false, false ];\n vm.done = true;\n return;\n\t\t\t}\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n \tvm.popupShown = true;\n \t}\n\n \tvm.hidePopup = function() {\n \t\tvar idx = vm.answerIndex;\n\n\t\t\tvm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n \t}\n\n vm.firstRun = true;\n vm.helpShown = vm.helpAvailable;\n vm.showHelp = function() {\n \tvm.helpShown = true;\n vm.firstRun = false;\n }\n\n vm.hideHelp = function() {\n \tvm.helpShown = false;\n vm.firstRun = false\n\n $timeout(function() {\n var elements = angular.element(\".helpinner\");\n if (elements.length > 0) {\n elements[0].scrollTo(0, 0);\n }\n }, 0); // XXX: must match the transition time for .helppopover.\n }\n\n vm.next = function() {\n if (!vm.done) {\n return;\n }\n\n console.log(\"previewExercisePerformCtrl... NEXT???\");\n\n \t\t// Go to question?\n \t\tif (vm.questionIndex < vm.exercise.questions.length - 1) {\n \t\t\tvar questionIndex = vm.questionIndex + 1;\n \t\t\twindow.localStorage.setItem(\"simulatorExerciseQuestionIndex\", \"\" + questionIndex);\n\n $state.go('preview.exerciseperform', {}, {reload: \"preview.exerciseperform\"});\n\t\t\t// Go to evaluation interstitial?\n \t\t} else if (vm.questionIndex === vm.exercise.questions.length - 1) {\n \t\t\t$state.go('preview.exerciseevalbegin', {});\n \t\t}\n \t}\n }\n]);","app.controller('headerCtrl', [\r\n 'navService', 'appService', 'messageService', '$state', function (navService, appService, messageService, $state) {\r\n var vm = this;\r\n\r\n \tvm.appService = appService;\r\n \tvm.navService = navService;\r\n vm.messageService = messageService;\r\n\r\n \tvm.openNav = function() {\r\n \t vm.navService.open();\r\n \t}\r\n\r\n \tvm.closeNav = function() {\r\n \t vm.navService.close();\r\n \t}\r\n\r\n \tvm.isLogin = function() {\r\n \t\treturn vm.isCurrentPage('student.login');\r\n \t}\r\n\r\n vm.isFreeGame = function() {\r\n return vm.isCurrentPage('student.freegameperform');\r\n }\r\n\r\n vm.isPreview = function() {\r\n return vm.isCurrentPage('preview');\r\n }\r\n\r\n vm.isCurrentPage = function (state) {\r\n return $state.current.name.substring(0, state.length) === state;\r\n }\r\n\r\n vm.isStateOrAncestor = function (state) {\r\n \treturn $state.current.name.indexOf(state) == 0;\r\n }\r\n\r\n \tvm.goHome = function() {\r\n if (vm.isPreview()) {\r\n return;\r\n }\r\n\r\n \t\tif (vm.isCurrentPage('student')) {\r\n \t\t\t$state.go('student');\r\n } else if (vm.isCurrentPage('teacherapp')) {\r\n $state.go('teacherapp');\r\n \t\t} else {\r\n \t\t\t$state.go('home');\r\n \t\t}\r\n \t}\r\n\r\n vm.goLogin = function() {\r\n $state.go('student.login');\r\n }\r\n\r\n vm.goTeacherMessages = function() {\r\n $state.go('teacherapp.messages');\r\n }\r\n\r\n vm.goStudentMessages = function() {\r\n $state.go('student.messages');\r\n }\r\n }\r\n]);\r\n","app.controller('navCtrl', [\r\n '$scope', '$state', 'appService', 'authService', 'gameService', '$window', '$transitions', 'logoutService', function ($scope, $state, appService, authService, gameService, $window, $transitions, logoutService) {\r\n \t$scope.appService = appService;\r\n $scope.authService = authService;\r\n $scope.gameService = gameService;\r\n $scope.logoutService = logoutService;\r\n\r\n \t$scope.isiOS = appService.isiOS();\r\n \t$scope.isiPhoneX = appService.isiPhoneX();\r\n \t$scope.isAndroid = appService.isAndroid();\r\n\r\n $scope.isCurrentPage = function (state) {\r\n return $state.current.name.substring(0, state.length) === state;\r\n }\r\n\r\n $scope.isActualPage = function (state) {\r\n return state === $state.current.name;\r\n }\r\n\r\n\t\t$transitions.onSuccess({}, function(transition) {\r\n\t\t\tvar newState = transition.to().name;\r\n\r\n\t\t\tif (newState === \"student\" || newState.indexOf(\"student.\") === 0) {\r\n\t\t\t\t$scope.items = $scope.studentItemsFiltered();\r\n\t\t\t} else if (newState === \"teacher\" || newState.indexOf(\"teacher.\") === 0) {\r\n\t\t\t\t$scope.items = $scope.teacherItems;\r\n } else if (newState === \"teacherapp\" || newState.indexOf(\"teacherapp.\") === 0) {\r\n $scope.items = $scope.teacherAppItems;\r\n } else {\r\n\t\t\t\t$scope.items = $scope.tivoliItems;\r\n\t\t\t}\r\n\t\t});\r\n\r\n \t$scope.teacherItems = [\r\n {\r\n state: \"teacher.signup\",\r\n displayName: \"Kom i gang\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacher.setupexercises\",\r\n displayName: \"Vælg opgaver\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacher.setupgroups\",\r\n displayName: \"Opret grupper\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacher.groups\",\r\n displayName: \"Gruppeoversigt\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacher.evaluation\",\r\n displayName: \"Evaluering\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacher.info\",\r\n displayName: \"Vigtig info\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n }\r\n \t];\r\n\r\n $scope.teacherAppItems = [\r\n {\r\n state: \"teacherapp.welcome\",\r\n displayName: \"Velkommen\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacherapp.groupstatus\",\r\n displayName: \"Status på grupper\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacherapp.exercises\",\r\n displayName: \"Opgaveoversigt\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n },\r\n {\r\n state: \"teacherapp.groupmap\",\r\n displayName: \"Kort\",\r\n iconClass: \"\",\r\n bigIcon: false\r\n }\r\n ];\r\n\r\n \t$scope.tivoliItems = [\r\n \t\t{\r\n \t\t\tstate: \"home\",\r\n \t\t\tdisplayName: \"Hjem\",\r\n \t\t\ticonUrl: \"/img/IconOpgaver.png\"\r\n \t\t},\r\n \t\t{\r\n \t\t\tstate: \"exercises\",\r\n \t\t\tdisplayName: \"Opaver\",\r\n \t\t\ticonUrl: \"/img/IconOpgaver.png\"\r\n \t\t},\r\n {\r\n state: \"config\",\r\n displayName: \"Config\",\r\n iconUrl: \"/img/IconOpgaver.png\"\r\n },\r\n {\r\n state: \"testticket\",\r\n displayName: \"Test-biletter\",\r\n iconUrl: \"/img/IconOpgaver.png\"\r\n },\r\n {\r\n state: \"rides\",\r\n displayName: \"Forlystelser\",\r\n iconUrl: \"/img/IconOpgaver.png\"\r\n },\r\n {\r\n state: \"freegame\",\r\n displayName: \"Øvelsesopgave\",\r\n iconUrl: \"/IconOpgaver.png\"\r\n },\r\n {\r\n state: \"stats\",\r\n displayName: \"Statistik\",\r\n iconUrl: \"/img/IconOpgaver.png\"\r\n },\r\n \t\t{\r\n \t\t\tstate: \"profile\",\r\n \t\t\tdisplayName: \"Profil\",\r\n \t\t\ticonUrl: \"/img/IconOpgaver.png\"\r\n \t\t},\r\n \t];\r\n\r\n \t$scope.items = [];\r\n\r\n $scope.studentItemsFiltered = function() {\r\n var items = [];\r\n if (gameService.isWelcomeNotFinished()) {\r\n items.push({\r\n state: \"student.welcome\",\r\n displayName: \"Velkommen\",\r\n iconClass: \"icon-velkommen\",\r\n bigIcon: true\r\n });\r\n } else {\r\n if (!gameService.isGameDone()) {\r\n items.push({\r\n state: 'student.exercises',\r\n displayName: 'Opgaver',\r\n iconClass: 'icon-opgaver',\r\n bigIcon: false\r\n });\r\n }\r\n if (gameService.isGameDone()) {\r\n items.push({\r\n state: \"student.trophy\",\r\n displayName: \"Point\",\r\n iconClass: \"icon-point\",\r\n bigIcon: false\r\n });\r\n }\r\n }\r\n return items;\r\n }\r\n\r\n $scope.showCookieDialog = function() {\r\n var cookieStateIsSupported = (window.tuAndroid != null && window.tuAndroid.setCookieState != null) || (window.webkit != null && window.webkit.messageHandlers != null && window.webkit.messageHandlers[\"setCookieState\"] != null);\r\n if (!cookieStateIsSupported) {\r\n return;\r\n }\r\n var showRemoveButton = $window.localStorage.getItem('cookieState') == 'all';\r\n if (showRemoveButton) {\r\n appService.showCookieRemoveDialog();\r\n } else {\r\n appService.showCookieDialog();\r\n }\r\n }\r\n\t}\r\n]);","app.controller('shellCtrl', [\r\n '$scope', 'navService', function ($scope, navService) {\r\n \t$scope.navService = navService;\r\n\t}\r\n]);","app.controller('studentCarouselCtrl', [\r\n '$scope', function ($scope) {\r\n\r\n \t$scope.touchStartPoint = { x: 0, y: 0 };\r\n \t$scope.touchStartContentOffset = { x: 0, y: 0};\r\n \t$scope.contentOffset = { x: 0, y: 0 };\r\n\r\n $scope.disablePanning = false;\r\n\r\n \t$scope.startTime = 0.0;\r\n\r\n $scope.enabledPages = [ true, true, true, false, false ];\r\n\r\n function isContainedInMdContent(elem) {\r\n var child = elem;\r\n do {\r\n var tagName = child.parentElement.tagName.toLowerCase();\r\n if (tagName === \"md-content\") {\r\n return true;\r\n }\r\n child = child.parentElement;\r\n } while (child && child.parentElement);\r\n return false;\r\n }\r\n\r\n \t$scope.onTouchStart = function(evt) {\r\n \t\t$scope.numPages = $scope.elem.children.length;\r\n\r\n \t\t$scope.startTime = performance.now();\r\n\r\n \t\t// Register the starting point\r\n \t\tvar touch = evt.touches[0];\r\n console.dir(touch);\r\n \t\t$scope.touchStartPoint = { x: touch.screenX, y: touch.screenY };\r\n \t\t$scope.touchStartContentOffset = JSON.parse(JSON.stringify($scope.contentOffset));\r\n\r\n // If the start touch is inside an md-content, discard it.\r\n $scope.disablePanning = isContainedInMdContent(touch.target);\r\n console.log(\"studentCarouselCtrl#onTouchStart: disablePanning = \" + $scope.disablePanning);\r\n \t}\r\n\r\n \t$scope.onTouchEnd = function(evt) {\r\n \t\tif ($scope.disablePanning) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n if ($scope.lastX !== undefined) {\r\n $scope.snap();\r\n $scope.lastX = undefined;\r\n }\r\n \t}\r\n\r\n \t$scope.onTouchCancel = function(evt) {\r\n \t\tif ($scope.disablePanning) {\r\n \t\t\treturn;\r\n }\r\n\r\n if ($scope.lastX !== undefined) {\r\n \t\t $scope.snap();\r\n $scope.lastX = undefined;\r\n }\r\n \t}\r\n\r\n \t$scope.lastX = undefined;\r\n \t$scope.lastT = undefined;\r\n \t$scope.velocity = undefined;\r\n \t$scope.animationStartT = undefined;\r\n \t$scope.animationDuration = 200;\r\n \t$scope.animationLastT = undefined;\r\n \t$scope.animateFromX = undefined;\r\n \t$scope.animateToX = undefined;\r\n $scope.moveDelta = undefined;\r\n\r\n \t$scope.onTouchMove = function(evt) {\r\n \t\tif ($scope.disablePanning) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n var vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\r\n\r\n \t\tvar touch = evt.touches[0];\r\n \t\tvar point = { x: touch.screenX, y: touch.screenY };\r\n \t\tvar now = performance.now();\r\n\r\n \t\tvar dx = point.x - $scope.touchStartPoint.x;\r\n \t\tvar dy = point.y - $scope.touchStartPoint.y;\r\n \t\tvar dpoint = { x: dx, y: dy };\r\n\r\n var newOffsetX = $scope.touchStartContentOffset.x + dpoint.x;\r\n var maxOffsetX = (-($scope.numPages - 1) * vw);\r\n var page = Math.round(Math.abs($scope.contentOffset.x / vw));\r\n\r\n if (newOffsetX > 0 || newOffsetX < maxOffsetX) {\r\n return;\r\n }\r\n\r\n if (!$scope.enabledPages[page] && dpoint.x < 0) {\r\n return;\r\n }\r\n\r\n if (Math.abs(dpoint.x) <= 5 && Math.abs(dpoint.y) <= 5) {\r\n return;\r\n }\r\n\r\n $scope.contentOffset = { x: newOffsetX, y : 0}\r\n \t$scope.elem.style.transform = \"translateX(\" + $scope.contentOffset.x + \"px)\";\r\n\r\n \t\tif ($scope.lastX !== undefined && $scope.lastT !== undefined) {\r\n \t\t\tvar dx = point.x - $scope.lastX;\r\n \t\t\tvar dt = now - $scope.lastT;\r\n \t\t\tvar velocity = dx / dt;\r\n \t\t\t$scope.velocity = velocity;\r\n \t\t}\r\n $scope.moveDelta = dpoint;\r\n \t\t$scope.lastX = point.x;\r\n \t\t$scope.lastT = performance.now();\r\n \t}\r\n\r\n \t$scope.snap = function() {\r\n \t\tvar vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\r\n\t\t\tvar vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\r\n\r\n\t\t\tvar ofs = JSON.parse(JSON.stringify($scope.contentOffset));\r\n\t\t\tvar a = ofs.x / vw;\r\n\t\t\tif (a > 0) { // Stop scrolling to the left.\r\n\t\t\t\ta = 0;\r\n\t\t\t}\r\n\r\n\t\t\tvar page = Math.round(Math.abs(a));\r\n\t\t\tif (page > $scope.numPages - 1) {\r\n\t\t\t\tpage = $scope.numPages - 1;\r\n\t\t\t}\r\n\r\n var prevPage = parseInt(page);\r\n\r\n if (Math.abs($scope.moveDelta.x) <= 65) {\r\n // Stay on the current page if we haven't moved much...\r\n console.log(\"Staying on the same page...\");\r\n\t\t\t} else if ($scope.velocity > 0) { // go back\r\n\t\t\t\tvar ceilPage = Math.ceil(Math.abs(a));\r\n\t\t\t\tif (page == ceilPage && Math.abs($scope.velocity) > 0.2) {\r\n\t\t\t\t\tpage -= 1;\r\n\t\t\t\t}\r\n\t\t\t} else if ($scope.velocity < 0) { // go forward\r\n\t\t\t\tvar floorPage = Math.floor(Math.abs(a));\r\n\t\t\t\tif (page == floorPage && Math.abs($scope.velocity) > 0.2) {\r\n\t\t\t\t\tpage += 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// ... again\r\n\t\t\tif (page > $scope.numPages - 1) {\r\n\t\t\t\tpage = $scope.numPages - 1;\r\n\t\t\t}\r\n\t\t\tif (page < 0) {\r\n\t\t\t\tpage = 0;\r\n\t\t\t}\r\n\r\n \t\t$scope.animateFromX = $scope.contentOffset.x;\r\n \t\t$scope.animateToX = (-page * vw);\r\n\r\n \t\t$scope.animateSnap();\r\n\r\n $scope.$broadcast('carouselPageChange', { prevPage: prevPage, newPage: page });\r\n \t}\r\n\r\n \t$scope.animateSnap = function() {\r\n \t\t$scope.animationStartT = performance.now();\r\n \t\t$scope.requestAnimationFrame();\r\n \t}\r\n\r\n \t$scope.lastRequestedAnimationFrameId = undefined;\r\n \t$scope.requestAnimationFrame = function() {\r\n \t\tif ($scope.lastRequestedAnimationFrameId === undefined) {\r\n \t\t\t$scope.lastRequestedAnimationFrameId = window.requestAnimationFrame($scope.onAnimationFrame.bind(this));\r\n \t\t}\r\n \t}\r\n\r\n \t$scope.onAnimationFrame = function() {\r\n \t\tvar ok = $scope.onAnimationUpdate();\r\n\r\n \t\t$scope.lastRequestedAnimationFrameId = undefined;\r\n \t\t\r\n \t\tif (ok) {\r\n\t \t\t$scope.requestAnimationFrame();\r\n\t \t}\r\n \t}\r\n\r\n \t$scope.onAnimationUpdate = function() {\r\n \t\tvar now = performance.now();\r\n \t\tvar\telapsed = now - $scope.animationStartT;\r\n \t\tvar dt = 0;\r\n \t\tif ($scope.animationLastT !== undefined) {\r\n \t\t\tdt = now - $scope.animationLastT;\r\n \t\t}\r\n \r\n\t\t\tfunction EaseOutSine(t, b, c, d) {\r\n \t\treturn c * Math.sin(t / d * (Math.PI / 2)) + b;\r\n\t\t\t}\r\n\r\n\t\t\tvar ok = true\r\n\t\t\tvar t = (now - $scope.animationStartT) / $scope.animationDuration;\r\n\t\t\tvar v = EaseOutSine(t, 0, 1, 1);\r\n\t\t\tif (now >= ($scope.animationStartT + $scope.animationDuration)) {\r\n\t\t\t\tv = 1.0;\r\n\t\t\t\tok = false;\r\n\t\t\t}\r\n \r\n\t\t\tvar dx = ($scope.animateToX - $scope.animateFromX) * v + $scope.animateFromX;\r\n\t\t\t$scope.contentOffset = { x: dx, y: 0 };\r\n \t\t$scope.elem.style.transform = \"translateX(\" + $scope.contentOffset.x + \"px)\";\r\n\r\n \t\treturn ok;\r\n \t}\r\n\r\n \t$scope.elem = angular.element(\".appcarousel\")[0];\r\n\r\n\t\t$scope.elem.addEventListener(\"touchstart\", $scope.onTouchStart.bind(this));\r\n\t\t$scope.elem.addEventListener(\"touchend\", $scope.onTouchEnd.bind(this));\r\n\t\t$scope.elem.addEventListener(\"touchcancel\", $scope.onTouchCancel.bind(this));\r\n\t\t$scope.elem.addEventListener(\"touchmove\", $scope.onTouchMove.bind(this));\r\n\r\n\t\t$scope.numPages = $scope.elem.children.length;\r\n\r\n $scope.pageNav = function(offset) {\r\n var vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\r\n var vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\r\n\r\n var ofs = JSON.parse(JSON.stringify($scope.contentOffset));\r\n var a = ofs.x / vw;\r\n if (a > 0) { // Stop scrolling to the left.\r\n a = 0;\r\n }\r\n\r\n var page = Math.round(Math.abs(a));\r\n if (page > $scope.numPages - 1) {\r\n page = $scope.numPages - 1;\r\n }\r\n\r\n $scope.animateFromX = $scope.contentOffset.x;\r\n $scope.animateToX = (-(page + offset) * vw);\r\n\r\n $scope.animateSnap();\r\n\r\n $scope.$broadcast('carouselPageChange', { prevPage: page, newPage: (page+offset) });\r\n }\r\n\r\n $scope.prevPage = function() {\r\n $scope.pageNav(-1);\r\n }\r\n\r\n $scope.nextPage = function() {\r\n $scope.pageNav(+1);\r\n }\r\n\r\n $scope.indexOfPage = function(pageScope) {\r\n var n = $scope.elem.children.length;\r\n console.log(n);\r\n for (var i = 0; i < n; i++) {\r\n var ce = $scope.elem.children[i];\r\n var scope = ce.scope();\r\n console.log(scope);\r\n if (scope == pageScope) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n }\r\n]);","app.controller('studentExerciseBeginCtrl', [\r\n '$scope', '$interval', 'gameService', '$state', '$stateParams', 'stopwatchService', function ($scope, $interval, gameService, $state, $stateParams, stopwatchService) {\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n vm.exercise = gameService.exerciseWithIndex($stateParams.id); \r\n\r\n vm.progressIndex = 0;\r\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length;\r\n vm.progressArray = new Array(vm.progressCount);\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n stopwatchService.start(\"exercise\", vm.exercise.id);\r\n $state.go('student.exerciseperform', {id: $stateParams.id, question: 0});\r\n }\r\n }\r\n]);\r\n","app.controller('studentExerciseDoneCtrl', [\r\n '$scope', '$interval', 'gameService', '$state', '$stateParams', '$timeout', 'stopwatchService', 'analyticsService', function ($scope, $interval, gameService, $state, $stateParams, $timeout, stopwatchService, analyticsService) {\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\r\n\r\n vm.progressIndex = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length;\r\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n\r\n stopwatchService.stop(\"exercise\", $stateParams.id);\r\n var stopwatch = stopwatchService.get(\"exercise\", $stateParams.id);\r\n\r\n var parent = angular.element(\"#evalbeginarrow\")[0];\r\n vm.arrow = new TivoliArrow(parent);\r\n vm.arrow.start();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.arrow.stop();\r\n vm.arrow = null;\r\n })\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n $state.go('student.exercises');\r\n }\r\n\r\n // -- CONFETTI --\r\n\r\n vm.confetti = new TG.Confetti({\r\n viewport: document.getElementsByClassName(\"confetticanvas\")[0],\r\n texture: '/img/confetti-sprite.png',\r\n particleCount: 759,\r\n particleScale: 1.0\r\n });\r\n\r\n vm.fireConfettiLoop = function() {\r\n $timeout(function() {\r\n vm.confetti.fireCenterCannon();\r\n }, 750);\r\n }\r\n\r\n vm.initiateConfettiLoop = function() {\r\n vm.fireConfettiLoop();\r\n }\r\n\r\n vm.initiateConfettiLoop();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.confetti.dispose();\r\n });\r\n }\r\n]);\r\n","app.controller('studentExerciseEvalBeginCtrl', [\r\n '$scope', '$interval', 'gameService', '$state', '$stateParams', function ($scope, $interval, gameService, $state, $stateParams) {\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\r\n\r\n vm.progressIndex = 1 + vm.exercise.questions.length;\r\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\r\n vm.progressArray = new Array(vm.progressCount);\r\n\r\n var parent = angular.element(\"#evalbeginarrow\")[0];\r\n vm.arrow = new TivoliArrow(parent);\r\n vm.arrow.start();\r\n\r\n $scope.$on('$destroy', function() {\r\n vm.arrow.stop();\r\n vm.arrow = null;\r\n })\r\n\r\n vm.ebimageStyle = {\r\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\r\n \t\"background-size\": \"cover\"\r\n };\r\n\r\n vm.next = function() {\r\n \t$state.go('student.exerciseevalperform', {id: $stateParams.id, question: 0});\r\n }\r\n }\r\n\r\n]);\r\n","app.controller('studentExerciseEvalPerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', 'gameService', '$state', '$stateParams', '$log', 'stopwatchService', 'analyticsService', function ($scope, $rootScope, $http, $mdDialog, gameService, $state, $stateParams, $log, stopwatchService, analyticsService) {\n var vm = this;\n\n vm.gameService = gameService;\n vm.gameState = gameService.getGameState();\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n vm.question = gameService.lookupEvaluationQuestion(vm.exercise.index, $stateParams.question);\n\n stopwatchService.start(\"exercise_eval_question\", vm.exercise.id, $stateParams.question);\n\n vm.progressIndex = 1 + vm.exercise.questions.length + 1 + $stateParams.question;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n\t vm.progressArray = new Array(vm.progressCount);\n\n // Create object for this exercise question.\n if (vm.gameState.evaluationAnswers == null) {\n vm.gameState.evaluationAnswers = {};\n }\n\n var evaluationQuestionAnswers = vm.gameState.evaluationAnswers[$stateParams.id];\n if (evaluationQuestionAnswers == null) {\n evaluationQuestionAnswers = {};\n }\n\n var evaluationQuestionAnswerArray = evaluationQuestionAnswers[$stateParams.question];\n if (evaluationQuestionAnswerArray == null) {\n evaluationQuestionAnswerArray = [];\n }\n\n \tvm.points = 40;\n\n \tvm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n var parent = angular.element(\"#eearrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n vm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.performAnswer = function(idx) {\n var answerObj = vm.question.answers[idx];\n\n // Add to list of evaluation answers.\n evaluationQuestionAnswerArray.push(idx);\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n analyticsService.event(\"exercise_eval_question_answered\", {\n \"exercise_id\": vm.exercise.id,\n \"exercise_version\": vm.exercise.version,\n \"question_idx\": $stateParams.question,\n \"answer_idx\": idx,\n \"correct\": vm.question.answers[idx].correct\n });\n\n if (vm.question.answers[idx].correct) {\n\n var numTries = vm.activeAnswers.reduce(function(acc, val) {\n if (val == false) {\n acc += 1;\n }\n return acc;\n }, 0);\n\n stopwatchService.stop(\"exercise_eval_question\", vm.exercise.id, $stateParams.question);\n var stopwatch = stopwatchService.get(\"exercise_eval_question\", vm.exercise.id, $stateParams.question);\n analyticsService.event(\"exercise_eval_question_completed\", {\n \"exercise_id\": vm.exercise.id,\n \"exercise_version\": vm.exercise.version,\n \"question_idx\": $stateParams.question,\n \"start_time\": stopwatch.start,\n \"end_time\": stopwatch.stop,\n \"elapsed_time\": stopwatch.elapsed,\n \"num_tries\": numTries\n });\n\n vm.activeAnswers = [ false, false, false, false ];\n vm.next();\n return;\n }\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n vm.popupShown = true;\n }\n\n vm.hidePopup = function() {\n var idx = vm.answerIndex;\n\n vm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n }\n\n vm.next = function() {\n vm.gameState.score += vm.points;\n\n // Update evaluation status.\n evaluationQuestionAnswers[$stateParams.question] = evaluationQuestionAnswerArray;\n vm.gameState.evaluationAnswers[$stateParams.id] = evaluationQuestionAnswers;\n\n // Go next evaluation question?\n if ($stateParams.question < vm.exercise.evaluationQuestions.length - 1) {\n vm.gameState.evaluationQuestionIndex += 1;\n\n gameService.setGameState(vm.gameState).then(function() {\n $state.go('student.exerciseevalperform', { id: $stateParams.id, question: vm.gameState.evaluationQuestionIndex });\n });\n // Go done?\n } else if ($stateParams.question === vm.exercise.evaluationQuestions.length - 1) {\n stopwatchService.stop(\"exercise\", vm.exercise.id);\n var stopwatch = stopwatchService.get(\"exercise\", vm.exercise.id);\n analyticsService.event(\"exercise_completed\", {\n \"exercise_id\": vm.exercise.id,\n \"exercise_version\": vm.exercise.version,\n \"start_time\": stopwatch.start,\n \"end_time\": stopwatch.stop,\n \"elapsed_time\": stopwatch.elapsed, \n });\n\n // Last exercise? Go to trophy.\n if (vm.gameService.exercises.length - 1 === vm.gameState.exerciseIndex) {\n vm.gameState.exerciseIndex += 1;\n vm.gameState.questionIndex = 0;\n vm.gameState.evaluationQuestionIndex = 0;\n gameService.setGameState(vm.gameState).then(function() {\n $state.go('student.trophy');\n });\n // Else, do as normal.\n } else {\n vm.gameState.exerciseIndex += 1;\n vm.gameState.questionIndex = 0;\n vm.gameState.evaluationQuestionIndex = 0;\n \n gameService.setGameState(vm.gameState).then(function() {\n $state.go('student.exercisedone', { id: $stateParams.id });\n });\n }\n }\n }\n }\n]);","app.controller('studentExerciseMapCtrl', [\r\n '$scope', '$interval', 'gameService', '$state', '$stateParams', '$interval', 'locationService', function ($scope, $interval, gameService, $state, $stateParams, $interval, locationService) {\r\n $scope.gameService = gameService;\r\n\r\n $scope.exercise = gameService.exerciseWithIndex($stateParams.id);\r\n\r\n\t\t$scope.curPos = [0.0, 0.0];\r\n $scope.targetPos = $scope.exercise.mapPos;\r\n\t\t$scope.targetOKDistanceKM = gameService.config.targetOKDistanceKM;\r\n $scope.closeEnough = false;\r\n $scope.nonInteractive = false;\r\n\r\n \t$scope.map = new maptalks.Map('maptalksc', {\r\n \tcenter: gameService.config.mapCenter,\r\n \tzoom: 16.64,\r\n \tbearing: 150.0,\r\n \tattribution: false,\r\n\r\n\t //allow map to drag pitching, true by default\r\n \tdragPitch : false,\r\n \t//allow map to drag rotating, true by default\r\n \tdragRotate : true,\r\n \t//enable map to drag pitching and rotating at the same time, false by default\r\n \tdragRotatePitch : false,\r\n\r\n \tbaseLayer: new maptalks.TileLayer('base', {\r\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\r\n \t\tsubdomains: ['a','b','c','d'],\r\n \t\tattribution: ''\r\n \t})\r\n \t});\r\n\r\n\t\tvar center = $scope.map.getCenter();\r\n\t\tvar layer = new maptalks.VectorLayer('vector').addTo($scope.map);\r\n\r\n $scope.rideMarkers = {};\r\n\r\n for (var i = 0; i < $scope.gameService.rides.length; i++) {\r\n var ride = $scope.gameService.rides[i];\r\n\r\n if (ride.enabled) {\r\n var marker = new maptalks.Marker(ride.location, {\r\n 'symbol' : {\r\n 'markerFile' : ride.markerImage,\r\n 'markerWidth' : ride.markerWidth,\r\n 'markerHeight' : ride.markerHeight,\r\n 'markerDx' : 0,\r\n 'markerDy' : 0,\r\n 'markerOpacity': 1\r\n }\r\n });\r\n $scope.rideMarkers[ride.key] = marker;\r\n marker.addTo(layer);\r\n }\r\n }\r\n\r\n // Add the go-to pos\r\n \t$scope.targetMarker = new maptalks.Marker(\r\n \t$scope.targetPos,\r\n \t{\r\n\t \t'symbol' : {\r\n\t \t'markerFile' : window.location.origin + '/img/map/MapPin.svg',\r\n\t \t'markerWidth' : 2*22,\r\n\t \t'markerHeight' : 2*35.5,\r\n\t \t'markerDx' : 0,\r\n\t \t'markerDy' : 0,\r\n\t \t'markerOpacity': 1\r\n\t \t}\r\n\t \t}\r\n \t);\r\n \t$scope.targetMarker.addTo(layer);\r\n\r\n // Add the You marker.\r\n $scope.youMarker = new maptalks.Marker($scope.curPos, {\r\n \t'symbol' : {\r\n \t'markerFile' : window.location.origin + '/img/map/marker-you.svg',\r\n \t'markerWidth' : 22,\r\n \t'markerHeight' : 22,\r\n \t'markerDx' : 0,\r\n \t'markerDy' : 0,\r\n \t'markerOpacity': 1\r\n \t}\r\n });\r\n $scope.youMarker.addTo(layer);\r\n\r\n $scope._intervalPromise = $interval(function() {\r\n \t$scope.onLocationUpdated();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n \t$interval.cancel($scope._intervalPromise);\r\n })\r\n\r\n $scope.onLocationUpdated = function () {\r\n \tvar pos = locationService.getLocation();\r\n \tif (!pos) {\r\n \t\treturn;\r\n \t}\r\n\r\n \t$scope.curPos = [pos.lng, pos.lat];\r\n\r\n \t// Update closeEnough state.\r\n \tvar distanceKM = locationService.distanceInKM({lat: $scope.curPos[0], lng: $scope.curPos[1]}, {lat: $scope.targetPos[0], lng: $scope.targetPos[1]});\r\n \t$scope.closeEnough = (distanceKM <= gameService.config.targetOKDistanceKM);\r\n\r\n \t// Update nonInteractive state.\r\n \tif (gameService.config.allowMapClickThrough) {\r\n \t\t$scope.nonInteractive = false;\r\n \t} else {\r\n \t\t$scope.nonInteractive = !$scope.closeEnough;\r\n \t}\r\n\r\n \tconsole.log(\"studentExerciseMapCtrl#onLocationUpdated: distanceKM = \" + distanceKM);\r\n \tconsole.log(\"studentExerciseMapCtrl \")\r\n\r\n \t$scope.youMarker.setCoordinates($scope.curPos);\r\n }\r\n\r\n $scope.onLocationUpdated();\r\n\r\n $scope.go = function() {\r\n \t$state.go('student.exercisebegin', {id: $stateParams.id});\r\n }\r\n }\r\n]);","app.controller('studentExercisePerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', 'gameService', '$state', '$stateParams', '$timeout', '$log', 'stopwatchService', 'analyticsService', function ($scope, $rootScope, $http, $mdDialog, gameService, $state, $stateParams, $timeout, $log, stopwatchService, analyticsService) {\n var vm = this;\n\n $scope.$on('$viewContentLoaded', function () {\n $timeout(function() {\n if (window.MathJax != null) {\n $log.debug(\"studentExercisePerformCtrl: viewContentLoaded typeset\");\n window.MathJax.Hub.Queue(\n [\"Typeset\",MathJax.Hub],\n [function() { $scope.$apply(function() {\n vm.showMathLoader = false;\n }); }]\n );\n } else {\n $log.debug(\"studentExercisePerformCtrl: no window.MathJax, skipping typeset\");\n }\n }, 1);\n });\n\n vm.gameService = gameService;\n vm.gameState = gameService.getGameState();\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n vm.question = gameService.lookupQuestion(vm.exercise.index, $stateParams.question);\n\n // Normally called in studentExerciseBeginCtrl. However,\n // we have observed that it sometimes isn't called. To ensure\n // proper analytics collection, attempt to register new times\n // for every exercise. If a time is already registered, this is\n // a no-op.\n stopwatchService.start(\"exercise\", vm.exercise.id);\n\n stopwatchService.start(\"exercise_question\", vm.exercise.id, $stateParams.question);\n\n vm.progressIndex = 1 + $stateParams.question;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n \n \tvm.points = 40;\n\n \tvm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n var parent = angular.element(\"#performarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n \tvm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.showMathLoader = vm.helpAvailable;\n\n \tvm.performAnswer = function(idx) {\n \t\tvar answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n analyticsService.event(\"exercise_question_answered\", {\n \"exercise_id\": vm.exercise.id,\n \"exercise_version\": vm.exercise.version,\n \"question_idx\": $stateParams.question,\n \"answer_idx\": idx,\n \"correct\": vm.question.answers[idx].correct\n });\n\n if (vm.question.answers[idx].correct) {\n var numTries = vm.activeAnswers.reduce(function(acc, val) {\n if (val == false) {\n acc += 1;\n }\n return acc;\n }, 0);\n\n stopwatchService.stop(\"exercise_question\", vm.exercise.id, $stateParams.question);\n var stopwatch = stopwatchService.get(\"exercise_question\", vm.exercise.id, $stateParams.question);\n analyticsService.event(\"exercise_question_completed\", {\n \"exercise_id\": vm.exercise.id,\n \"exercise_version\": vm.exercise.version,\n \"question_idx\": $stateParams.question,\n \"start_time\": stopwatch.start,\n \"end_time\": stopwatch.stop,\n \"elapsed_time\": stopwatch.elapsed, \n \"num_tries\": numTries\n });\n\n vm.activeAnswers = [ false, false, false, false ];\n vm.done = true;\n return;\n\t\t\t}\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n \tvm.popupShown = true;\n \t}\n\n \tvm.hidePopup = function() {\n \t\tvar idx = vm.answerIndex;\n\n\t\t\tvm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n \t}\n\n vm.firstRun = true;\n vm.helpShown = vm.helpAvailable;\n vm.showHelp = function() {\n \tvm.helpShown = true;\n vm.firstRun = false;\n }\n\n vm.hideHelp = function() {\n \tvm.helpShown = false;\n vm.firstRun = false\n\n $timeout(function() {\n var elements = angular.element(\".helpinner\");\n if (elements.length > 0) {\n elements[0].scrollTo(0, 0);\n }\n }, 0); // XXX: must match the transition time for .helppopover.\n }\n\n vm.next = function() {\n if (!vm.done) {\n return;\n }\n\n \tvm.gameState.score += vm.points;\n\n \t\t// Go to question?\n \t\tif ($stateParams.question < vm.exercise.questions.length - 1) {\n \t\t\tvm.gameState.exerciseIndex = $stateParams.id; // XXX\n \t\t\tvm.gameState.questionIndex = $stateParams.question + 1; // XXX\n\n \t\t\tvm.gameService.setGameState(vm.gameState).then(function() {\n \t\t\t\t$state.go('student.exerciseperform', { id: vm.gameState.exerciseIndex, question: vm.gameState.questionIndex });\n \t\t\t})\n\t\t\t// Go to evaluation interstitial?\n \t\t} else if ($stateParams.question === vm.exercise.questions.length - 1) {\n vm.gameState.exerciseIndex = $stateParams.id; // XXX\n vm.gameState.questionIndex = $stateParams.question + 1; // XXX\n\n \t\t\tvm.gameService.setGameState(vm.gameState).then(function() {\n \t\t\t\t$state.go('student.exerciseevalbegin', { id: $stateParams.id });\n \t\t\t});\n \t\t}\n \t}\n }\n]);","app.controller('studentExercisesCtrl', [\r\n '$scope', '$interval', 'gameService', '$state', '$stateParams', function ($scope, $interval, gameService, $state, $stateParams) {\r\n $scope.gameService = gameService;\r\n\r\n $scope.go = function() {\r\n \tvar exerciseIndex = $scope.gameService.gameState.exerciseIndex;\r\n \tvar questionIndex = $scope.gameService.gameState.questionIndex;\r\n \tvar evaluationQuestionIndex = $scope.gameService.gameState.evaluationQuestionIndex;\r\n\r\n\t\t\tvar exercise = gameService.exerciseWithIndex(exerciseIndex);\r\n\r\n\t\t\tconsole.log(exerciseIndex);\r\n\t\t\tconsole.log(questionIndex);\r\n\t\t\tconsole.log(evaluationQuestionIndex);\r\n\r\n\t\t\tif (questionIndex == 0 && evaluationQuestionIndex == 0) {\r\n\t $state.go('student.exercisemap', {id: exerciseIndex});\r\n\t } else if (questionIndex > 0 && questionIndex != exercise.questions.length && evaluationQuestionIndex == 0) {\r\n\t \t$state.go('student.exerciseperform', {id: exerciseIndex, question: questionIndex });\r\n\t } else if (questionIndex == exercise.questions.length && evaluationQuestionIndex == 0) {\r\n\t \t$state.go('student.exerciseevalbegin', { id: exerciseIndex });\r\n\t } else if (questionIndex == exercise.questions.length && evaluationQuestionIndex > 0) {\r\n\t \t$state.go('student.exerciseevalperform', { id: exerciseIndex, question: evaluationQuestionIndex });\r\n\t }\r\n\t }\r\n }\r\n]);","app.controller('studentFreeGamePerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', 'freeGameService', '$state', '$stateParams', '$timeout', '$log', function ($scope, $rootScope, $http, $mdDialog, freeGameService, $state, $stateParams, $timeout, $log) {\n var vm = this;\n\n\n $scope.$on('$viewContentLoaded', function () {\n $timeout(function() {\n if (window.MathJax != null) {\n $log.debug(\"studentExercisePerformCtrl: viewContentLoaded typeset\");\n window.MathJax.Hub.Queue(\n [\"Typeset\",MathJax.Hub],\n [function() { $scope.$apply(function() {\n vm.showMathLoader = false;\n }); }]\n );\n } else {\n $log.debug(\"studentExercisePerformCtrl: no window.MathJax, skipping typeset\");\n }\n }, 1);\n });\n\n vm.freeGameService = freeGameService;\n vm.exercise = freeGameService.exerciseWithIndex($stateParams.id);\n vm.question = freeGameService.lookupQuestion(vm.exercise.index, $stateParams.question);\n\n console.log(vm.exercise);\n\n vm.progressIndex = $stateParams.question;\n vm.progressCount = vm.exercise.questions.length;\n vm.progressArray = new Array(vm.progressCount);\n vm.lastQuestion = $stateParams.question == vm.exercise.questions.length - 1;\n \n \tvm.points = 40;\n\n \tvm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n var parent = angular.element(\"#performarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n \tvm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.showMathLoader = vm.helpAvailable;\n\n \tvm.performAnswer = function(idx) {\n \t\tvar answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n if (vm.question.answers[idx].correct) {\n vm.activeAnswers = [ false, false, false, false ];\n vm.done = true;\n return;\n\t\t\t}\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n \tvm.popupShown = true;\n \t}\n\n \tvm.hidePopup = function() {\n \t\tvar idx = vm.answerIndex;\n\n\t\t\tvm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n \t}\n\n vm.firstRun = true;\n vm.helpShown = vm.helpAvailable;\n vm.showHelp = function() {\n \tvm.helpShown = true;\n vm.firstRun = false;\n }\n\n vm.hideHelp = function() {\n \tvm.helpShown = false;\n vm.firstRun = false;\n\n $timeout(function() {\n var elements = angular.element(\".helpinner\");\n if (elements.length > 0) {\n elements[0].scrollTo(0, 0);\n }\n }, 0); // XXX: must match the transition time for .helppopover.\n }\n\n vm.next = function() {\n if (!vm.done) {\n return;\n }\n\n if (!vm.lastQuestion) {\n \t\t$state.go('student.freegameperform', { id: $stateParams.id, question: $stateParams.question + 1 });\n } else {\n $state.go('student.login');\n }\n \t}\n }\n]);","app.controller('studentLoginCtrl', [\r\n '$scope', '$state', 'authService', 'freeGameService', 'keyboardService', function ($scope, $state, authService, freeGameService, keyboardService) {\r\n var vm = this;\r\n\r\n vm.keyboardShown = keyboardService.isShown;\r\n $scope.$on('keyboardShownChanged', function(event, args) {\r\n $scope.$apply(function() {\r\n vm.keyboardShown = args.shown;\r\n });\r\n });\r\n\r\n vm.loggingIn = false;\r\n\r\n vm.pin1 = \"\";\r\n vm.pin2 = \"\";\r\n vm.pin3 = \"\";\r\n vm.pin4 = \"\";\r\n\r\n vm.resetPin = function() {\r\n vm.pin1 = \"\";\r\n vm.pin2 = \"\";\r\n vm.pin3 = \"\";\r\n vm.pin4 = \"\";\r\n }\r\n\r\n vm.pin1change = function() {\r\n if (vm.pin1.length > 0) {\r\n angular.element(\"#pin2\").focus();\r\n }\r\n }\r\n\r\n vm.pin1keydown = function(evt) {\r\n }\r\n\r\n vm.pin2change = function() {\r\n if (vm.pin2.length > 0) {\r\n angular.element(\"#pin3\").focus();\r\n } else {\r\n angular.element(\"#pin1\").focus();\r\n }\r\n }\r\n\r\n vm.pin2keydown = function(evt) {\r\n if (evt.keyCode === 8 && vm.pin2.length === 0) {\r\n angular.element(\"#pin1\").focus();\r\n }\r\n }\r\n\r\n vm.pin3change = function() {\r\n if (vm.pin3.length > 0) {\r\n angular.element(\"#pin4\").focus();\r\n } else {\r\n angular.element(\"#pin2\").focus();\r\n }\r\n }\r\n\r\n vm.pin3keydown = function(evt) {\r\n if (evt.keyCode === 8 && vm.pin3.length === 0) {\r\n angular.element(\"#pin2\").focus();\r\n }\r\n }\r\n\r\n vm.pin4change = function() {\r\n if (vm.pin4.length <= 0) {\r\n angular.element(\"#pin3\").focus();\r\n }\r\n }\r\n\r\n vm.pin4keydown = function(evt) {\r\n if (evt.keyCode === 8 && vm.pin4.length === 0) {\r\n angular.element(\"#pin3\").focus();\r\n }\r\n }\r\n\r\n vm.error = false;\r\n vm.login = function() {\r\n vm.error = false;\r\n var pin = \"\" + vm.pin1 + vm.pin2 + vm.pin3 + vm.pin4;\r\n vm.loggingIn = true;\r\n authService.authenticateWithPin(pin).then(function(authStatus) {\r\n vm.loggingIn = false;\r\n\r\n if (authStatus === true) {\r\n if (authService.isTeacher) {\r\n $state.go('teacherapp.welcome');\r\n } else {\r\n $state.go('student.welcome');\r\n }\r\n } else {\r\n vm.error = true;\r\n vm.resetPin();\r\n }\r\n }, function(err) {\r\n vm.loggingIn = false;\r\n vm.error = true;\r\n vm.resetPin();\r\n });\r\n }\r\n\r\n vm.goFreeGame = function() {\r\n $state.go('student.freegameperform', {id: 0, question: 0});\r\n }\r\n }\r\n]);","app.controller('studentMessagesCtrl', [\r\n '$scope', '$interval', '$state', '$stateParams', 'messageService', function ($scope, $interval, $state, $stateParams, messageService) {\r\n \tvar vm = this;\r\n\r\n\t\tvm.messageService = messageService;\r\n \tvm.messageService.setLastRead();\r\n\r\n\t\tvm.messages = angular.copy(vm.messageService.messages);\r\n\t\r\n \t$scope.$on('messageServiceUpdated', function() {\r\n\t\t\tconsole.log(\"tudentMessagesCtrl: sync'd messages with messageService\");\r\n\t\t\tvm.messages = angular.copy(vm.messageService.messages);\r\n \t});\r\n\r\n\t}\r\n]);\r\n","app.controller('trophyIndexCtrl', [\r\n '$scope', 'gameService', '$timeout', function ($scope, gameService, $timeout) {\r\n\r\n \t$scope.score = gameService.gameState.score;\r\n \t\r\n var teamName = gameService.teamName;\r\n var trimmedTeamName = teamName;\r\n if (teamName.length > 15) {\r\n trimmedTeamName = trimmedTeamName.substr(0, 15) + \"...\";\r\n }\r\n $scope.teamName = teamName;\r\n $scope.trophyTeamName = trimmedTeamName;\r\n\r\n $scope.confetti = new TG.Confetti({\r\n viewport: document.getElementsByClassName(\"confetticanvas\")[0],\r\n texture: '/img/confetti-sprite.png',\r\n particleCount: 759,\r\n particleScale: 1.0\r\n });\r\n\r\n $scope.fireConfettiLoop = function() {\r\n $timeout(function() {\r\n $scope.confetti.fireLeftCannon();\r\n $timeout(function() {\r\n $scope.confetti.fireRightCannon();\r\n $timeout(function() {\r\n $scope.confetti.fireCenterCannon();\r\n $timeout(function() {\r\n $scope.initiateConfettiLoop();\r\n }, 2250);\r\n }, 2250);\r\n }, 750);\r\n }, 750);\r\n }\r\n\r\n $scope.initiateConfettiLoop = function() {\r\n $scope.fireConfettiLoop();\r\n }\r\n\r\n $scope.initiateConfettiLoop();\r\n\r\n $scope.$on('$destroy', function() {\r\n $scope.confetti.dispose();\r\n });\r\n }\r\n]);","app.controller('studentWelcome1Ctrl', [\r\n '$scope', '$interval', 'Upload', 'gameService', 'welcomeService', '$state', 'keyboardService', function ($scope, $interval, Upload, gameService, welcomeService, $state, keyboardService) {\r\n\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n vm.welcomeService = welcomeService;\r\n\r\n vm.keyboardShown = keyboardService.isShown;\r\n $scope.$on('keyboardShownChanged', function(event, args) {\r\n vm.keyboardShown = args.shown;\r\n }); \r\n\r\n var now = new Date();\r\n var startTime = vm.gameService.startTime;\r\n var timeRemainingMsecs = startTime.getTime() - now.getTime();\r\n vm.timeRemainingSecs = parseInt(timeRemainingMsecs / 1000.0, 10);\r\n\r\n vm.onTeamInfoUpdated = function() {\r\n if (!welcomeService.teamImageURL) {\r\n welcomeService.w1imageStyle[\"background-image\"] = \"url(\\\"/img/defaultteam.svg\\\")\";\r\n } else {\r\n welcomeService.w1imageStyle[\"background-image\"] = \"url(\\\"\" + welcomeService.teamImageURL + \"\\\")\";\r\n }\r\n }\r\n\r\n vm.onTeamInfoUpdated();\r\n\r\n $scope.$watch(angular.bind(vm, function () {\r\n vm.onTeamInfoUpdated();\r\n }));\r\n\r\n vm.uploading = false;\r\n vm.upload = function (file) {\r\n if (file == null) {\r\n return;\r\n }\r\n\r\n vm.uploading = true;\r\n gameService.uploadTeamImage(file).then(function(url) {\r\n welcomeService.teamImageURL = url;\r\n vm.uploading = false;\r\n }, function() {\r\n vm.uploading = false;\r\n });\r\n }\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.onTeamNameChanged = function() {\r\n if (!welcomeService.teamName) {\r\n $scope.$parent.enabledPages[0] = false;\r\n $scope.$parent.enabledPages[1] = false;\r\n } else {\r\n $scope.$parent.enabledPages[0] = true;\r\n $scope.$parent.enabledPages[1] = true;\r\n }\r\n }\r\n\r\n $scope.$watch('welcomeService.teamName', angular.bind(vm, function() {\r\n vm.onTeamNameChanged();\r\n }));\r\n\r\n vm.next = function() {\r\n $scope.$parent.nextPage();\r\n }\r\n\r\n $scope.$on('carouselPageChange', function(event, args) {\r\n if (args.prevPage == 0 && args.newPage == 1) {\r\n gameService.setTeamInfo({\r\n teamName: welcomeService.teamName,\r\n teamImageURL: welcomeService.teamImageURL\r\n });\r\n }\r\n });\r\n }\r\n]);","app.controller('studentWelcome2Ctrl', [\r\n '$scope', '$interval', 'Upload', 'gameService', 'welcomeService', '$state', 'keyboardService', function ($scope, $interval, Upload, gameService, welcomeService, $state, keyboardService) {\r\n\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n vm.welcomeService = welcomeService;\r\n\r\n vm.keyboardShown = keyboardService.isShown;\r\n $scope.$on('keyboardShownChanged', function(event, args) {\r\n vm.keyboardShown = args.shown;\r\n });\r\n\r\n var now = new Date();\r\n var startTime = vm.gameService.startTime;\r\n var timeRemainingMsecs = startTime.getTime() - now.getTime();\r\n vm.timeRemainingSecs = parseInt(timeRemainingMsecs / 1000.0, 10);\r\n\r\n vm.onTeamInfoUpdated = function() {\r\n if (!welcomeService.teamImageURL) {\r\n welcomeService.w1imageStyle[\"background-image\"] = \"url(\\\"/img/defaultteam.svg\\\")\";\r\n } else {\r\n welcomeService.w1imageStyle[\"background-image\"] = \"url(\\\"\" + vm.teamImageURL + \"\\\")\";\r\n }\r\n }\r\n\r\n vm.onTeamInfoUpdated();\r\n\r\n $scope.$watch('welcomeService.teamImageURL', angular.bind(vm, function() {\r\n vm.onTeamInfoUpdated();\r\n }));\r\n\r\n vm.uploading = false;\r\n vm.upload = function (file) {\r\n if (file == null) {\r\n return;\r\n }\r\n\r\n vm.uploading = true;\r\n gameService.uploadTeamImage(file).then(function(url) {\r\n welcomeService.teamImageURL = url;\r\n vm.uploading = false;\r\n }, function() {\r\n vm.uploading = false;\r\n });\r\n }\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.onTeamNameChanged = function() {\r\n if (!welcomeService.teamName) {\r\n $scope.$parent.enabledPages[0] = false;\r\n $scope.$parent.enabledPages[1] = false;\r\n } else {\r\n $scope.$parent.enabledPages[0] = true;\r\n $scope.$parent.enabledPages[1] = true;\r\n }\r\n }\r\n\r\n $scope.$watch('welcomeService.teamName', angular.bind(vm, function() {\r\n vm.onTeamNameChanged();\r\n }));\r\n\r\n vm.prev = function() {\r\n $scope.$parent.prevPage();\r\n }\r\n\r\n vm.next = function() {\r\n $scope.$parent.nextPage();\r\n }\r\n\r\n $scope.$on('carouselPageChange', function(event, args) {\r\n if (args.prevPage == 1 && args.newPage == 2) {\r\n gameService.setTeamInfo({\r\n teamName: welcomeService.teamName,\r\n teamImageURL: welcomeService.teamImageURL\r\n });\r\n }\r\n });\r\n }\r\n]);","app.controller('studentWelcome3Ctrl', [\r\n '$scope', '$interval', 'gameService', '$state', function ($scope, $interval, gameService, $state) {\r\n\r\n var vm = this;\r\n vm.gameService = gameService;\r\n\r\n var now = new Date();\r\n var startTime = vm.gameService.startTime;\r\n var timeRemainingMsecs = startTime.getTime() - now.getTime();\r\n vm.timeRemainingSecs = parseInt(timeRemainingMsecs / 1000.0, 10);\r\n\r\n vm.canProceed = true;\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.prev = function() {\r\n $scope.$parent.prevPage();\r\n }\r\n\r\n vm.next = function() {\r\n $scope.$parent.nextPage();\r\n }\r\n }\r\n]);","app.controller('studentWelcome3CtrlOrig', [\r\n '$scope', '$interval', 'gameService', '$state', function ($scope, $interval, gameService, $state) {\r\n\r\n var vm = this;\r\n\r\n vm.timeRemainingSecs = 84010; // 23h, 20m, 10s\r\n vm.showPlaceHolder = true;\r\n vm.canProceed = gameService.config.allowSkipIntroMovie;\r\n vm.skipPercentage = gameService.config.introMoviePassPercentage;\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.isPlaying = false;\r\n vm.playVideo = function() {\r\n var video = $(\".w3video\")[0];\r\n if (vm.showPlaceHolder) {\r\n vm.showPlaceHolder = false;\r\n video.play();\r\n video.addEventListener(\"timeupdate\", vm.onVideoTimeUpdated);\r\n vm.isPlaying = true;\r\n } else {\r\n if (vm.isPlaying) {\r\n video.pause();\r\n vm.isPlaying = false;\r\n } else {\r\n video.play();\r\n vm.isPlaying = true;\r\n }\r\n }\r\n }\r\n\r\n vm.onVideoTimeUpdated = function(event) {\r\n var percentage = Math.floor((100 / event.target.duration) * event.target.currentTime);\r\n if (percentage >= (vm.skipPercentage * 100.0) && !vm.canProceed) {\r\n vm.canProceed = true;\r\n }\r\n }\r\n\r\n vm.onCanProceedChanged = function() {\r\n if (!vm.canProceed) {\r\n $scope.$parent.enabledPages[2] = false;\r\n } else {\r\n $scope.$parent.enabledPages[2] = true;\r\n }\r\n }\r\n\r\n $scope.$watch('vm.canProceed', angular.bind(vm, function() {\r\n vm.onCanProceedChanged();\r\n }));\r\n\r\n vm.prev = function() {\r\n $scope.$parent.prevPage();\r\n }\r\n\r\n vm.next = function() {\r\n var video = $(\".w3video\")[0];\r\n video.pause();\r\n $scope.$parent.nextPage();\r\n }\r\n }\r\n]);","app.controller('studentWelcome4Ctrl', [\r\n '$scope', '$interval', 'gameService', '$state', function ($scope, $interval, gameService, $state) {\r\n var vm = this;\r\n\r\n vm.gameService = gameService;\r\n\r\n var now = new Date();\r\n var startTime = vm.gameService.startTime;\r\n var timeRemainingMsecs = startTime.getTime() - now.getTime();\r\n vm.timeRemainingSecs = parseInt(timeRemainingMsecs / 1000.0, 10);\r\n\r\n vm.canProceed = false;\r\n $scope.$parent.enabledPages[3] = false;\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateCanProceed = function() {\r\n var trs = vm.timeRemainingSecs;\r\n var enabled = trs <= 0;\r\n vm.canProceed = enabled;\r\n $scope.$parent.enabledPages[3] = enabled;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n vm.updateCanProceed();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n vm.updateCanProceed();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.prev = function() {\r\n $scope.$parent.prevPage();\r\n }\r\n\r\n vm.next = function() {\r\n $scope.$parent.nextPage();\r\n }\r\n }\r\n]);\r\n","app.controller('studentWelcome5Ctrl', [\r\n '$scope', '$interval', 'gameService', 'welcomeService', '$state', function ($scope, $interval, gameService, welcomeService, $state) {\r\n var vm = this;\r\n\r\n var idx = $scope.$parent.indexOfPage($scope);\r\n console.log(\"my index is \" + idx);\r\n\r\n vm.gameService = gameService;\r\n vm.welcomeService = welcomeService;\r\n\r\n vm.timeRemainingSecs = 84010; // 23h, 20m, 10s\r\n\r\n vm.updateClockDisplay = function() {\r\n var trs = vm.timeRemainingSecs;\r\n \r\n var hr = parseInt(Math.floor(trs / 3600));\r\n trs -= (hr * 3600);\r\n\r\n var mr = parseInt(Math.floor(trs / 60));\r\n trs -= (mr * 60);\r\n \r\n vm.daysRemain = Math.floor(hr / 24.0);\r\n vm.hoursRemain = hr;\r\n vm.minutesRemain = mr;\r\n vm.secondsRemain = trs;\r\n }\r\n\r\n vm.updateClockDisplay();\r\n\r\n vm.countdownId = $interval(function() {\r\n vm.timeRemainingSecs -= 1;\r\n vm.updateClockDisplay();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n $interval.cancel(vm.countdownId);\r\n });\r\n\r\n vm.prev = function() {\r\n $scope.$parent.prevPage();\r\n }\r\n\r\n vm.start = function() {\r\n gameService.setWelcomeFinished(true).then(function() {\r\n $state.go('student.exercises');\r\n });\r\n }\r\n }\r\n]);","app.controller('studentWorthKnowingIndexCtrl', [\r\n '$scope', function ($scope) {\r\n }\r\n]);","app.controller('teacherAppExerciseBeginCtrl', [\n '$scope', '$interval', 'gameService', '$state', '$stateParams', function ($scope, $interval, gameService, $state, $stateParams) {\n var vm = this;\n\n vm.gameService = gameService;\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n\n vm.progressIndex = 0;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length;\n vm.progressArray = new Array(vm.progressCount);\n\n vm.ebimageStyle = {\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\n \t\"background-size\": \"cover\"\n };\n\n vm.next = function() {\n \t$state.go('teacherapp.exerciseperform', {id: $stateParams.id, question: 0});\n }\n } \n\n]);\n","app.controller('teacherAppExerciseDoneCtrl', [\n '$scope', '$interval', 'gameService', '$state', '$stateParams', '$timeout', function ($scope, $interval, gameService, $state, $stateParams, $timeout) {\n var vm = this;\n\n vm.gameService = gameService;\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n\n vm.progressIndex = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n\n var parent = angular.element(\"#evalbeginarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n vm.arrow = null;\n })\n\n vm.ebimageStyle = {\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\n \t\"background-size\": \"cover\"\n };\n\n vm.next = function() {\n $state.go('teacherapp.exercises');\n }\n\n // -- CONFETTI --\n\n vm.confetti = new TG.Confetti({\n viewport: document.getElementsByClassName(\"confetticanvas\")[0],\n texture: '/img/confetti-sprite.png',\n particleCount: 759,\n particleScale: 1.0\n });\n\n vm.fireConfettiLoop = function() {\n $timeout(function() {\n vm.confetti.fireCenterCannon();\n }, 750);\n }\n\n vm.initiateConfettiLoop = function() {\n vm.fireConfettiLoop();\n }\n\n vm.initiateConfettiLoop();\n\n $scope.$on('$destroy', function() {\n vm.confetti.dispose();\n });\n }\n]);\n","app.controller('teacherAppExerciseEvalBeginCtrl', [\n '$scope', '$interval', 'gameService', '$state', '$stateParams', function ($scope, $interval, gameService, $state, $stateParams) {\n var vm = this;\n\n vm.gameService = gameService;\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n\n vm.progressIndex = 1 + vm.exercise.questions.length;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n\n var parent = angular.element(\"#evalbeginarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n vm.arrow = null;\n })\n\n vm.ebimageStyle = {\n \t\"background-image\": \"url(\\\"\" + vm.exercise.imageUrl + \"\\\")\",\n \t\"background-size\": \"cover\"\n };\n\n vm.next = function() {\n \t$state.go('teacherapp.exerciseevalperform', {id: $stateParams.id, question: 0});\n }\n }\n\n]);\n","app.controller('teacherAppExerciseEvalPerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', 'gameService', '$state', '$stateParams', '$log', function ($scope, $rootScope, $http, $mdDialog, gameService, $state, $stateParams, $log) {\n var vm = this;\n\n vm.gameService = gameService;\n vm.gameState = gameService.getGameState();\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n vm.question = gameService.lookupEvaluationQuestion(vm.exercise.index, $stateParams.question);\n\n vm.progressIndex = 1 + vm.exercise.questions.length + 1 + $stateParams.question;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n\t vm.progressArray = new Array(vm.progressCount);\n\n \tvm.points = 40;\n\n \tvm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n var parent = angular.element(\"#eearrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n vm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.performAnswer = function(idx) {\n var answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n if (vm.question.answers[idx].correct) {\n vm.activeAnswers = [ false, false, false, false ];\n vm.next();\n return;\n }\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n vm.popupShown = true;\n }\n\n vm.hidePopup = function() {\n var idx = vm.answerIndex;\n\n vm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n }\n\n vm.next = function() {\n vm.gameState.score += vm.points;\n\n // Go next evaluation question?\n if ($stateParams.question < vm.exercise.evaluationQuestions.length - 1) {\n vm.gameState.evaluationQuestionIndex += 1;\n\n gameService.setGameState(vm.gameState).then(function() {\n $state.go('teacherapp.exerciseevalperform', { id: $stateParams.id, question: vm.gameState.evaluationQuestionIndex });\n });\n // Go done?\n } else if ($stateParams.question === vm.exercise.evaluationQuestions.length - 1) {\n // Last exercise? Go to trophy.\n if (vm.gameService.exercises.length - 1 === vm.gameState.exerciseIndex) {\n vm.gameState.exerciseIndex += 1;\n vm.gameState.questionIndex = 0;\n vm.gameState.evaluationQuestionIndex = 0;\n gameService.setGameState(vm.gameState).then(function() {\n $state.go('teacherapp.exercises');\n });\n // Else, do as normal.\n } else {\n vm.gameState.exerciseIndex += 1;\n vm.gameState.questionIndex = 0;\n vm.gameState.evaluationQuestionIndex = 0;\n \n gameService.setGameState(vm.gameState).then(function() {\n $state.go('teacherapp.exercisedone', { id: $stateParams.id });\n });\n }\n }\n }\n }\n]);","app.controller('teacherAppExerciseMapCtrl', [\n '$scope', '$interval', 'gameService', '$state', '$stateParams', '$interval', 'locationService', function ($scope, $interval, gameService, $state, $stateParams, $interval, locationService) {\n $scope.gameService = gameService;\n\n $scope.exercise = gameService.exerciseWithIndex($stateParams.id);\n\n\t\t$scope.curPos = [0.0, 0.0];\n $scope.targetPos = $scope.exercise.mapPos;\n\t\t$scope.targetOKDistanceKM = gameService.config.targetOKDistanceKM;\n $scope.closeEnough = false;\n $scope.nonInteractive = false;\n\n \t$scope.map = new maptalks.Map('maptalksc', {\n \tcenter: gameService.config.mapCenter,\n \tzoom: 16.64,\n \tbearing: 150.0,\n \tattribution: false,\n\n\t //allow map to drag pitching, true by default\n \tdragPitch : false,\n \t//allow map to drag rotating, true by default\n \tdragRotate : true,\n \t//enable map to drag pitching and rotating at the same time, false by default\n \tdragRotatePitch : false,\n\n \tbaseLayer: new maptalks.TileLayer('base', {\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n \t\tsubdomains: ['a','b','c','d'],\n \t\tattribution: ''\n \t})\n \t});\n\n\t\tvar center = $scope.map.getCenter();\n\t\tvar layer = new maptalks.VectorLayer('vector').addTo($scope.map);\n\n $scope.rideMarkers = {};\n\n for (var i = 0; i < $scope.gameService.rides.length; i++) {\n var ride = $scope.gameService.rides[i];\n\n if (ride.enabled) {\n var marker = new maptalks.Marker(ride.location, {\n 'symbol' : {\n 'markerFile' : ride.markerImage,\n 'markerWidth' : ride.markerWidth,\n 'markerHeight' : ride.markerHeight,\n 'markerDx' : 0,\n 'markerDy' : 0,\n 'markerOpacity': 1\n }\n });\n $scope.rideMarkers[ride.key] = marker;\n marker.addTo(layer);\n }\n }\n\n // Add the go-to pos\n \t$scope.targetMarker = new maptalks.Marker(\n \t$scope.targetPos,\n \t{\n\t \t'symbol' : {\n\t \t'markerFile' : window.location.origin + '/img/map/MapPin.svg',\n\t \t'markerWidth' : 2*22,\n\t \t'markerHeight' : 2*35.5,\n\t \t'markerDx' : 0,\n\t \t'markerDy' : 0,\n\t \t'markerOpacity': 1\n\t \t}\n\t \t}\n \t);\n \t$scope.targetMarker.addTo(layer);\n\n // Add the You marker.\n $scope.youMarker = new maptalks.Marker($scope.curPos, {\n \t'symbol' : {\n \t'markerFile' : window.location.origin + '/img/map/marker-you.svg',\n \t'markerWidth' : 22,\n \t'markerHeight' : 22,\n \t'markerDx' : 0,\n \t'markerDy' : 0,\n \t'markerOpacity': 1\n \t}\n });\n $scope.youMarker.addTo(layer);\n\n $scope._intervalPromise = $interval(function() {\n \t$scope.onLocationUpdated();\n }, 1000);\n\n $scope.$on('$destroy', function() {\n \t$interval.cancel($scope._intervalPromise);\n })\n\n $scope.onLocationUpdated = function () {\n \tvar pos = locationService.getLocation();\n \tif (!pos) {\n \t\treturn;\n \t}\n\n \t$scope.curPos = [pos.lng, pos.lat];\n\n \t// Update closeEnough state.\n \tvar distanceKM = locationService.distanceInKM({lat: $scope.curPos[0], lng: $scope.curPos[1]}, {lat: $scope.targetPos[0], lng: $scope.targetPos[1]});\n \t$scope.closeEnough = (distanceKM <= gameService.config.targetOKDistanceKM);\n\n \t// Update nonInteractive state.\n \tif (gameService.config.allowMapClickThrough) {\n \t\t$scope.nonInteractive = false;\n \t} else {\n \t\t$scope.nonInteractive = !$scope.closeEnough;\n \t}\n\n \tconsole.log(\"studentExerciseMapCtrl#onLocationUpdated: distanceKM = \" + distanceKM);\n \tconsole.log(\"studentExerciseMapCtrl \")\n\n \t$scope.youMarker.setCoordinates($scope.curPos);\n }\n\n $scope.onLocationUpdated();\n\n $scope.go = function() {\n \t$state.go('teacherapp.exercisebegin', {id: $stateParams.id});\n }\n }\n]);","app.controller('teacherAppExercisePerformCtrl', [\n '$scope', '$rootScope', '$http', '$mdDialog', 'gameService', '$state', '$stateParams', '$timeout', '$log', function ($scope, $rootScope, $http, $mdDialog, gameService, $state, $stateParams, $timeout, $log) {\n var vm = this;\n\n $scope.$on('$viewContentLoaded', function () {\n $timeout(function() {\n if (window.MathJax != null) {\n $log.debug(\"teacherAppExercisePerformCtrl: viewContentLoaded typeset\");\n window.MathJax.Hub.Queue(\n [\"Typeset\",MathJax.Hub],\n [function() { $scope.$apply(function() {\n vm.showMathLoader = false;\n }); }]\n );\n } else {\n $log.debug(\"teacherAppExercisePerformCtrl: no window.MathJax, skipping typeset\");\n }\n }, 1);\n });\n\n vm.gameService = gameService;\n vm.gameState = gameService.getGameState();\n vm.exercise = gameService.exerciseWithIndex($stateParams.id);\n vm.question = gameService.lookupQuestion(vm.exercise.index, $stateParams.question);\n\n vm.progressIndex = 1 + $stateParams.question;\n vm.progressCount = 1 + vm.exercise.questions.length + 1 + vm.exercise.evaluationQuestions.length + 1;\n vm.progressArray = new Array(vm.progressCount);\n \n \tvm.points = 40;\n\n \tvm.activeAnswers = [ true, true, true, true ];\n vm.done = false;\n\n var parent = angular.element(\"#performarrow\")[0];\n vm.arrow = new TivoliArrow(parent);\n vm.arrow.start();\n\n $scope.$on('$destroy', function() {\n vm.arrow.stop();\n \tvm.arrow = null;\n });\n\n vm.popupShown = false;\n vm.answer = null;\n vm.answerIndex = 0;\n\n vm.helpAvailable = vm.question.extraButtonText.length > 0;\n\n vm.showMathLoader = vm.helpAvailable;\n\n \tvm.performAnswer = function(idx) {\n \t\tvar answerObj = vm.question.answers[idx];\n\n // Don't do anything if the answer isn't active.\n if (!vm.activeAnswers[idx]) {\n return;\n }\n\n if (vm.question.answers[idx].correct) {\n vm.activeAnswers = [ false, false, false, false ];\n vm.done = true;\n return;\n\t\t\t}\n\n vm.answerIndex = idx;\n vm.answer = answerObj;\n \tvm.popupShown = true;\n \t}\n\n \tvm.hidePopup = function() {\n \t\tvar idx = vm.answerIndex;\n\n\t\t\tvm.activeAnswers[idx] = false;\n vm.points -= 10;\n vm.popupShown = false;\n \t}\n\n vm.helpShown = vm.helpAvailable;\n vm.firstRun = true;\n vm.showHelp = function() {\n \tvm.helpShown = true;\n vm.firstRun = false;\n }\n\n vm.hideHelp = function() {\n \tvm.helpShown = false;\n vm.firstRun = false;\n\n $timeout(function() {\n var elements = angular.element(\".helpinner\");\n if (elements.length > 0) {\n elements[0].scrollTo(0, 0);\n }\n }, 0); // XXX: must match the transition time for .helppopover.\n }\n\n vm.next = function() {\n if (!vm.done) {\n return;\n }\n\n \tvm.gameState.score += vm.points;\n\n \t\t// Go to question?\n \t\tif ($stateParams.question < vm.exercise.questions.length - 1) {\n \t\t\tvm.gameState.exerciseIndex = $stateParams.id; // XXX\n \t\t\tvm.gameState.questionIndex = $stateParams.question + 1; // XXX\n\n \t\t\tvm.gameService.setGameState(vm.gameState).then(function() {\n \t\t\t\t$state.go('teacherapp.exerciseperform', { id: vm.gameState.exerciseIndex, question: vm.gameState.questionIndex });\n \t\t\t})\n\t\t\t// Go to evaluation interstitial?\n \t\t} else if ($stateParams.question === vm.exercise.questions.length - 1) {\n vm.gameState.exerciseIndex = $stateParams.id; // XXX\n vm.gameState.questionIndex = $stateParams.question + 1; // XXX\n\n \t\t\tvm.gameService.setGameState(vm.gameState).then(function() {\n \t\t\t\t$state.go('teacherapp.exerciseevalbegin', { id: $stateParams.id });\n \t\t\t});\n \t\t}\n \t}\n }\n]);","app.controller('teacherAppExercisesCtrl', [\n '$scope', '$interval', 'gameService', '$state', '$stateParams', function ($scope, $interval, gameService, $state, $stateParams) {\n $scope.gameService = gameService;\n\n $scope.go = function() {\n \tvar exerciseIndex = $scope.gameService.gameState.exerciseIndex;\n \tvar questionIndex = $scope.gameService.gameState.questionIndex;\n \tvar evaluationQuestionIndex = $scope.gameService.gameState.evaluationQuestionIndex;\n\n\t\t\tvar exercise = gameService.exerciseWithIndex(exerciseIndex);\n\n\t\t\tconsole.log(exerciseIndex);\n\t\t\tconsole.log(questionIndex);\n\t\t\tconsole.log(evaluationQuestionIndex);\n\n\t\t\tif (questionIndex == 0 && evaluationQuestionIndex == 0) {\n\t $state.go('student.exercisemap', {id: exerciseIndex});\n\t } else if (questionIndex > 0 && questionIndex != exercise.questions.length && evaluationQuestionIndex == 0) {\n\t \t$state.go('student.exerciseperform', {id: exerciseIndex, question: questionIndex });\n\t } else if (questionIndex == exercise.questions.length && evaluationQuestionIndex == 0) {\n\t \t$state.go('student.exerciseevalbegin', { id: exerciseIndex });\n\t } else if (questionIndex == exercise.questions.length && evaluationQuestionIndex > 0) {\n\t \t$state.go('student.exerciseevalperform', { id: exerciseIndex, question: evaluationQuestionIndex });\n\t }\n\t }\n }\n]);","app.controller('teacherAppGroupMapCtrl', [\r\n '$scope', '$interval', '$state', '$stateParams', 'gameService', 'teacherAppService', '$interval', 'locationService', function ($scope, $interval, $state, $stateParams, gameService, teacherAppService, $interval, locationService) {\r\n \tvar vm = this;\r\n\r\n \tvm.gameService = gameService;\r\n\r\n\t\tvm.curPos = [0.0, 0.0];\r\n\r\n \tvm.map = new maptalks.Map('maptalksc', {\r\n \tcenter: vm.gameService.config.mapCenter,\r\n \tzoom: 16.64,\r\n \tbearing: 150.0,\r\n \tattribution: false,\r\n\r\n\t //allow map to drag pitching, true by default\r\n \tdragPitch : false,\r\n \t//allow map to drag rotating, true by default\r\n \tdragRotate : true,\r\n \t//enable map to drag pitching and rotating at the same time, false by default\r\n \tdragRotatePitch : false,\r\n\r\n \tbaseLayer: new maptalks.TileLayer('base', {\r\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\r\n \t\tsubdomains: ['a','b','c','d'],\r\n \t\tattribution: ''\r\n \t})\r\n \t});\r\n\r\n\t\tvar center = vm.map.getCenter();\r\n\t\tvar layer = new maptalks.VectorLayer('vector').addTo(vm.map);\r\n\r\n\t\tvm.rideMarkers = {};\r\n for (var i = 0; i < vm.gameService.rides.length; i++) {\r\n var ride = vm.gameService.rides[i];\r\n\r\n if (ride.enabled) {\r\n var marker = new maptalks.Marker(ride.location, {\r\n 'symbol' : {\r\n 'markerFile' : ride.markerImage,\r\n 'markerWidth' : ride.markerWidth,\r\n 'markerHeight' : ride.markerHeight,\r\n 'markerDx' : 0,\r\n 'markerDy' : 0,\r\n 'markerOpacity': 1\r\n }\r\n });\r\n vm.rideMarkers[ride.key] = marker;\r\n marker.addTo(layer);\r\n }\r\n }\r\n\r\n // Add the You marker.\r\n vm.youMarker = new maptalks.Marker(vm.curPos, {\r\n \t'symbol' : {\r\n \t'markerFile' : window.location.origin + '/img/map/MapPinLærer.svg',\r\n 'markerWidth' : 2*22,\r\n 'markerHeight' : 2*35.5,\r\n \t'markerDx' : 0,\r\n \t'markerDy' : 0,\r\n \t'markerOpacity': 1\r\n \t}\r\n });\r\n vm.youMarker.addTo(layer);\r\n\r\n vm._intervalPromise = $interval(function() {\r\n \tvm.onLocationUpdated();\r\n vm.updateMarkerLocations();\r\n }, 1000);\r\n\r\n $scope.$on('$destroy', function() {\r\n \t$interval.cancel(vm._intervalPromise);\r\n });\r\n\r\n vm.gameMarkers = [];\r\n vm.createGameMarkers = function() {\r\n if (vm.gameMarkers.length === 0) {\r\n var gameInfos = teacherAppService.gameInfo;\r\n for (var i = 0; i < gameInfos.length; i++) {\r\n if (i > 9) {\r\n // XXX: we currently only have images for 1-10.\r\n continue;\r\n }\r\n\r\n var gameInfo = gameInfos[i];\r\n var marker = new maptalks.Marker(gameInfo.locationState.lastLocation, {\r\n 'symbol' : {\r\n 'markerFile' : window.location.origin + '/img/map/MapPin' + (i + 1) + '.svg',\r\n 'markerWidth' : 2*22,\r\n 'markerHeight' : 2*35.5,\r\n 'markerDx' : 0,\r\n 'markerDy' : 0,\r\n 'markerOpacity': 1\r\n }\r\n });\r\n marker.addTo(layer);\r\n\r\n vm.gameMarkers.push(marker);\r\n }\r\n }\r\n }\r\n\r\n vm.updateMarkerLocations = function() {\r\n vm.createGameMarkers();\r\n\r\n var gameInfos = teacherAppService.gameInfo;\r\n for (var i = 0; i < gameInfos.length; i++) {\r\n var gameInfo = gameInfos[i];\r\n var teamNumber = i + 1;\r\n var marker = vm.gameMarkers[i];\r\n marker.setCoordinates(gameInfo.locationState.lastLocation);\r\n\r\n // Set a random zindex for the marker.\r\n // First, we generate a random number between 0 and gameInfos.length + 1 (to compensate for the teacher marker).\r\n // Then we add 1 to the result to reserve 0 for the ride markers.\r\n marker.setZIndex(Math.floor(Math.random() * (gameInfos.length + 1)) + 1);\r\n }\r\n }\r\n\r\n $scope.$on('teacherAppServiceUpdated', function(gameInfo) {\r\n vm.updateMarkerLocations();\r\n });\r\n\r\n vm.onLocationUpdated = function () {\r\n \tvar pos = locationService.getLocation();\r\n \tif (!pos) {\r\n \t\treturn;\r\n \t}\r\n\r\n \tvm.curPos = [pos.lng, pos.lat];\r\n \tvm.youMarker.setCoordinates(vm.curPos);\r\n\r\n // Set a random zindex for the marker.\r\n // First, we generate a random number between 0 and gameInfos.length + 1 (to compensate for the teacher marker).\r\n // Then we add 1 to the result to reserve 0 for the ride markers.\r\n var gameInfos = teacherAppService.gameInfo;\r\n vm.youMarker.setZIndex(Math.floor(Math.random() * (gameInfos.length + 1)) + 1);\r\n }\r\n\r\n // Update the teacher marker location.\r\n vm.onLocationUpdated();\r\n\r\n // Update marker locations on load; the teacherAppService has already\r\n // been updated at login.\r\n vm.updateMarkerLocations();\r\n\r\n vm.sendMessage = function() {\r\n $state.go('teacherapp.messages');\r\n }\r\n }\r\n]);","app.controller('teacherAppGroupStatusCtrl', [\r\n '$scope', '$interval', 'gameService', 'teacherAppService', '$state', '$stateParams', '$window', '$timeout', function ($scope, $interval, gameService, teacherAppService, $state, $stateParams, $window, $timeout) {\r\n \tvar vm = this;\r\n\r\n \tvm.gameService = gameService;\r\n vm.teacherAppService = teacherAppService;\r\n\r\n\t\tvm.gameInverseProgressStyle = [];\r\n\t\tvm.gameProgress = [];\r\n\r\n function countGameStateProgress(gameState) {\r\n\t\t\tvar count = 0;\r\n\t for (var i = 0; i < gameService.exercises.length; i++) {\r\n\t \tif (i == gameState.exerciseIndex) {\r\n\t\t \t\tcount += gameState.questionIndex;\r\n\t\t \t\tcount += gameState.evaluationQuestionIndex;\r\n\t\t \t\treturn count;\r\n\t \t}\r\n\t\t\t\tvar exercise = gameService.exercises[i];\r\n\t\t\t\tcount += exercise.questions.length;\r\n\t\t\t\tcount += exercise.evaluationQuestions.length;\r\n\t }\r\n\t return count;\r\n }\r\n\r\n vm.showDetails = function(idx) {\r\n\t\t\tvm.teacherAppService.setCurrentGroup(idx);\r\n\t\t\t$state.go('teacherapp.groupstatus.details', {id: idx});\r\n }\r\n\r\n vm.updateStateFromTeacherAppService = function() {\r\n\t\t\tif (!teacherAppService.isReady()) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n \t\tvar totalItems = 0;\r\n\t for (var i = 0; i < gameService.exercises.length; i++) {\r\n\t \tvar exercise = gameService.exercises[i];\r\n\t \ttotalItems += exercise.questions.length;\r\n\t \ttotalItems += exercise.evaluationQuestions.length;\r\n\t }\r\n\r\n\t vm.gameInverseProgressStyle = [];\r\n\t vm.gameProgress = [];\r\n\t var gameInfo = vm.teacherAppService.gameInfo;\r\n\t for (var i = 0; i < gameInfo.length; i++) {\r\n\t \tvar gi = gameInfo[i];\r\n\t \tvar gameState = gi.gameState;\r\n\t\t\t\tvar progress = countGameStateProgress(gameState);\r\n\t\t\t\tvar pct = progress / totalItems;\r\n\t\t\t\tvm.gameInverseProgressStyle.push({\"width\": (100 - parseInt(pct * 100)) + \"%\"});\r\n\t\t\t\tvm.gameProgress.push(parseInt(pct * 100));\r\n\t }\r\n }\r\n\r\n $scope.$on('teacherAppServiceUpdated', function() {\r\n \tvm.updateStateFromTeacherAppService();\r\n });\r\n\r\n vm.updateStateFromTeacherAppService();\r\n }\r\n]);","app.controller('teacherAppGroupStatusDetailsCtrl', [\n '$scope', '$interval', 'gameService', 'teacherAppService', '$state', '$stateParams', '$window', '$timeout', function ($scope, $interval, gameService, teacherAppService, $state, $stateParams, $window, $timeout) {\n \tvar vm = this;\n\n \tvm.gameService = gameService;\n vm.teacherAppService = teacherAppService;\n\n\t\tvm.gameInverseProgressStyle = [];\n\t\tvm.gameProgress = [];\n\t\tvm.gameExercisePercentages = [];\n\t\tvm.gameExerciseListStyle = [];\n\n\t\tvm.exercises = [];\n\t\tvm.filterExercises = function() {\n\t\t\tvar gameState = vm.teacherAppService.gameInfo[vm.teacherAppService.currentGroup].gameState;\n\t\t\tvar game = vm.teacherAppService.gameInfo[vm.teacherAppService.currentGroup].game;\n\t\t\tfor (var i = 0; i < game.exercises.length; i++) {\n\t\t\t\tvar exercise = angular.copy(game.exercises[i]);\n\t\t\t\texercise.index = i;\n\t\t\t\tif (i < gameState.exerciseIndex) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvm.exercises.push(exercise);\n\t\t\t}\n\t\t}\n\t\tvm.filterExercises();\n\n\t\tvm.showDetails = function(idx) {\n\t\t\tvm.teacherAppService.setCurrentGroup(idx);\n\t\t\t$state.go('teacherapp.groupstatus.details', {id: idx});\n\t\t}\n\n vm.switchGroup = function(idx) {\n \tvm.teacherAppService.setCurrentGroup(idx);\n\t $state.go('.', {id: idx});\n }\n\n vm.groupPickerElement = angular.element(\".tagrouppicker\")[0];\n if (vm.groupPickerElement) {\n\t vm.groupPickerElement.addEventListener(\"scroll\", function() {\n\t \tvm.teacherAppService.groupPickerScrollOffset = vm.groupPickerElement.scrollLeft;\n\t });\n\t $timeout(function() {\n\t \t\tvm.groupPickerElement.scrollLeft = vm.teacherAppService.groupPickerScrollOffset;\n\t \t});\n\t \t}\n\n vm.goMap = function() {\n \t$state.go('teacherapp.groupstatus.detailsmap', {id: vm.teacherAppService.currentGroup}, {reload: true});\n }\n\n vm.goBack = function() {\n \t$state.go('teacherapp.groupstatus');\n }\n\n vm.goExercise = function(idx) {\n \tvar gameState = vm.teacherAppService.gameInfo[vm.teacherAppService.currentGroup].gameState;\n\t\t\tvar game = vm.teacherAppService.gameInfo[vm.teacherAppService.currentGroup].game;\n\t\t\t\n\t\t\tvm.gameService.setTeacherAppState(game, gameState);\n\n\t\t\tvar exercise = game.exercises[idx];\n\n\t\t\tif (gameState.exerciseIndex == idx) {\n\t\t\t\tif (exercise.questions.length === gameState.questionIndex) {\n\t\t\t\t\t$state.go('teacherapp.exerciseevalperform', {id: gameState.exerciseIndex, question: gameState.evaluationQuestionIndex});\n\t\t\t\t} else {\n\t\t\t\t\t$state.go('teacherapp.exerciseperform', {id: gameState.exerciseIndex, question: gameState.questionIndex});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$state.go('teacherapp.exercisepeform', {id: idx, qeustion: 0});\n\t\t\t}\n\t\t}\n\n\t\tfunction countGameStateProgress(gameInfo) {\n\t\t\tvar gameState = gameInfo.gameState;\n\t\t\tvar game = gameInfo.game;\n\n\t\t\tvar count = 0;\n\t\t\tfor (var i = 0; i < game.exercises.length; i++) {\n\t\t\t\tif (i == gameState.exerciseIndex) {\n\t\t\t\t\tcount += gameState.questionIndex;\n\t\t\t\t\tcount += gameState.evaluationQuestionIndex;\n\t\t\t\t\treturn count;\n\t\t\t\t}\n\t\t\t\tvar exercise = game.exercises[i];\n\t\t\t\tcount += exercise.questions.length;\n\t\t\t\tcount += exercise.evaluationQuestions.length;\n\t\t\t}\n\t\t\treturn count;\n\t\t}\n\n\t\tfunction countTotalItemsForGameInfo(gameInfo) {\n\t\t\tvar game = gameInfo.game;\n\t\t\tvar totalItems = 0;\n\t\t\tfor (var i = 0; i < game.exercises.length; i++) {\n\t\t\t\tvar exercise = game.exercises[i];\n\n\t\t\t\tvar nitems = 0;\n\t\t\t\tnitems += exercise.questions.length;\n\t\t\t\tnitems += exercise.evaluationQuestions.length;\n\n\t\t\t\ttotalItems += nitems;\n\t\t\t}\n\t\t\treturn totalItems;\n\t\t}\n\n\t\tfunction itemsPerExerciseForGameInfo(gameInfo) {\n\t\t\tvar game = gameInfo.game;\n\t\t\tvar itemsPerExercise = [];\n\t\t\tfor (var i = 0; i < game.exercises.length; i++) {\n\t\t\t\tvar exercise = game.exercises[i];\n\n\t\t\t\tvar nitems = 0;\n\t\t\t\tnitems += exercise.questions.length;\n\t\t\t\tnitems += exercise.evaluationQuestions.length;\n\t\t\t\titemsPerExercise.push(nitems);\n\t\t\t}\n\t\t\treturn itemsPerExercise;\n\t\t}\n\n\t\tfunction percentagePerExerciseForGameInfo(gameInfo) {\n\t\t\tvar itemsPerExercise = itemsPerExerciseForGameInfo(gameInfo);\n\n\t\t\tvar totalItems = 0;\n\t\t\tfor (var i = 0; i < itemsPerExercise.length; i++) {\n\t\t\t\ttotalItems += itemsPerExercise[i];\n\t\t\t}\n\n\t\t\tvar percentagePerExercise = [];\n\t\t\tfor (var i = 0; i < itemsPerExercise.length; i++) {\n\t\t\t\tpercentagePerExercise.push(itemsPerExercise[i] / totalItems);\n\t\t\t}\n\n\t\t\treturn percentagePerExercise;\n\t\t}\n\n\t\tvm.updateStateFromTeacherAppService = function() {\n\t\t\tif (!teacherAppService.isReady()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvm.gameInverseProgressStyle = [];\n\t\t\tvm.gameProgress = [];\n\t\t\tvm.gameExercisePercentages = [];\n\t\t\tvm.gameExerciseListStyle = [];\n\t\t\tvar gameInfo = vm.teacherAppService.gameInfo;\n\t\t\tfor (var i = 0; i < gameInfo.length; i++) {\n\t\t\t\tvar gi = gameInfo[i];\n\t\t\t\tvar totalItems = countTotalItemsForGameInfo(gi);\n\t\t\t\tvar progress = countGameStateProgress(gi);\n\t\t\t\tvar pct = progress / totalItems;\n\t\t\t\tvar gameExercisePercentage = percentagePerExerciseForGameInfo(gi);\n\t\t\t\tvm.gameInverseProgressStyle.push({\"width\": (100 - parseInt(pct * 100)) + \"%\"});\n\t\t\t\tvm.gameProgress.push(parseInt(pct * 100));\n\n\t\t\t\tvm.gameExercisePercentages.push(gameExercisePercentage);\n\n\t\t\t\tvar styles = [];\n\t\t\t\tfor (var j = 0; j < gameExercisePercentage.length; j++) {\n\t\t\t\t\tvar exercisePercentage = gameExercisePercentage[j];\n\t\t\t\t\tvar style = { \"flex\": \"\" + exercisePercentage, \"msFlex\": \"\" + exercisePercentage };\n\t\t\t\t\tstyles.push(style);\n\t\t\t\t}\n\n\t\t\t\tvm.gameExerciseListStyle.push(styles);\n\t\t\t}\n\t\t}\n\n $scope.$on('teacherAppServiceUpdated', function() {\n \tvm.updateStateFromTeacherAppService();\n });\n\n vm.updateStateFromTeacherAppService();\n\n // ---- MAP ----\n\n if ($window.location.href.indexOf(\"detailsmap\") !== -1) {\n \t$timeout(function() {\n\t\t\t\tvm.curPos = [0.0, 0.0];\n\n\t\t \tvm.map = new maptalks.Map('maptalksc', {\n\t\t \tcenter: vm.gameService.config.mapCenter,\n\t\t \tzoom: 16.64,\n\t\t \tbearing: 150.0,\n\t\t \tattribution: false,\n\n\t\t\t //allow map to drag pitching, true by default\n\t\t \tdragPitch : false,\n\t\t \t//allow map to drag rotating, true by default\n\t\t \tdragRotate : true,\n\t\t \t//enable map to drag pitching and rotating at the same time, false by default\n\t\t \tdragRotatePitch : false,\n\n\t\t \tbaseLayer: new maptalks.TileLayer('base', {\n\t\t \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n\t\t \t\tsubdomains: ['a','b','c','d'],\n\t\t \t\tattribution: ''\n\t\t \t})\n\t\t \t});\n\n\t\t\t\tvar center = vm.map.getCenter();\n\t\t\t\tvar layer = new maptalks.VectorLayer('vector').addTo(vm.map);\n\n\t\t\t\tvm.rideMarkers = {};\n\t\t for (var i = 0; i < vm.gameService.rides.length; i++) {\n\t\t var ride = vm.gameService.rides[i];\n\n\t\t if (ride.enabled) {\n\t\t var marker = new maptalks.Marker(ride.location, {\n\t\t 'symbol' : {\n\t\t 'markerFile' : ride.markerImage,\n\t\t 'markerWidth' : ride.markerWidth,\n\t\t 'markerHeight' : ride.markerHeight,\n\t\t 'markerDx' : 0,\n\t\t 'markerDy' : 0,\n\t\t 'markerOpacity': 1\n\t\t }\n\t\t });\n\t\t vm.rideMarkers[ride.key] = marker;\n\t\t marker.addTo(layer);\n\t\t }\n\t\t }\n\n\t\t vm.gameMarker = undefined;\n\t\t vm.createGameMarker = function() {\n\t\t \tif (vm.gameMarker) {\n\t\t \t\treturn;\n\t\t \t}\n\t\t \tvar gameInfos = vm.teacherAppService.gameInfo;\n\t\t \tvar i = $stateParams.id;\n\t var gameInfo = gameInfos[i];\n\t var marker = new maptalks.Marker(gameInfo.locationState.lastLocation, {\n\t 'symbol' : {\n\t 'markerFile' : window.location.origin + '/img/map/MapPin' + (i + 1) + '.svg',\n\t 'markerWidth' : 2*22,\n\t 'markerHeight' : 2*35.5,\n\t 'markerDx' : 0,\n\t 'markerDy' : 0,\n\t 'markerOpacity': 1\n\t }\n\t });\n\t marker.addTo(layer);\n\t vm.gameMarker = marker;\n\t\t }\n\n\t\t vm.updateMarkerLocations = function() {\n\t\t vm.createGameMarker();\n\n\t\t var gameInfos = vm.teacherAppService.gameInfo;\n\t\t var i = $stateParams.id;\n\t var gameInfo = gameInfos[i];\n\t var teamNumber = i + 1;\n\t var marker = vm.gameMarkers[i];\n\t marker.setCoordinates(gameInfo.locationState.lastLocation);\n\t\t }\n\n\t\t $scope.$on('teacherAppServiceUpdated', function(gameInfo) {\n\t\t vm.updateMarkerLocations();\n\t\t });\n\t\t\t});\n }\n }\n]);","app.controller('teacherAppGroupStatusDetailsMapCtrl', [\n '$scope', '$interval', 'gameService', 'teacherAppService', '$state', '$stateParams', '$window', '$timeout', function ($scope, $interval, gameService, teacherAppService, $state, $stateParams, $window, $timeout) {\n \tvar vm = this;\n\n \tvm.gameService = gameService;\n vm.teacherAppService = teacherAppService;\n\n\t\tvm.gameInverseProgressStyle = [];\n\t\tvm.gameProgress = [];\n\n vm.groupPickerElement = angular.element(\".tagrouppicker\")[0];\n if (vm.groupPickerElement) {\n\t vm.groupPickerElement.addEventListener(\"scroll\", function() {\n\t \tvm.teacherAppService.groupPickerScrollOffset = vm.groupPickerElement.scrollLeft;\n\t });\n\t $timeout(function() {\n\t \t\tvm.groupPickerElement.scrollLeft = vm.teacherAppService.groupPickerScrollOffset;\n\t \t});\n\t \t}\n\n\t\tvm.switchGroup = function(idx) {\n\t\t\tvm.teacherAppService.setCurrentGroup(idx);\n\t\t\t$state.go('.', {id: idx});\n\t\t}\n\n vm.goBack = function() {\n \t$state.go('teacherapp.groupstatus.details', {id: $stateParams.id});\n }\n\n function countGameStateProgress(gameState) {\n\t\t\tvar count = 0;\n\t for (var i = 0; i < gameService.exercises.length; i++) {\n\t \tif (i == gameState.exerciseIndex) {\n\t\t \t\tcount += gameState.questionIndex;\n\t\t \t\tcount += gameState.evaluationQuestionIndex;\n\t\t \t\treturn count;\n\t \t}\n\t\t\t\tvar exercise = gameService.exercises[i];\n\t\t\t\tcount += exercise.questions.length;\n\t\t\t\tcount += exercise.evaluationQuestions.length;\n\t }\n\t return count;\n }\n\n vm.updateStateFromTeacherAppService = function() {\n\t\t\tif (!teacherAppService.isReady()) {\n\t\t\t\treturn;\n\t\t\t}\n\n \t\tvar totalItems = 0;\n\t for (var i = 0; i < gameService.exercises.length; i++) {\n\t \tvar exercise = gameService.exercises[i];\n\t \ttotalItems += exercise.questions.length;\n\t \ttotalItems += exercise.evaluationQuestions.length;\n\t }\n\n\t vm.gameInverseProgressStyle = [];\n\t vm.gameProgress = [];\n\t var gameInfo = vm.teacherAppService.gameInfo;\n\t for (var i = 0; i < gameInfo.length; i++) {\n\t \tvar gi = gameInfo[i];\n\t \tvar gameState = gi.gameState;\n\t\t\t\tvar progress = countGameStateProgress(gameState);\n\t\t\t\tvar pct = progress / totalItems;\n\t\t\t\tvm.gameInverseProgressStyle.push({\"width\": (100 - parseInt(pct * 100)) + \"%\"});\n\t\t\t\tvm.gameProgress.push(parseInt(pct * 100));\n\t }\n }\n\n\t\tvm.curPos = [0.0, 0.0];\n\n \tvm.map = new maptalks.Map('maptalksc', {\n \tcenter: vm.gameService.config.mapCenter,\n \tzoom: 16.64,\n \tbearing: 150.0,\n \tattribution: false,\n\n\t //allow map to drag pitching, true by default\n \tdragPitch : false,\n \t//allow map to drag rotating, true by default\n \tdragRotate : true,\n \t//enable map to drag pitching and rotating at the same time, false by default\n \tdragRotatePitch : false,\n\n \tbaseLayer: new maptalks.TileLayer('base', {\n \t\turlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n \t\tsubdomains: ['a','b','c','d'],\n \t\tattribution: ''\n \t})\n \t});\n\n\t\tvar center = vm.map.getCenter();\n\t\tvar layer = new maptalks.VectorLayer('vector').addTo(vm.map);\n\n\t\tvm.rideMarkers = {};\n for (var i = 0; i < vm.gameService.rides.length; i++) {\n var ride = vm.gameService.rides[i];\n\n if (ride.enabled) {\n var marker = new maptalks.Marker(ride.location, {\n 'symbol' : {\n 'markerFile' : ride.markerImage,\n 'markerWidth' : ride.markerWidth,\n 'markerHeight' : ride.markerHeight,\n 'markerDx' : 0,\n 'markerDy' : 0,\n 'markerOpacity': 1\n }\n });\n vm.rideMarkers[ride.key] = marker;\n marker.addTo(layer);\n }\n }\n\n vm.gameMarker = undefined;\n vm.createGameMarker = function() {\n \tif (vm.gameMarker) {\n \t\treturn;\n \t}\n \tvar gameInfos = vm.teacherAppService.gameInfo;\n \tvar i = $stateParams.id;\n var gameInfo = gameInfos[i];\n var marker = new maptalks.Marker(gameInfo.locationState.lastLocation, {\n 'symbol' : {\n 'markerFile' : window.location.origin + '/img/map/MapPin' + (i + 1) + '.svg',\n 'markerWidth' : 2*22,\n 'markerHeight' : 2*35.5,\n 'markerDx' : 0,\n 'markerDy' : 0,\n 'markerOpacity': 1\n }\n });\n marker.addTo(layer);\n vm.gameMarker = marker;\n }\n\n vm.updateMarkerLocations = function() {\n vm.createGameMarker();\n\n var gameInfos = vm.teacherAppService.gameInfo;\n var i = $stateParams.id;\n var gameInfo = gameInfos[i];\n var teamNumber = i + 1;\n \tvm.gameMarker.setCoordinates(gameInfo.locationState.lastLocation);\n }\n\n $scope.$on('teacherAppServiceUpdated', function() {\n \tvm.updateMarkerLocations();\n \tvm.updateStateFromTeacherAppService();\n });\n\n vm.updateMarkerLocations();\n vm.updateStateFromTeacherAppService();\n }\n]);","app.controller('teacherAppMessagesCtrl', [\r\n '$scope', '$interval', '$state', '$stateParams', 'messageService', function ($scope, $interval, $state, $stateParams, messageService) {\r\n \tvar vm = this;\r\n\r\n\t\tvm.messageService = messageService;\r\n\r\n\t\tvm.messages = angular.copy(vm.messageService.messages);\r\n\t\tvm.messageText = \"\";\r\n\r\n \t$scope.$on('messageServiceUpdated', function() {\r\n\t\t\tconsole.log(\"teacherAppMessagesCtrl: sync'd messages with messageService\");\r\n\t\t\tvm.messages = angular.copy(vm.messageService.messages);\r\n \t});\r\n\r\n \tvm.sendMessage = function() {\r\n \t\tif (vm.messageText.length == 0) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tvar msgObj = {\r\n \t\t\tfrom: \"Lærer\",\r\n \t\t\ttimestmap: parseInt((new Date()).getTime() / 1000.0), // current unix timestamp\r\n \t\t\ttext: vm.messageText\r\n \t\t};\r\n\r\n \t\tvm.messageService.sendMessage(msgObj).then(function() {\r\n \t\t\tvm.messageText = \"\";\r\n \t\t}, function() {\r\n \t\t\tvm.messageText = \"\";\r\n \t\t});\r\n \t}\r\n\t}\r\n]);\r\n","app.controller('teacherAppWelcomeCtrl', [\r\n '$scope', '$rootScope', '$http', '$state', 'teacherAppService', function ($scope, $rootScope, $http, $state, teacherAppService) {\r\n var vm = this;\r\n\r\n var temporaryConfigNoRealTeacherName = false;\r\n\r\n vm.teacherName = \"LÆRER\";\r\n if (!temporaryConfigNoRealTeacherName) {\r\n var tn = teacherAppService.gameDayInfo.teacherName;\r\n if (tn != null && tn != \"\") {\r\n vm.teacherName = tn.toUpperCase();\r\n }\r\n }\r\n\r\n vm.showPlaceHolder = true;\r\n\r\n\t\tvm.isPlaying = false;\r\n vm.playVideo = function() {\r\n var video = $(\".w3video\")[0];\r\n if (vm.showPlaceHolder) {\r\n vm.showPlaceHolder = false;\r\n video.play();\r\n vm.isPlaying = true;\r\n } else {\r\n if (vm.isPlaying) {\r\n video.pause();\r\n vm.isPlaying = false;\r\n } else {\r\n video.play();\r\n vm.isPlaying = true;\r\n }\r\n }\r\n }\r\n\r\n vm.next = function() {\r\n \t$state.go('teacherapp.groupstatus');\r\n }\r\n }\r\n]);\r\n"]}