text:   // our current position
    var positionCurrent = {
      lat: null,
      lng: null,
      hng: null
    };
  
  
  (function () {
    "use strict";
  
    //set to true for debugging output
    var debug = false;
  
    // the outer part of the compass that rotates
    var rose = document.getElementById("rose");
  
    // elements that ouput our position
    var positionLat = document.getElementById("position-lat");
    var positionLng = document.getElementById("position-lng");
    var positionHng = document.getElementById("position-hng");
  
    // debug outputs
    var debugOrientation = document.getElementById("debug-orientation");
    var debugOrientationDefault = document.getElementById("debug-orientation-default");
  
    // info popup elements, pus buttons that open popups
    var popup = document.getElementById("popup");
    var popupContents = document.getElementById("popup-contents");
    var popupInners = document.querySelectorAll(".popup__inner");
    var btnsPopup = document.querySelectorAll(".btn-popup");
  
    // buttons at the bottom of the screen
    //var btnLockOrientation = document.getElementById("btn-lock-orientation");
    var btnNightmode = document.getElementById("btn-nightmode");
    var btnMap = document.getElementById("btn-map");
    var btnInfo = document.getElementById("btn-info");
    var btnDecUP = document.getElementById("btn-decUP");
    var btnDecDN = document.getElementById("btn-decDN");
  
  
    // if we have shown the heading unavailable warning yet
    var warningHeadingShown = false;
  
  
    // switches keeping track of our current app state
    var isOrientationLockable = false;
    var isOrientationLocked = false;
    var isNightMode = false;
  
  
    // the orientation of the device on app load
    var defaultOrientation;
  
    // set magnetic declination
    var declination_offset = document.getElementById("declination-val");
  
    // browser agnostic orientation
    function getBrowserOrientation() {
      var orientation;
      if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
      } else {
        orientation = screen.orientation ||
                      screen.mozOrientation ||
                      screen.msOrientation;
      }
  
      /*
        'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
                                  device is in 'normal' orientation
                                for (screen width > screen height, e.g. large tablet, laptop)
                                  device has been turned 90deg clockwise from normal
  
        'portait-secondary':    for (screen width < screen height)
                                  device has been turned 180deg from normal
                                for (screen width > screen height)
                                  device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
  
        'landscape-primary':    for (screen width < screen height)
                                  device has been turned 90deg clockwise from normal
                                for (screen width > screen height)
                                  device is in 'normal' orientation
  
        'landscape-secondary':  for (screen width < screen height)
                                  device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
                                for (screen width > screen height)
                                  device has been turned 180deg from normal
      */
  
      return orientation;
    }
  
  
    // browser agnostic orientation unlock
    function browserUnlockOrientation() {
      if (screen.orientation && screen.orientation.unlock) {
        screen.orientation.unlock();
      } else if (screen.unlockOrientation) {
        screen.unlockOrientation();
      } else if (screen.mozUnlockOrientation) {
        screen.mozUnlockOrientation();
      } else if (screen.msUnlockOrientation) {
        screen.msUnlockOrientation();
      }
    }
  
  
    // browser agnostic document.fullscreenElement
    function getBrowserFullscreenElement() {
      if (typeof document.fullscreenElement !== "undefined") {
        return document.fullscreenElement;
      } else if (typeof document.webkitFullscreenElement !== "undefined") {
        return document.webkitFullscreenElement;
      } else if (typeof document.mozFullScreenElement !== "undefined") {
        return document.mozFullScreenElement;
      } else if (typeof document.msFullscreenElement !== "undefined") {
        return document.msFullscreenElement;
      }
    }
  
  
    // browser agnostic document.documentElement.requestFullscreen
    function browserRequestFullscreen() {
      if (document.documentElement.requestFullscreen) {
        document.documentElement.requestFullscreen();
      } else if (document.documentElement.webkitRequestFullscreen) {
        document.documentElement.webkitRequestFullscreen();
      } else if (document.documentElement.mozRequestFullScreen) {
        document.documentElement.mozRequestFullScreen();
      } else if (document.documentElement.msRequestFullscreen) {
        document.documentElement.msRequestFullscreen();
      }
    }
  
  
    // browser agnostic document.documentElement.exitFullscreen
    function browserExitFullscreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
    }
  
  
    // called on device orientation change
    function onHeadingChange(event) {
      var heading;
  
      if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
      } else {
        heading = event.alpha; 
      }
  
      var orientation = getBrowserOrientation();
  
      if (typeof heading !== "undefined" && heading !== null) { // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation
  
        if (debug) {
          debugOrientation.textContent = orientation;
        }
  
        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
          adjustment -= 90;
        }
  
        if (typeof orientation !== "undefined") {
          var currentOrientation = orientation.split("-");
  
          if (defaultOrientation !== currentOrientation[0]) {
            if (defaultOrientation === "landscape") {
              adjustment -= 270;
            } else {
              adjustment -= 90;
            }
          }
  
          if (currentOrientation[1] === "secondary") {
            adjustment -= 180;
          }
        }
  
        positionCurrent.hng = heading + adjustment;
  
        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        positionHng.textContent = (360 - phase | 0) + "°";
  
        // apply rotation to compass pointer
        if (typeof pointer.style.transform !== "undefined") {
          pointer.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof pointer.style.webkitTransform !== "undefined") {
          pointer.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        
        // make sure the pointer is displayed if a heading is available
        //var pointer = document.getElementById("pointer");
        pointer.style.display = 'initial';
      } else {
        // device can't show heading
  
        positionHng.textContent = "n/a";
        //var pointer = document.getElementById("pointer");
        pointer.style.display = 'none';
        //showHeadingWarning();
      }
    }
  
    function setDeclinationOffsetUP() {
      declination_offset.textContent++;
      setDeclinationOffset();
    }
    function setDeclinationOffsetDN() {
      declination_offset.textContent--;
      setDeclinationOffset();
    }
    function setDeclinationOffset() {
  
      // apply magnetic declination
      if (typeof declination.style.transform !== "undefined") {
        declination.style.transform = "rotateZ(" + declination_offset.textContent + "deg)";
      } else if (typeof declination.style.webkitTransform !== "undefined") {
        declination.style.webkitTransform = "rotateZ(" + declination_offset.textContent + "deg)";
      }
  }
  
    function showHeadingWarning() {
      if (!warningHeadingShown) {
        popupOpen("noorientation");
        warningHeadingShown = true;
      }
    }
  
    function onFullscreenChange() {
      if (isOrientationLockable && getBrowserFullscreenElement()) {
        if (screen.orientation && screen.orientation.lock) {
          screen.orientation.lock(getBrowserOrientation()).then(function () {
          }).catch(function () {
          });
        }
      } else {
        lockOrientationRequest(false);
      }
    }
  
    function toggleOrientationLockable(lockable) {
      isOrientationLockable = lockable;
  
      //if (isOrientationLockable) {
      //  btnLockOrientation.classList.remove("btn--hide");
      //} else {
      //  btnLockOrientation.classList.add("btn--hide");
      //}
    }
  
    function checkLockable() {
      if (screen.orientation && screen.orientation.lock) {
        screen.orientation.lock(getBrowserOrientation()).then(function () {
          toggleOrientationLockable(true);
          browserUnlockOrientation();
        }).catch(function (event) {
          if (event.code === 18) { // The page needs to be fullscreen in order to call lockOrientation(), but is lockable
            toggleOrientationLockable(true);
            browserUnlockOrientation(); //needed as chrome was locking orientation (even if not in fullscreen, bug??)
          } else {  // lockOrientation() is not available on this device (or other error)
            toggleOrientationLockable(false);
          }
        });
      } else {
        toggleOrientationLockable(false);
      }
    }
  
    function lockOrientationRequest(doLock) {
      if (isOrientationLockable) {
        if (doLock) {
          browserRequestFullscreen();
          lockOrientation(true);
        } else {
          browserUnlockOrientation();
          browserExitFullscreen();
          lockOrientation(false);
        }
      }
    }
  
    function lockOrientation(locked) {
      //if (locked) {
      //  btnLockOrientation.classList.add("active");
      //} else {
      //  btnLockOrientation.classList.remove("active");
      //}
  
      isOrientationLocked = locked;
    }
  
    function toggleOrientationLock() {
      if (isOrientationLockable) {
        lockOrientationRequest(!isOrientationLocked);
      }
    }
  
    function locationUpdate(position) {
      positionCurrent.lat = position.coords.latitude;
      positionCurrent.lng = position.coords.longitude;
  
      positionLat.textContent = decimalToSexagesimal(positionCurrent.lat, "lat");
      positionLng.textContent = decimalToSexagesimal(positionCurrent.lng, "lng");
    }
  
    function locationUpdateFail(error) {
      positionLat.textContent = "n/a";
      positionLng.textContent = "n/a";
      console.log("location fail: ", error);
    }
  
    function setNightmode(on) {
  
      if (on) {
        btnNightmode.classList.add("active");
      } else {
        btnNightmode.classList.remove("active");
      }
  
      window.setTimeout(function() {
        if (on) {
          document.documentElement.classList.add("nightmode");
        } else {
          document.documentElement.classList.remove("nightmode");
        }
      }, 1);
  
  
      isNightMode = on;
    }
  
    function toggleNightmode() {
      setNightmode(!isNightMode);
    }
  
    function openMap() {
      window.open("https://www.google.com/maps/place/@" + positionCurrent.lat + "," + positionCurrent.lng + ",16z", "_blank");
    }
  
    function popupOpenFromClick(event) {
      popupOpen(event.currentTarget.dataset.name);
    }
  
    function popupOpen(name) {
      var i;
      for (i=0; i<popupInners.length; i++) {
        popupInners[i].classList.add("popup__inner--hide");
      }
      document.getElementById("popup-inner-" + name).classList.remove("popup__inner--hide");
  
      popup.classList.add("popup--show");
    }
  
    function popupClose() {
      popup.classList.remove("popup--show");
    }
  
    function popupContentsClick(event) {
      event.stopPropagation();
    }
  
    function decimalToSexagesimal(decimal, type) {
      var degrees = decimal | 0;
      var fraction = Math.abs(decimal - degrees);
      var minutes = (fraction * 60) | 0;
      var seconds = (fraction * 3600 - minutes * 60) | 0;
  
      var direction = "";
      var positive = degrees > 0;
      degrees = Math.abs(degrees);
      switch (type) {
        case "lat":
          direction = positive ? "N" : "S";
          break;
        case "lng":
          direction = positive ? "E" : "W";
          break;
      }
  
      return degrees + "° " + minutes + "' " + seconds + "\" " + direction;
    }
  
  
  
    if (screen.width > screen.height) {
      defaultOrientation = "landscape";
    } else {
      defaultOrientation = "portrait";
    }
    if (debug) {
      debugOrientationDefault.textContent = defaultOrientation;
    }
  
    window.addEventListener("deviceorientationabsolute", onHeadingChange);
  
    document.addEventListener("fullscreenchange", onFullscreenChange);
    document.addEventListener("webkitfullscreenchange", onFullscreenChange);
    document.addEventListener("mozfullscreenchange", onFullscreenChange);
    document.addEventListener("MSFullscreenChange", onFullscreenChange);
  
    //btnLockOrientation.addEventListener("click", toggleOrientationLock);
    btnNightmode.addEventListener("click", toggleNightmode);
    btnMap.addEventListener("click", openMap);
  
    btnDecDN.addEventListener("click", setDeclinationOffsetDN);
    btnDecUP.addEventListener("click", setDeclinationOffsetUP);
  
    var i;
    for (i=0; i<btnsPopup.length; i++) {
      btnsPopup[i].addEventListener("click", popupOpenFromClick);
    }
  
    popup.addEventListener("click", popupClose);
    popupContents.addEventListener("click", popupContentsClick);
  
    navigator.geolocation.watchPosition(locationUpdate, locationUpdateFail, {
      enableHighAccuracy: false,
      maximumAge: 30000,
      timeout: 27000
    });
  
    setDeclinationOffset();
    setNightmode(false);
    checkLockable();
  
  }());
  
  
  