<commit_before>/* ----------------- My maps edition ------------------- */

function setMapItemVisibility(elt, props) {
  //var isVisible = e.target.getAttribute("isVisible") == "true";
  var isVisible = props.on;
  elt.attr("isVisible", "" + isVisible);
  elt.text(isVisible ? "visibility" : "visibility_off");
  var parent = elt.parent(".map-item");
  if (isVisible && parent.length) {
    parent.removeClass("map-invisible");
  } else {
    parent.addClass("map-invisible");
  }
}

function addMymapsItem(name, props, addHandlers) {
  var mapitem = "
";
  mapitem += "drag_indicator ";
  mapitem += "" + name + " ";
  mapitem += "?? ";
  if (props.in == MAP_MY) {
    mapitem += "create ";
    mapitem += "share ";
    mapitem += "delete ";
  }
  mapitem += "
";
  $("#mymaps-list").append(mapitem);
  var newitem = $("#mymaps-list").children().last();
  setMapItemVisibility(newitem.find(".map-visibility"), props);
  if (addHandlers) {
    addMapItemHandlers(newitem);
  }
}

function getMapName(elt) {
  return elt.parentNode.querySelector(".map-name").innerText;
}

function getMapProps(elt) {
  var name = getMapName(elt);
  var idx = mapsListNames.indexOf(name);
  return mapsListProps[idx];
}

function getMapItem(name) {
  var res = undefined;
  $("#mymaps-list .map-name").each(function(i, v) {
    if (name == v.innerText) {
      res = $(v).parents("li");
      return true;
    }
  });
  return res;
}

function changeMymapsItem(oldname, newname) {
  var mapItem = getMapItem(oldname);
  if (mapItem) {
    if (newname) {
      // name changed
      mapItem.find(".map-name").text(newname);
    } else {
      // item deleted
      mapItem.remove();
    }
  }
}

function showMapsList() {
  $("#mymaps-list").empty();
  mapsForEach(function(name, value) {
    addMymapsItem(name, value);
  });
  addMapItemHandlers($('#mymaps-list li'));
}

function toggleMapVisibility(e) {
  var mprops = getMapProps(e.target);
  mprops.on = !mprops.on;
  ga('send', 'event', 'map', 'visibility');
  saveMapList();
  setMapItemVisibility($(e.target), mprops)
}

function editMapItem(e) {
  var name = getMapName(e.target);
  editMymap(name);
}
function deleteMapItem(e) {
  var name = getMapName(e.target);
  deleteMymap(name);
}
function shareMapItem(e) {
  var name = getMapName(e.target);
  openExportMymaps(null, name);
}

function addMapItemHandlers(selector) {
  selector.find(".map-edit").click(editMapItem);
  selector.find(".map-visibility").click(toggleMapVisibility);
  selector.find(".map-delete").click(deleteMapItem);
  selector.find(".map-share").click(shareMapItem);
}

// ----------------------- Personal map edition ----------------------

var mymap;

function initCrsSelector() {
  var crsSelect = $("#mymap-crs")[0];
  for (var i = CrsValues.length - 1; i >=0; i--) {
    var crs = CrsValues[i];
    addSelectOption(crsSelect, crs ? crs.code : "");
  }
}
initCrsSelector();

function openMymapBox() {
  $("#mymap-name").val(mymap.name);
  $("#mymap-url").val(mymap.url);
  $("#mymap-minz").val(mymap.options.minZoom);
  $("#mymap-maxz").val(mymap.options.maxZoom);
  $("#mymap-layers").val(mymap.options.layers);
  $("#mymap-layer").val(mymap.options.layer);
  $("#mymap-tilematrixSet").val(mymap.options.tilematrixSet);
  $("#mymap-crs").val(mymap.options.crs);
  $("#mymap-styles").val(mymap.options.styles);
  $("#mymap-style").val(mymap.options.style);
  $("#mymap-format").val(mymap.options.format);
  $("#mymap-attr").val(mymap.options.attribution);
  $("#mymap-box input:radio[name=mymap-type][value=" + mymap.type + "]").prop('checked', true);
  $("#mymap-box").show();
  $("#mymap-name").focus();
  changeMymapType();
}

function newMymap(evt) {
  mymap = { options: {} };
  openMymapBox();
}

function editMymap(mymapname) {
  if (mymapname) {
    mymap = mymaps[mymapname];
    if (mymap) {
      mymap.name = mymapname;
      openMymapBox();
    }
  }
}

var mymapsInputs = $("#mymap-box input");
mymapsInputs.on("invalid", function(evt) {
  var invalidInput = $(evt.target);
  invalidInput.addClass("invalid");
  invalidInput.focus();
});
mymapsInputs.on("input", function(evt) {
  if (evt.target.checkValidity()) {
    $(evt.target).removeClass("invalid");
  }
});

mymapsInputs.keyup(function(event) {
  if (event.which == 27) {
    cancelMymapBox();
    event.stopPropagation();
  } else if (event.keyCode == 13) {
    validateMymapBox();
  }
});

function validateMymapBox(evt) {
  var valid = true;
  // check validity on displayed inputs
  $("#mymap-box input:visible").each(function(i, v) {
    var display = $(v).css('display');
    if ((display != "none") && (!v.checkValidity())) {
      valid = false;
      return false;
    }
  });
  var oldname = mymap.name;
  var newname = $("#mymap-name").val().trim();
  if ((oldname != newname) && (getMapListEntryIndex(newname) >= 0)) {
    $("#mymap-name").trigger("invalid");
    warn("Map name already used: " + newname);
    valid = false;
  }
  if (valid) {
    //mymapsInputs.removeClass("invalid");
    $("#mymap-box").hide();
    mymap[name] = undefined;
    mymap.url = $("#mymap-url").val().trim();
    mymap.type = $('input:radio[name=mymap-type]:checked').val();
    mymap.options.minZoom= $("#mymap-minz").val().trim();
    mymap.options.maxZoom = $("#mymap-maxz").val().trim();
    if (mymap.type === "wms") {
      mymap.options.layers = $("#mymap-layers").val().trim();
      mymap.options.crs = $("#mymap-crs").val().trim();
      mymap.options.styles = $("#mymap-styles").val().trim();
      mymap.options.format = $("#mymap-format").val().trim();
    } else if (mymap.type === "wmts") {
      mymap.options.layer = $("#mymap-layer").val().trim();
      mymap.options.tilematrixSet = $("#mymap-tilematrixSet").val().trim();
      mymap.options.style = $("#mymap-style").val().trim();
      mymap.options.format = $("#mymap-format").val().trim();
    }
    mymap.options.attribution = $("#mymap-attr").val().trim();
    if (oldname && mymaps[oldname]) {
      if (oldname != newname) {
        // rebuild object to preserve order
        var tmp = {};
        objectForEach(mymaps, function(name, value) {
          if (name == oldname) {
            tmp[newname] = mymap;
          } else {
            tmp[name] = value;
          }
        });
        mymaps = tmp;
        renameMapListEntry(oldname, newname);
        changeMymapsItem(oldname, newname);
        saveMapList();
      } else {
        mymaps[newname] = mymap;
      }
      ga('send', 'event', 'map', 'edit');
    } else {
      mymaps[newname] = mymap;
      addMymapsItem(newname, addMapListEntry(newname, MAP_MY, true), true);
      saveMapList();
      ga('send', 'event', 'map', 'add');
    }
    saveJsonValOpt("wt.mymaps", mymaps);
  }
}

function cancelMymapBox(evt) {
  $("#mymap-box").hide();
  mymapsInputs.removeClass("invalid");
  mymap = undefined;
}

function deleteMymap(mymapname) {
  if (mymapname) {
    mymap = mymaps[mymapname];
    if (mymap && confirm("Delete " + mymapname + "?")) {
      mymaps[mymapname] = undefined;
      saveJsonValOpt("wt.mymaps", mymaps);
      // delete map in lists
      delMapListEntry(getMapListEntryIndex(mymapname));
      changeMymapsItem(mymapname);
      saveMapList();
      ga('send', 'event', 'map', 'delete');
    }
  }
}

function changeMymapType(evt) {
  var type =  $('input:radio[name=mymap-type]:checked').val();
  $(".map-wmts").hide();
  $(".map-wms").hide();
  if (type != "base") {
    $(".map-" + type).show();
  }
}

function deleteAllMymaps(evt) {
  if (!$.isEmptyObject(mymaps) &&
      confirm("Delete all your personal maps?")) {
    mymaps = {};
    saveJsonValOpt("wt.mymaps", undefined);
    ga('send', 'event', 'map', 'deleteall');
    getMapList();
    showMapsList()
  }
}
function reorderMapList(evt) {
  if (confirm("Re-order map list according to defaults, with personal maps at the end?")) {
    ga('send', 'event', 'map', 'reorder');
    resetMapList();
    getMapList();
    showMapsList();
  }
}

$("#mymap-ok").click(validateMymapBox);
$("#mymap-cancel").click(cancelMymapBox);

$("#mymaps-new").click(newMymap);
$("#mymaps-deleteall").click(deleteAllMymaps);

$("#maps-reorder").click(reorderMapList);
$("input:radio[name=mymap-type]").change(changeMymapType);

// ---------------- Import / export my maps

function openExportMymaps(evt, mymapname) {
  var toexport = mymapname ? { mymapname : mymaps[mymapname] } : mymaps;
  if (!$.isEmptyObject(toexport)) {
    var json = JSON.stringify(toexport);
    var data = b64EncodeUnicode(json);
    $("#input-text").text("Copy and share map data below (Ctrl+C & Enter):");
    $("#input-ok").hide();
    $("#input-val").val(data);
    $("#input-box").show();
    $("#input-val").focus();
    $("#input-val").select();
    $("#input-val").attr("readonly", "readonly");
    $(".prompt-content .copyonclick").show();
    ga('send', 'event', 'map', 'export', undefined, mymapname ? 1 : mymaps.length);
  }
}

function openImportMymaps() {
  $("#input-text").text("Paste exported map data (Ctrl+V & Enter):");
  $("#input-val").val("");
  $("#input-ok").show();
  $("#input-box").show();
  $("#input-val").removeAttr("readonly");
  $(".prompt-content .copyonclick").hide();
  $("#input-val").focus();
}

function importMymaps() {
  var imported = 0;
  try {
    var data = $("#input-val").val().trim();
    var importedMymaps = data ? JSON.parse(b64DecodeUnicode(data)) : {};
    objectForEach(importedMymaps, function(name, value) {
      var overwrite = mymaps[name];
      var msg = overwrite ? "Overwrite " : "Import ";
      if (confirm(msg + name + "?")) {
        if (overwrite) {
          // useless
          //changeMymapsItem(name, name);
        } else {
          addMymapsItem(name, addMapListEntry(name, MAP_MY, true), true);
        }
        mymaps[name] = value;
        imported++;
      }
    });
  } catch (ex) {
    error("Invalid import data");
  }
  if (imported > 0) {
    saveJsonValOpt("wt.mymaps", mymaps);
    ga('send', 'event', 'map', 'import', undefined, imported);
    saveMapList();
  }
  $("#input-box").hide();
}

$("#input-box-close").click(function() {
  $("#input-box").hide();
  return false;
});

$("#input-val").keyup(function(event) {
  if (event.which == 27) {
    $("#input-box").hide();
  } else if (event.keyCode == 13) {
    var isImport = $("#input-ok").is(":visible");
    $("#input-box").hide();
    if (isImport) {
      importMymaps();
    }
  }
});

$("#input-ok").click(importMymaps);

$("#mymaps-import").click(openImportMymaps);
$("#mymaps-export").click(openExportMymaps);

if (!supportsBase64() || !JSON || !JSON.parse || !JSON.stringify) {
  $("#mymaps-import").attr("disabled", "disabled");
  $("#mymaps-export").attr("disabled", "disabled");
}

// ------------------- ready?

$(document).ready(function() {
  showMapsList();
  // ----- drag & drop list -----
  $("#mymaps-list").sortable({
    //scroll: true,
    handle: ".map-drag, .map-name",
    update: function(evt) {
      // get map-item
      var item = $(evt.target).parents(".map-item");
      // NOTE: item may be detached from the list at this step
      // moved item name
      var name = item.find(".map-name").text();
      // get new index
      var toIdx = getMapItem(name).index();
      // get old index
      var fromIdx = getMapListEntryIndex(name);
      if (fromIdx != toIdx) {
        // update list data
        moveMapListEntry(fromIdx, toIdx);
        saveMapList();
        ga('send', 'event', 'map', 'move');
      }
    }
  });
});

$(window).on("unload", function() {
  $("#mymaps-list").sortable('destroy');
});
<commit_msg>fix export perso map name setting<commit_after>/* ----------------- My maps edition ------------------- */

function setMapItemVisibility(elt, props) {
  //var isVisible = e.target.getAttribute("isVisible") == "true";
  var isVisible = props.on;
  elt.attr("isVisible", "" + isVisible);
  elt.text(isVisible ? "visibility" : "visibility_off");
  var parent = elt.parent(".map-item");
  if (isVisible && parent.length) {
    parent.removeClass("map-invisible");
  } else {
    parent.addClass("map-invisible");
  }
}

function addMymapsItem(name, props, addHandlers) {
  var mapitem = "
";
  mapitem += "drag_indicator ";
  mapitem += "" + name + " ";
  mapitem += "?? ";
  if (props.in == MAP_MY) {
    mapitem += "create ";
    mapitem += "share ";
    mapitem += "delete ";
  }
  mapitem += "
";
  $("#mymaps-list").append(mapitem);
  var newitem = $("#mymaps-list").children().last();
  setMapItemVisibility(newitem.find(".map-visibility"), props);
  if (addHandlers) {
    addMapItemHandlers(newitem);
  }
}

function getMapName(elt) {
  return elt.parentNode.querySelector(".map-name").innerText;
}

function getMapProps(elt) {
  var name = getMapName(elt);
  var idx = mapsListNames.indexOf(name);
  return mapsListProps[idx];
}

function getMapItem(name) {
  var res = undefined;
  $("#mymaps-list .map-name").each(function(i, v) {
    if (name == v.innerText) {
      res = $(v).parents("li");
      return true;
    }
  });
  return res;
}

function changeMymapsItem(oldname, newname) {
  var mapItem = getMapItem(oldname);
  if (mapItem) {
    if (newname) {
      // name changed
      mapItem.find(".map-name").text(newname);
    } else {
      // item deleted
      mapItem.remove();
    }
  }
}

function showMapsList() {
  $("#mymaps-list").empty();
  mapsForEach(function(name, value) {
    addMymapsItem(name, value);
  });
  addMapItemHandlers($('#mymaps-list li'));
}

function toggleMapVisibility(e) {
  var mprops = getMapProps(e.target);
  mprops.on = !mprops.on;
  ga('send', 'event', 'map', 'visibility');
  saveMapList();
  setMapItemVisibility($(e.target), mprops)
}

function editMapItem(e) {
  var name = getMapName(e.target);
  editMymap(name);
}
function deleteMapItem(e) {
  var name = getMapName(e.target);
  deleteMymap(name);
}
function shareMapItem(e) {
  var name = getMapName(e.target);
  openExportMymaps(null, name);
}

function addMapItemHandlers(selector) {
  selector.find(".map-edit").click(editMapItem);
  selector.find(".map-visibility").click(toggleMapVisibility);
  selector.find(".map-delete").click(deleteMapItem);
  selector.find(".map-share").click(shareMapItem);
}

// ----------------------- Personal map edition ----------------------

var mymap;

function initCrsSelector() {
  var crsSelect = $("#mymap-crs")[0];
  for (var i = CrsValues.length - 1; i >=0; i--) {
    var crs = CrsValues[i];
    addSelectOption(crsSelect, crs ? crs.code : "");
  }
}
initCrsSelector();

function openMymapBox() {
  $("#mymap-name").val(mymap.name);
  $("#mymap-url").val(mymap.url);
  $("#mymap-minz").val(mymap.options.minZoom);
  $("#mymap-maxz").val(mymap.options.maxZoom);
  $("#mymap-layers").val(mymap.options.layers);
  $("#mymap-layer").val(mymap.options.layer);
  $("#mymap-tilematrixSet").val(mymap.options.tilematrixSet);
  $("#mymap-crs").val(mymap.options.crs);
  $("#mymap-styles").val(mymap.options.styles);
  $("#mymap-style").val(mymap.options.style);
  $("#mymap-format").val(mymap.options.format);
  $("#mymap-attr").val(mymap.options.attribution);
  $("#mymap-box input:radio[name=mymap-type][value=" + mymap.type + "]").prop('checked', true);
  $("#mymap-box").show();
  $("#mymap-name").focus();
  changeMymapType();
}

function newMymap(evt) {
  mymap = { options: {} };
  openMymapBox();
}

function editMymap(mymapname) {
  if (mymapname) {
    mymap = mymaps[mymapname];
    if (mymap) {
      mymap.name = mymapname;
      openMymapBox();
    }
  }
}

var mymapsInputs = $("#mymap-box input");
mymapsInputs.on("invalid", function(evt) {
  var invalidInput = $(evt.target);
  invalidInput.addClass("invalid");
  invalidInput.focus();
});
mymapsInputs.on("input", function(evt) {
  if (evt.target.checkValidity()) {
    $(evt.target).removeClass("invalid");
  }
});

mymapsInputs.keyup(function(event) {
  if (event.which == 27) {
    cancelMymapBox();
    event.stopPropagation();
  } else if (event.keyCode == 13) {
    validateMymapBox();
  }
});

function validateMymapBox(evt) {
  var valid = true;
  // check validity on displayed inputs
  $("#mymap-box input:visible").each(function(i, v) {
    var display = $(v).css('display');
    if ((display != "none") && (!v.checkValidity())) {
      valid = false;
      return false;
    }
  });
  var oldname = mymap.name;
  var newname = $("#mymap-name").val().trim();
  if ((oldname != newname) && (getMapListEntryIndex(newname) >= 0)) {
    $("#mymap-name").trigger("invalid");
    warn("Map name already used: " + newname);
    valid = false;
  }
  if (valid) {
    //mymapsInputs.removeClass("invalid");
    $("#mymap-box").hide();
    mymap[name] = undefined;
    mymap.url = $("#mymap-url").val().trim();
    mymap.type = $('input:radio[name=mymap-type]:checked').val();
    mymap.options.minZoom= $("#mymap-minz").val().trim();
    mymap.options.maxZoom = $("#mymap-maxz").val().trim();
    if (mymap.type === "wms") {
      mymap.options.layers = $("#mymap-layers").val().trim();
      mymap.options.crs = $("#mymap-crs").val().trim();
      mymap.options.styles = $("#mymap-styles").val().trim();
      mymap.options.format = $("#mymap-format").val().trim();
    } else if (mymap.type === "wmts") {
      mymap.options.layer = $("#mymap-layer").val().trim();
      mymap.options.tilematrixSet = $("#mymap-tilematrixSet").val().trim();
      mymap.options.style = $("#mymap-style").val().trim();
      mymap.options.format = $("#mymap-format").val().trim();
    }
    mymap.options.attribution = $("#mymap-attr").val().trim();
    if (oldname && mymaps[oldname]) {
      if (oldname != newname) {
        // rebuild object to preserve order
        var tmp = {};
        objectForEach(mymaps, function(name, value) {
          if (name == oldname) {
            tmp[newname] = mymap;
          } else {
            tmp[name] = value;
          }
        });
        mymaps = tmp;
        renameMapListEntry(oldname, newname);
        changeMymapsItem(oldname, newname);
        saveMapList();
      } else {
        mymaps[newname] = mymap;
      }
      ga('send', 'event', 'map', 'edit');
    } else {
      mymaps[newname] = mymap;
      addMymapsItem(newname, addMapListEntry(newname, MAP_MY, true), true);
      saveMapList();
      ga('send', 'event', 'map', 'add');
    }
    saveJsonValOpt("wt.mymaps", mymaps);
  }
}

function cancelMymapBox(evt) {
  $("#mymap-box").hide();
  mymapsInputs.removeClass("invalid");
  mymap = undefined;
}

function deleteMymap(mymapname) {
  if (mymapname) {
    mymap = mymaps[mymapname];
    if (mymap && confirm("Delete \"" + mymapname + "\"?")) {
      mymaps[mymapname] = undefined;
      saveJsonValOpt("wt.mymaps", mymaps);
      // delete map in lists
      delMapListEntry(getMapListEntryIndex(mymapname));
      changeMymapsItem(mymapname);
      saveMapList();
      ga('send', 'event', 'map', 'delete');
    }
  }
}

function changeMymapType(evt) {
  var type =  $('input:radio[name=mymap-type]:checked').val();
  $(".map-wmts").hide();
  $(".map-wms").hide();
  if (type != "base") {
    $(".map-" + type).show();
  }
}

function deleteAllMymaps(evt) {
  if (!$.isEmptyObject(mymaps) &&
      confirm("Delete all your personal maps?")) {
    mymaps = {};
    saveJsonValOpt("wt.mymaps", undefined);
    ga('send', 'event', 'map', 'deleteall');
    getMapList();
    showMapsList()
  }
}
function reorderMapList(evt) {
  if (confirm("Re-order map list according to defaults, with personal maps at the end?")) {
    ga('send', 'event', 'map', 'reorder');
    resetMapList();
    getMapList();
    showMapsList();
  }
}

$("#mymap-ok").click(validateMymapBox);
$("#mymap-cancel").click(cancelMymapBox);

$("#mymaps-new").click(newMymap);
$("#mymaps-deleteall").click(deleteAllMymaps);

$("#maps-reorder").click(reorderMapList);
$("input:radio[name=mymap-type]").change(changeMymapType);

// ---------------- Import / export my maps

function openExportMymaps(evt, mymapname) {
  var toexport = {};
  if (mymapname) {
    toexport[mymapname] = mymaps[mymapname];
  } else {
    toexport = mymaps;
  }
  if (!$.isEmptyObject(toexport)) {
    var json = JSON.stringify(toexport);
    var data = b64EncodeUnicode(json);
    $("#input-text").text("Copy and share map data below (Ctrl+C & Enter):");
    $("#input-ok").hide();
    $("#input-val").val(data);
    $("#input-box").show();
    $("#input-val").focus();
    $("#input-val").select();
    $("#input-val").attr("readonly", "readonly");
    $(".prompt-content .copyonclick").show();
    ga('send', 'event', 'map', 'export', undefined, mymapname ? 1 : mymaps.length);
  }
}

function openImportMymaps() {
  $("#input-text").text("Paste exported map data (Ctrl+V & Enter):");
  $("#input-val").val("");
  $("#input-ok").show();
  $("#input-box").show();
  $("#input-val").removeAttr("readonly");
  $(".prompt-content .copyonclick").hide();
  $("#input-val").focus();
}

function importMymaps() {
  var imported = 0;
  try {
    var data = $("#input-val").val().trim();
    var importedMymaps = data ? JSON.parse(b64DecodeUnicode(data)) : {};
    objectForEach(importedMymaps, function(name, value) {
      var overwrite = mymaps[name];
      var msg = overwrite ? "Overwrite \"" : "Import \"";
      if (confirm(msg + name + "\"?")) {
        if (overwrite) {
          // useless
          //changeMymapsItem(name, name);
        } else {
          addMymapsItem(name, addMapListEntry(name, MAP_MY, true), true);
        }
        mymaps[name] = value;
        imported++;
      }
    });
  } catch (ex) {
    error("Invalid import data");
  }
  if (imported > 0) {
    saveJsonValOpt("wt.mymaps", mymaps);
    ga('send', 'event', 'map', 'import', undefined, imported);
    saveMapList();
  }
  $("#input-box").hide();
}

$("#input-box-close").click(function() {
  $("#input-box").hide();
  return false;
});

$("#input-val").keyup(function(event) {
  if (event.which == 27) {
    $("#input-box").hide();
  } else if (event.keyCode == 13) {
    var isImport = $("#input-ok").is(":visible");
    $("#input-box").hide();
    if (isImport) {
      importMymaps();
    }
  }
});

$("#input-ok").click(importMymaps);

$("#mymaps-import").click(openImportMymaps);
$("#mymaps-export").click(openExportMymaps);

if (!supportsBase64() || !JSON || !JSON.parse || !JSON.stringify) {
  $("#mymaps-import").attr("disabled", "disabled");
  $("#mymaps-export").attr("disabled", "disabled");
}

// ------------------- ready?

$(document).ready(function() {
  showMapsList();
  // ----- drag & drop list -----
  $("#mymaps-list").sortable({
    //scroll: true,
    handle: ".map-drag, .map-name",
    update: function(evt) {
      // get map-item
      var item = $(evt.target).parents(".map-item");
      // NOTE: item may be detached from the list at this step
      // moved item name
      var name = item.find(".map-name").text();
      // get new index
      var toIdx = getMapItem(name).index();
      // get old index
      var fromIdx = getMapListEntryIndex(name);
      if (fromIdx != toIdx) {
        // update list data
        moveMapListEntry(fromIdx, toIdx);
        saveMapList();
        ga('send', 'event', 'map', 'move');
      }
    }
  });
});

$(window).on("unload", function() {
  $("#mymaps-list").sortable('destroy');
});
<|endoftext|>


<commit_before>angular.module('starter.controllers', ['ui.router'])

.controller('AppCtrl', function($scope, $location, RegistrationService) {
  $scope.logout = function() {
    RegistrationService.logout();
    $location.path("/home");
  }
  $scope.timeleft = '0 secs';
})

.controller('RegisterCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    name: '',
    email: '',
    password: '',
    password2: ''
  };

  $scope.$parent.logout_text = 'Logout';

  $scope.register = function() {
    RegistrationService.register($scope.user).then(function() {
      $location.path("/");
    })
  }
})

.controller('LoginCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    email: '',
    password: ''
  };

  $scope.$parent.logout_text = 'Register';

  $scope.login = function() {
    RegistrationService.login($scope.user.email, $scope.user.password).then(function() {
      $location.path("/");
    });
  }

})

.controller('LeadersCtrl', function($scope, SocketIO, Answer) {
  $scope.leaders = Answer.leaders();

  SocketIO.on('answer', function(msg) {
    $scope.leaders = Answer.leaders();
  });

  $scope.$on('$destroy', function(event) {
    SocketIO.removeAllListeners('answer');
  });

})

.controller('HomeCtrl', function($scope, $location) {

})

.controller('OneCtrl', function($scope, $location) {
  $scope.$parent.logout_text = 'Home';

  $scope.one = function() {
    (function() {
    $location.path("/");
    });
  }
})

.controller('TwoCtrl', function($scope, $location) {

})

.controller('ThreeCtrl', function($scope, $location) {

})

.controller('AllCtrl', function($scope, $location) {

})

.controller('1B1Ctrl', function($scope, $location) {

})

.controller('1B2Ctrl', function($scope, $location) {

})

.controller('1B3Ctrl', function($scope, $location) {

})

.controller('2B1Ctrl', function($scope, $location) {

})

.controller('2B2Ctrl', function($scope, $location) {

})

.controller('2B3Ctrl', function($scope, $location) {

})
.controller('2B4Ctrl', function($scope, $location) {

})

.controller('2B5Ctrl', function($scope, $location) {

})

.controller('2B6Ctrl', function($scope, $location) {

})

.controller('3B1Ctrl', function($scope, $location) {

})

.controller('3B2Ctrl', function($scope, $location) {

})

.controller('3B3Ctrl', function($scope, $location) {

})
.controller('3B4Ctrl', function($scope, $location) {

})

.controller('3B5Ctrl', function($scope, $location) {

})

.controller('3B6Ctrl', function($scope, $location) {

})
<commit_msg>Update controllers.js<commit_after>angular.module('starter.controllers', ['routerRoutes'])

.controller('AppCtrl', function($scope, $location, RegistrationService) {
  $scope.logout = function() {
    RegistrationService.logout();
    $location.path("/home");
  }
  $scope.timeleft = '0 secs';
})

.controller('RegisterCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    name: '',
    email: '',
    password: '',
    password2: ''
  };

  $scope.$parent.logout_text = 'Logout';

  $scope.register = function() {
    RegistrationService.register($scope.user).then(function() {
      $location.path("/");
    })
  }
})

.controller('LoginCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    email: '',
    password: ''
  };

  $scope.$parent.logout_text = 'Register';

  $scope.login = function() {
    RegistrationService.login($scope.user.email, $scope.user.password).then(function() {
      $location.path("/");
    });
  }

})

.controller('LeadersCtrl', function($scope, SocketIO, Answer) {
  $scope.leaders = Answer.leaders();

  SocketIO.on('answer', function(msg) {
    $scope.leaders = Answer.leaders();
  });

  $scope.$on('$destroy', function(event) {
    SocketIO.removeAllListeners('answer');
  });

})

.controller('HomeCtrl', function($scope, $location) {

})

.controller('OneCtrl', function($scope, $location) {
  $scope.$parent.logout_text = 'Home';

  $scope.one = function() {
    (function() {
    $location.path("/");
    });
  }
})

.controller('TwoCtrl', function($scope, $location) {

})

.controller('ThreeCtrl', function($scope, $location) {

})

.controller('AllCtrl', function($scope, $location) {

})

.controller('1B1Ctrl', function($scope, $location) {

})

.controller('1B2Ctrl', function($scope, $location) {

})

.controller('1B3Ctrl', function($scope, $location) {

})

.controller('2B1Ctrl', function($scope, $location) {

})

.controller('2B2Ctrl', function($scope, $location) {

})

.controller('2B3Ctrl', function($scope, $location) {

})
.controller('2B4Ctrl', function($scope, $location) {

})

.controller('2B5Ctrl', function($scope, $location) {

})

.controller('2B6Ctrl', function($scope, $location) {

})

.controller('3B1Ctrl', function($scope, $location) {

})

.controller('3B2Ctrl', function($scope, $location) {

})

.controller('3B3Ctrl', function($scope, $location) {

})
.controller('3B4Ctrl', function($scope, $location) {

})

.controller('3B5Ctrl', function($scope, $location) {

})

.controller('3B6Ctrl', function($scope, $location) {

})
<|endoftext|>


<commit_before>import EmberObject from '@ember/object';
import classic from 'ember-classic-decorator';

@classic
export default class DummyValidationAdapter extends EmberObject {
  validate() {
    return this.object.validate();
  }

  get attributes() {
    return this.object.validationsDummy;
  }
}
<commit_msg>fix 3.16 compatibility<commit_after>import EmberObject from '@ember/object';
import classic from 'ember-classic-decorator';
import { dependentKeyCompat } from '@ember/object/compat';

@classic
export default class DummyValidationAdapter extends EmberObject {
  validate() {
    if (this.object?.validate) {
      return this.object.validate();
    }
  }

  @dependentKeyCompat
  get attributes() {
    return this.object?.validationsDummy;
  }
}
<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var paths = require('../helpers/paths');
var env = require('../helpers/env');
var HappyPack = require('happypack');
var babelConfig = require('../helpers/babelConfig');
var globals = require('../helpers/globals');

module.exports = function styles (webpackConfig) {
  webpackConfig.plugins.push(
    new webpack.DefinePlugin(globals),
    new HtmlWebpackPlugin({
      template: path.resolve(paths.srcPath, 'index.html'),
      hash: false,
      filename: 'index.html',
      inject: 'body',
      favicon: path.resolve(paths.srcPath, 'static/favicon.ico'),
      minify: {
        collapseWhitespace: true
      }
    })
  )

  var preprocess =

  webpackConfig.plugins.push(
    new HappyPack({
      id: 'scripts',
      loaders: [
        'babel?' + JSON.stringify(babelConfig)
      ]
    })
  )

  if (env.isDevelopment) {
    webpackConfig.plugins.push(
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin()
    )
  } else if (env.isProduction) {
    webpackConfig.plugins.push(
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          unused: true,
          dead_code: true,
          warnings: false
        }
      })
    )
  }

  if (!env.isTest) {
    webpackConfig.plugins.push(new webpack.optimize.CommonsChunkPlugin({
      names: ['vendors']
    }))
  }

  return webpackConfig;
}
<commit_msg>now using 4 threads for babel<commit_after>var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var paths = require('../helpers/paths');
var env = require('../helpers/env');
var HappyPack = require('happypack');
var babelConfig = require('../helpers/babelConfig');
var globals = require('../helpers/globals');

module.exports = function styles (webpackConfig) {
  webpackConfig.plugins.push(
    new webpack.DefinePlugin(globals),
    new HtmlWebpackPlugin({
      template: path.resolve(paths.srcPath, 'index.html'),
      hash: false,
      filename: 'index.html',
      inject: 'body',
      favicon: path.resolve(paths.srcPath, 'static/favicon.ico'),
      minify: {
        collapseWhitespace: true
      }
    })
  )

  var preprocess =

  webpackConfig.plugins.push(
    new HappyPack({
      id: 'scripts',
      threads: 4,
      loaders: [
        'babel?' + JSON.stringify(babelConfig)
      ]
    })
  )

  if (env.isDevelopment) {
    webpackConfig.plugins.push(
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin()
    )
  } else if (env.isProduction) {
    webpackConfig.plugins.push(
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          unused: true,
          dead_code: true,
          warnings: false
        }
      })
    )
  }

  if (!env.isTest) {
    webpackConfig.plugins.push(new webpack.optimize.CommonsChunkPlugin({
      names: ['vendors']
    }))
  }

  return webpackConfig;
}
<|endoftext|>


<commit_before>var loadScripts = function(js_files, onComplete){
    var len = js_files.length;
    var head = document.getElementsByTagName('head')[0];

    function loadScript(index){
        if (index >= len){
            onComplete();
            return;
        }

        try {
            testOk = js_files[index].test();
        } catch (e) {
            // with certain browsers like opera the above test can fail
            // because of undefined variables...
            testOk = true;
        }

        if (testOk) {
            var s = document.createElement('script');
            s.src = js_files[index].src;
            s.type = 'text/javascript';
            head.appendChild(s);

            s.onload = function(){
                loadScript(index+1);
            }
        } else {
            loadScript(index+1);
        }
    }

    loadScript(0);
}
<commit_msg>testOk variable was polluting the 'window' object<commit_after>var loadScripts = function(js_files, onComplete){
    var len = js_files.length;
    var head = document.getElementsByTagName('head')[0];

    function loadScript(index){
        var testOk;

        if (index >= len){
            onComplete();
            return;
        }

        try {
            testOk = js_files[index].test();
        } catch (e) {
            // with certain browsers like opera the above test can fail
            // because of undefined variables...
            testOk = true;
        }

        if (testOk) {
            var s = document.createElement('script');
            s.src = js_files[index].src;
            s.type = 'text/javascript';
            head.appendChild(s);

            s.onload = function(){
                loadScript(index+1);
            }
        } else {
            loadScript(index+1);
        }
    }

    loadScript(0);
}
<|endoftext|>


<commit_before>game.MiniMap = me.Entity.extend({

});<commit_msg>Video 64 Coded/Commented<commit_after>game.MiniMap = me.Entity.extend({
	init: function(x, y, settings){
		this._super(me.Entity, "init", [x, y, {
			image: "minimap",
			width: 699,
			height: 114,
			spritewidth: "699",
			spriteheight: "114",
			getShape: function(){
				return (new me.Rect(0, 0, 699, 144)) .toPolygon();
			}
		}]);
		this.floating = true;

	}
});<|endoftext|>


<commit_before>(function(){

    var routineAppControllers = angular.module('routineApp.controllers', ['routineApp.filters',
                'ngCookies',
                ]);

    routineAppControllers.controller('RoutineListController', ['RoutineService', 'SharedProperties', function(RoutineService, SharedProperties) {

        var vm = this;

        vm.setId = function(id) {
            SharedProperties.setProperty(id);
        };

        vm.getRoutines = function() {
            RoutineService.getRoutines()
            .success(function(response){
                vm.routines = response;
            })
            .error(function() {
                // Need error handling
            });
        }

        vm.getRoutines();

    }]);

    routineAppControllers.controller('RoutineCreateRoutineController', ['RoutineService', 'SharedProperties', '$cookies', '$state', function(RoutineService, SharedProperties, $cookies, $state) {

        var vm = this;

        vm.createRoutine = function(routineJson) {
            RoutineService.createRoutine(routineJson)
            .success(function(response) {
                SharedProperties.setProperty(response.id);
            })
            .error(function(){
                // Need error handling
            });
        };

        vm.submit = function() {

            var routineObj = {};

            routineObj.name = vm.routine.name;

            $cookies.put('routine', routineObj.name);

            var routineJson = angular.toJson(routineObj);

            vm.createRoutine(routineJson);

            $state.go('create_exercises');

        };

    }]);

    routineAppControllers.controller('RoutineCreateExercisesController', ['$cookies', 'RoutineService', 'SharedProperties', '$state', function($cookies, RoutineService, SharedProperties, $state) {

        var vm = this;

        vm.exercises = [{position: '1'}, {position: '2'}, {position: '3'}, {position: '4'}, {position: '5'}];

        vm.addNewExercise = function() {
            var newExercisePosition = vm.exercises.length + 1;
            vm.exercises.push({'position': newExercisePosition});
        };

        vm.removeExercise = function() {
            var lastExercise = vm.exercises.length - 1;
            vm.exercises.splice(lastExercise);
        };

        vm.createExercises = function(exercisesJson){
            RoutineService.createExercises(exercisesJson)
            .success(function(response) {

            })
            .error(function() {
                // Need error handling
            });
        };

        vm.submit = function() {

            var routineId = SharedProperties.getProperty();

            var exerciseObjs = [];

            angular.forEach(vm.exercises, function(exercise, index){
                if (exercise.name) {

                    var exerciseObj = {};
                    exerciseObj.position = exercise.position;
                    exerciseObj.name = exercise.name;
                    exerciseObj.completion_time = "00:" + exercise.minutes + ":" + exercise.seconds;
                    exerciseObj.routine = routineId;

                    exerciseObjs.push(exerciseObj);

                }
            });

            var exercisesJson = angular.toJson(exerciseObjs);
            vm.createExercises(exercisesJson);

            $state.go('list_routines');
        };

    }]);

    routineAppControllers.controller('RoutineEditController', ['RoutineService', 'SharedProperties', '$location', function(RoutineService, SharedProperties, $location) {

        var vm = this;

        var routineId = SharedProperties.getProperty();

        vm.getRoutine = function(routineId) {
            RoutineService.getRoutine(routineId)
            .success(function(response){
                vm.routine = response;
            })
            .error(function(){

            });
        };

        vm.getRoutine(routineId);

        vm.getFullRoutine = function(routineId) {
            RoutineService.getFullRoutine(routineId)
            .success(function(response){
                vm.exercises = response;
                vm.formatCompletionTimes(vm.exercises);
            })
            .error(function(){

            });
        };

        vm.getFullRoutine(routineId);

        // Format the completion time to fit in the form
        vm.formatCompletionTimes = function(exercises){
            angular.forEach(exercises, function(exercise, index){

                var completion_time = exercise.completion_time.split(":");

                exercise.minutes = completion_time[1];
                exercise.seconds = completion_time[2];
            });
        }

        vm.addNewExercise = function() {
            var newExercisePosition = vm.exercises.length + 1;
            vm.exercises.push({'position': newExercisePosition});
        };

        vm.deleteExerciseClick = function() {
            var lastExercise = vm.exercises.length - 1;

            // delete exercise from the database
            vm.deleteExercise(vm.exercises[lastExercise].id);

            vm.exercises.splice(lastExercise);
        };

        vm.editExercise = function(exerciseJson) {
            RoutineService.editExercise(exerciseJson)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.editRoutine = function(routineJson) {
            RoutineService.editRoutine(routineJson)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.deleteExercise = function(exerciseId) {
            RoutineService.deleteExercise(exerciseId)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.submit = function() {

            var routineJson = angular.toJson(vm.routine);
            vm.editRoutine(routineJson);

            var exerciseObjs = [];

            angular.forEach(vm.exercises, function(exercise, index){

                var exerciseObj = {};

                exerciseObj.id = exercise.id;
                exerciseObj.position = exercise.position;
                exerciseObj.name = exercise.name;
                exerciseObj.completion_time = "00:" + exercise.minutes + ":" + exercise.seconds;
                exerciseObj.routine = vm.routine.id;

                var exerciseJson = angular.toJson(exerciseObj);
                vm.editExercise(exerciseJson);

            });

        };

    }]);

    routineAppControllers.controller('RoutineUseController', ['$interval', 'RoutineService', '$location', function($interval, RoutineService, $location){

        var ctrl = this;

        var routineName = $location.url().split('/')[2];

        ctrl.routine = {name:routineName, total_time: '00:00:00'};

        console.log(ctrl.routine);

        ctrl.getRoutine = function() {
            RoutineService.getRoutine(ctrl.routine.name).then(function(response){

                ctrl.routine = response.data[0].routine;
                ctrl.exercises = response.data;
                ctrl.total_exercises = ctrl.exercises.length;
                ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);

            })
        }

        ctrl.getRoutine();

        ctrl.current_position = 1;

        var count_down;
        var reset = false;
        ctrl.timerStartStop = function(){

            // If the timer has run through completely, reset it
            if (reset) {
                exerciseReset();
            }

            // If already running, stop the timer
            if (angular.isDefined(count_down)) {
                $interval.cancel(count_down);
                count_down = undefined;
            } else {

                count_down = $interval(function(){

                    if (exerciseHasEnded(ctrl.current_exercise.count_down_time)) {

                        ctrl.current_position == ctrl.current_position++;

                        // If the last exercise has finished, stop the timer
                        // Otherwise move on to the next exercise
                        if (ctrl.current_position > ctrl.total_exercises) {
                            $interval.cancel(count_down);
                            count_down = undefined;
                            ctrl.current_position == ctrl.current_position--;
                            reset = true;
                        } else {
                            ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);
                        }

                    } else {
                        countDown(ctrl.current_exercise.count_down_time);
                    }

                }, 1000);
            }

        };

        ctrl.timerReset = function(){

            if (angular.isDefined(count_down)) {
                $interval.cancel(count_down);
                count_down = undefined;
            }

            exerciseReset();

        };

        function exerciseReset(){

            ctrl.current_position = 1;
            ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);

            reset = false;

        }

        function exerciseHasEnded(time){
            return time.seconds == 0 && time.minutes == 00;
        }

        function setCurrentExercise(exercises, position){

            var indexPosition = position - 1;
            var current_exercise = exercises[indexPosition];

            current_exercise.count_down_time = completionTimeToObj(current_exercise.completion_time);

            return current_exercise;
        }

        function countDown(time){

            if (time.seconds > 0 && time.minutes > -1){
                time.seconds == time.seconds--;
                // return time;
            } else if (time.minutes > 0) {
                time.minutes == time.minutes--;
                time.seconds = 60;
                // return time;
            }

        };

        function completionTimeToObj(completion_time){

            // Not starting at index of 0 because django stores times as 00:00:00
            var completionSplit = completion_time.split(":");
            var minutes = parseInt(completionSplit[1]);
            var seconds = parseInt(completionSplit[2]);

            return {
                minutes: minutes,
                seconds: seconds
            }

        };

    }]);

})();
<commit_msg>Client - Added create exercise to edit page<commit_after>(function(){

    var routineAppControllers = angular.module('routineApp.controllers', ['routineApp.filters',
                'ngCookies',
                ]);

    routineAppControllers.controller('RoutineListController', ['RoutineService', 'SharedProperties', function(RoutineService, SharedProperties) {

        var vm = this;

        vm.setId = function(id) {
            SharedProperties.setProperty(id);
        };

        vm.getRoutines = function() {
            RoutineService.getRoutines()
            .success(function(response){
                vm.routines = response;
            })
            .error(function() {
                // Need error handling
            });
        }

        vm.getRoutines();

    }]);

    routineAppControllers.controller('RoutineCreateRoutineController', ['RoutineService', 'SharedProperties', '$cookies', '$state', function(RoutineService, SharedProperties, $cookies, $state) {

        var vm = this;

        vm.createRoutine = function(routineJson) {
            RoutineService.createRoutine(routineJson)
            .success(function(response) {
                SharedProperties.setProperty(response.id);
            })
            .error(function(){
                // Need error handling
            });
        };

        vm.submit = function() {

            var routineObj = {};

            routineObj.name = vm.routine.name;

            $cookies.put('routine', routineObj.name);

            var routineJson = angular.toJson(routineObj);

            vm.createRoutine(routineJson);

            $state.go('create_exercises');

        };

    }]);

    routineAppControllers.controller('RoutineCreateExercisesController', ['$cookies', 'RoutineService', 'SharedProperties', '$state', function($cookies, RoutineService, SharedProperties, $state) {

        var vm = this;

        vm.exercises = [{position: '1'}, {position: '2'}, {position: '3'}, {position: '4'}, {position: '5'}];

        vm.addNewExercise = function() {
            var newExercisePosition = vm.exercises.length + 1;
            vm.exercises.push({'position': newExercisePosition});
        };

        vm.removeExercise = function() {
            var lastExercise = vm.exercises.length - 1;
            vm.exercises.splice(lastExercise);
        };

        vm.createExercises = function(exercisesJson){
            RoutineService.createExercises(exercisesJson)
            .success(function(response) {

            })
            .error(function() {
                // Need error handling
            });
        };

        vm.submit = function() {

            var routineId = SharedProperties.getProperty();

            var exerciseObjs = [];

            angular.forEach(vm.exercises, function(exercise, index){
                if (exercise.name) {

                    var exerciseObj = {};
                    exerciseObj.position = exercise.position;
                    exerciseObj.name = exercise.name;
                    exerciseObj.completion_time = "00:" + exercise.minutes + ":" + exercise.seconds;
                    exerciseObj.routine = routineId;

                    exerciseObjs.push(exerciseObj);

                }
            });

            var exercisesJson = angular.toJson(exerciseObjs);
            vm.createExercises(exercisesJson);

            $state.go('list_routines');
        };

    }]);

    routineAppControllers.controller('RoutineEditController', ['RoutineService', 'SharedProperties', '$location', function(RoutineService, SharedProperties, $location) {

        var vm = this;

        var routineId = SharedProperties.getProperty();

        vm.getRoutine = function(routineId) {
            RoutineService.getRoutine(routineId)
            .success(function(response){
                vm.routine = response;
            })
            .error(function(){

            });
        };

        vm.getFullRoutine = function(routineId) {
            RoutineService.getFullRoutine(routineId)
            .success(function(response){
                vm.exercises = response;
                vm.formatCompletionTimes(vm.exercises);
            })
            .error(function(){

            });
        };

        // Format the completion time to fit in the form
        vm.formatCompletionTimes = function(exercises){
            angular.forEach(exercises, function(exercise, index){

                var completion_time = exercise.completion_time.split(":");

                exercise.minutes = completion_time[1];
                exercise.seconds = completion_time[2];
            });
        }

        vm.addNewExercise = function() {
            var newExercisePosition = vm.exercises.length + 1;
            vm.exercises.push({'position': newExercisePosition});
        };

        vm.createExercise = function(exerciseJson) {
            RoutineService.createExercise(exerciseJson)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.deleteExerciseClick = function() {
            var lastExercise = vm.exercises.length - 1;

            // delete exercise from the database
            vm.deleteExercise(vm.exercises[lastExercise].id);

            vm.exercises.splice(lastExercise);
        };

        vm.editExercise = function(exerciseJson) {
            RoutineService.editExercise(exerciseJson)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.editRoutine = function(routineJson) {
            RoutineService.editRoutine(routineJson)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.deleteExercise = function(exerciseId) {
            RoutineService.deleteExercise(exerciseId)
            .success(function(response){

            })
            .error(function(){

            });
        };

        vm.findNewExercises = function(exercises) {

            newExercises = [];

            exercises.forEach(function(exercise){
                if (typeof exercise.id == 'undefined') {
                    newExercises.push(exercise);
                }
            });

            return newExercises;
        };

        vm.submit = function() {

            var routineJson = angular.toJson(vm.routine);
            vm.editRoutine(routineJson);

            var exerciseObjs = [];

            angular.forEach(vm.exercises, function(exercise, index){

                if (typeof exercise.id !== 'undefined') {

                    var exerciseObj = {};

                    exerciseObj.id = exercise.id;
                    exerciseObj.position = exercise.position;
                    exerciseObj.name = exercise.name;
                    exerciseObj.completion_time = "00:" + exercise.minutes + ":" + exercise.seconds;
                    exerciseObj.routine = vm.routine.id;

                    var exerciseJson = angular.toJson(exerciseObj);

                    vm.editExercise(exerciseJson);

                } else if (typeof exercise.id == 'undefined') {

                    var exerciseObj = {};

                    exerciseObj.position = exercise.position;
                    exerciseObj.name = exercise.name;
                    exerciseObj.completion_time = "00:" + exercise.minutes + ":" + exercise.seconds;
                    exerciseObj.routine = vm.routine.id;

                    var exerciseJson = angular.toJson(exerciseObj);

                    vm.createExercise(exerciseJson);

                };

            });

        };

        vm.getRoutine(routineId);

        vm.getFullRoutine(routineId);

    }]);

    routineAppControllers.controller('RoutineUseController', ['$interval', 'RoutineService', '$location', function($interval, RoutineService, $location){

        var ctrl = this;

        var routineName = $location.url().split('/')[2];

        ctrl.routine = {name:routineName, total_time: '00:00:00'};

        console.log(ctrl.routine);

        ctrl.getRoutine = function() {
            RoutineService.getRoutine(ctrl.routine.name).then(function(response){

                ctrl.routine = response.data[0].routine;
                ctrl.exercises = response.data;
                ctrl.total_exercises = ctrl.exercises.length;
                ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);

            })
        }

        ctrl.getRoutine();

        ctrl.current_position = 1;

        var count_down;
        var reset = false;
        ctrl.timerStartStop = function(){

            // If the timer has run through completely, reset it
            if (reset) {
                exerciseReset();
            }

            // If already running, stop the timer
            if (angular.isDefined(count_down)) {
                $interval.cancel(count_down);
                count_down = undefined;
            } else {

                count_down = $interval(function(){

                    if (exerciseHasEnded(ctrl.current_exercise.count_down_time)) {

                        ctrl.current_position == ctrl.current_position++;

                        // If the last exercise has finished, stop the timer
                        // Otherwise move on to the next exercise
                        if (ctrl.current_position > ctrl.total_exercises) {
                            $interval.cancel(count_down);
                            count_down = undefined;
                            ctrl.current_position == ctrl.current_position--;
                            reset = true;
                        } else {
                            ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);
                        }

                    } else {
                        countDown(ctrl.current_exercise.count_down_time);
                    }

                }, 1000);
            }

        };

        ctrl.timerReset = function(){

            if (angular.isDefined(count_down)) {
                $interval.cancel(count_down);
                count_down = undefined;
            }

            exerciseReset();

        };

        function exerciseReset(){

            ctrl.current_position = 1;
            ctrl.current_exercise = setCurrentExercise(ctrl.exercises, ctrl.current_position);

            reset = false;

        }

        function exerciseHasEnded(time){
            return time.seconds == 0 && time.minutes == 00;
        }

        function setCurrentExercise(exercises, position){

            var indexPosition = position - 1;
            var current_exercise = exercises[indexPosition];

            current_exercise.count_down_time = completionTimeToObj(current_exercise.completion_time);

            return current_exercise;
        }

        function countDown(time){

            if (time.seconds > 0 && time.minutes > -1){
                time.seconds == time.seconds--;
                // return time;
            } else if (time.minutes > 0) {
                time.minutes == time.minutes--;
                time.seconds = 60;
                // return time;
            }

        };

        function completionTimeToObj(completion_time){

            // Not starting at index of 0 because django stores times as 00:00:00
            var completionSplit = completion_time.split(":");
            var minutes = parseInt(completionSplit[1]);
            var seconds = parseInt(completionSplit[2]);

            return {
                minutes: minutes,
                seconds: seconds
            }

        };

    }]);

})();
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class nova extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'nova',
            'name': 'Novaexchange',
            'countries': [ 'TZ' ], // Tanzania
            'rateLimit': 2000,
            'version': 'v2',
            'has': {
                'CORS': false,
                'createMarketOrder': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30518571-78ca0bca-9b8a-11e7-8840-64b83a4a94b2.jpg',
                'api': 'https://novaexchange.com/remote',
                'www': 'https://novaexchange.com',
                'doc': 'https://novaexchange.com/remote/faq',
            },
            'api': {
                'public': {
                    'get': [
                        'markets/',
                        'markets/{basecurrency}/',
                        'market/info/{pair}/',
                        'market/orderhistory/{pair}/',
                        'market/openorders/{pair}/buy/',
                        'market/openorders/{pair}/sell/',
                        'market/openorders/{pair}/both/',
                        'market/openorders/{pair}/{ordertype}/',
                    ],
                },
                'private': {
                    'post': [
                        'getbalances/',
                        'getbalance/{currency}/',
                        'getdeposits/',
                        'getwithdrawals/',
                        'getnewdepositaddress/{currency}/',
                        'getdepositaddress/{currency}/',
                        'myopenorders/',
                        'myopenorders_market/{pair}/',
                        'cancelorder/{orderid}/',
                        'withdraw/{currency}/',
                        'trade/{pair}/',
                        'tradehistory/',
                        'getdeposithistory/',
                        'getwithdrawalhistory/',
                        'walletstatus/',
                        'walletstatus/{currency}/',
                    ],
                },
            },
        });
    }

    async fetchMarkets (params = {}) {
        let response = await this.publicGetMarkets ();
        let markets = response['markets'];
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let market = markets[i];
            let id = market['marketname'];
            let [ quote, base ] = id.split ('_');
            let symbol = base + '/' + quote;
            let active = true;
            if (market['disabled'])
                active = false;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketOpenordersPairBoth (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetMarketInfoPair (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        let ticker = response['markets'][0];
        let timestamp = this.milliseconds ();
        let last = this.safeFloat (ticker, 'last_price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high24h'),
            'low': this.safeFloat (ticker, 'low24h'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': this.safeFloat (ticker, 'change24h'),
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume24h'),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['unix_t_datestamp'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['tradetype'].toLowerCase (),
            'price': this.safeFloat (trade, 'price'),
            'amount': this.safeFloat (trade, 'amount'),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketOrderhistoryPair (this.extend ({
            'pair': market['id'],
        }, params));
        return this.parseTrades (response['items'], market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostGetbalances ();
        let balances = response['balances'];
        let result = { 'info': response };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let lockbox = parseFloat (balance['amount_lockbox']);
            let trades = parseFloat (balance['amount_trades']);
            let account = {
                'free': parseFloat (balance['amount']),
                'used': this.sum (lockbox, trades),
                'total': parseFloat (balance['amount_total']),
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        await this.loadMarkets ();
        amount = amount.toString ();
        price = price.toString ();
        let market = this.market (symbol);
        let order = {
            'tradetype': side.toUpperCase (),
            'tradeamount': amount,
            'tradeprice': price,
            'tradebase': 1,
            'pair': market['id'],
        };
        let response = await this.privatePostTradePair (this.extend (order, params));
        return {
            'info': response,
            'id': undefined,
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        return await this.privatePostCancelorder (this.extend ({
            'orderid': id,
        }, params));
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/';
        if (api === 'private')
            url += api + '/';
        url += this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            url += '?' + this.urlencode ({ 'nonce': nonce });
            let signature = this.hmac (this.encode (url), this.encode (this.secret), 'sha512', 'base64');
            body = this.urlencode (this.extend ({
                'apikey': this.apiKey,
                'signature': signature,
            }, query));
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response)
            if (response['status'] !== 'success')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<commit_msg>Update nova.js<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class nova extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'nova',
            'name': 'Novaexchange',
            'countries': [ 'TZ' ], // Tanzania
            'rateLimit': 2000,
            'version': 'v2',
            'has': {
                'CORS': false,
                'createMarketOrder': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30518571-78ca0bca-9b8a-11e7-8840-64b83a4a94b2.jpg',
                'api': 'https://novaexchange.com/remote',
                'www': 'https://novaexchange.com',
                'doc': 'https://novaexchange.com/remote/faq',
            },
            'api': {
                'public': {
                    'get': [
                        'markets/',
                        'markets/{basecurrency}/',
                        'market/info/{pair}/',
                        'market/orderhistory/{pair}/',
                        'market/openorders/{pair}/buy/',
                        'market/openorders/{pair}/sell/',
                        'market/openorders/{pair}/both/',
                        'market/openorders/{pair}/{ordertype}/',
                    ],
                },
                'private': {
                    'post': [
                        'getbalances/',
                        'getbalance/{currency}/',
                        'getdeposits/',
                        'getwithdrawals/',
                        'getnewdepositaddress/{currency}/',
                        'getdepositaddress/{currency}/',
                        'myopenorders/',
                        'myopenorders_market/{pair}/',
                        'cancelorder/{orderid}/',
                        'withdraw/{currency}/',
                        'trade/{pair}/',
                        'tradehistory/',
                        'getdeposithistory/',
                        'getwithdrawalhistory/',
                        'walletstatus/',
                        'walletstatus/{currency}/',
                    ],
                },
            },
        });
    }

    async fetchMarkets (params = {}) {
        let response = await this.publicGetMarkets ();
        let markets = response['markets'];
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let market = markets[i];
            let id = market['marketname'];
            let [ quote, base ] = id.split ('_');
            let symbol = base + '/' + quote;
            let active = true;
            if (market['disabled'])
                active = false;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketOpenordersPairBoth (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetMarketInfoPair (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        let ticker = response['markets'][0];
        let timestamp = this.milliseconds ();
        let last = this.safeFloat (ticker, 'last_price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high24h'),
            'low': this.safeFloat (ticker, 'low24h'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': this.safeFloat (ticker, 'change24h'),
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume24h'),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['unix_t_datestamp'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['tradetype'].toLowerCase (),
            'price': this.safeFloat (trade, 'price'),
            'amount': this.safeFloat (trade, 'amount'),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketOrderhistoryPair (this.extend ({
            'pair': market['id'],
        }, params));
        return this.parseTrades (response['items'], market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostGetbalances ();
        let balances = response['balances'];
        let result = { 'info': response };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let lockbox = parseFloat (balance['amount_lockbox']);
            let trades = parseFloat (balance['amount_trades']);
            let account = {
                'free': parseFloat (balance['amount']),
                'used': this.sum (lockbox, trades),
                'total': parseFloat (balance['amount_total']),
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        await this.loadMarkets ();
        amount = amount.toString ();
        price = price.toString ();
        let market = this.market (symbol);
        let order = {
            'tradetype': side.toUpperCase (),
            'tradeamount': amount,
            'tradeprice': price,
            'tradebase': 1,
            'pair': market['id'],
        };
        let response = await this.privatePostTradePair (this.extend (order, params));
        return {
            'info': response,
            'id': undefined,
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        return await this.privatePostCancelorder (this.extend ({
            'orderid': id,
        }, params));
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/';
        if (api === 'private')
            url += api + '/';
        url += this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            url += '?' + this.urlencode ({ 'nonce': nonce });
            let signature = this.hmac (this.encode (url), this.encode (this.secret), 'sha512', 'base64');
            body = this.urlencode (this.extend ({
                'apikey': this.apiKey,
                'signature': signature,
            }, query));
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response)
            if (response['status'] !== 'success')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

function mkdir(path) {
	function create(path) {
		if (path) {
			if (!fs.existsSync(path) || !fs.statSync(path).isDirectory()) {
				try {
					fs.mkdirSync(path);
				} catch (error) {
					return false;
				}
			}
		}

		return true;
	}

	path.replace(/^\/+/, '').split(/\/+/).reduce(function (previousValue, currentValue) {
		create('/' + previousValue);

		return previousValue + '/' + currentValue;
	});

	return create(path);
}

function exit(code, message) {
	console.log(message);

	process.exit(code || 0);
}

var
fs = require('fs'),
path = require('path'),
manifestFile = 2 in process.argv ? path.resolve(process.argv[2]) : '',
baseDirectory = 3 in process.argv ? path.resolve(process.argv[3]).replace(/\/+$/, '') : path.dirname(manifestFile);

if (process.argv.length < 3) {
	exit(1, 'Usage: sass-director <manifest-file> <base-directory>');
}

if (!fs.existsSync(manifestFile)) {
	exit(1, 'Sorry, sass-director could not access ' + manifestFile + '.');
}

if (!mkdir(baseDirectory)) {
	exit(1, 'Sorry, sass-director could not access ' + baseDirectory + '.');
}

fs.readFile(manifestFile, 'utf8', function (error, data) {
	if (error) {
		exit(1, 'Sorry, sass-director could not access ' + manifestFile + '.');
	}

	var
	importStatements = data.match(/^[ \t]*@import[ \t]+(['"])(.+?)\1/mg),
	importDirectories = [],
	importBasenames = [];

	if (importStatements) {
		importStatements.forEach(function (importStatement) {
			var
			importPath = importStatement.match(/^[ \t]*@import[ \t]+(['"])(.+?)\1/)[2];

			importPath = importPath.match(/\.scss$/) ? importPath : importPath + '.scss';

			var
			importDirectory = baseDirectory + '/' + path.dirname(importPath),
			importBasename = importDirectory + '/_' + path.basename(importPath);

			if (!fs.existsSync(importDirectory) && importDirectories.indexOf(importDirectory) === -1) {
				importDirectories.push(importDirectory);
			}

			if (!fs.existsSync(importBasename) && importDirectories.indexOf(importBasename) === -1) {
				importBasenames.push(importBasename);
			}
		});
	}

	importDirectories.forEach(function (importDirectory) {
		if (!mkdir(importDirectory)) {
			exit(1, 'Sorry, sass-director could not create the ' + importDirectory + ' directory.');
		}
	});

	importBasenames.forEach(function (importBasename) {
		try {
			fs.closeSync(fs.openSync(importBasename, 'w'));
		} catch (error) {
			exit(1, 'Sorry, sass-director could not create the ' + importBasename + ' file.');
		}
	});

	exit(0, 'Hurray, sass-director created ' + importDirectories.length + ' directories and ' + importBasenames.length + ' files!');
});
<commit_msg>added ASCII art -- because every CLI needs ASCII art<commit_after>#!/usr/bin/env node

function mkdir(path) {
	function create(path) {
		if (path) {
			if (!fs.existsSync(path) || !fs.statSync(path).isDirectory()) {
				try {
					fs.mkdirSync(path);
				} catch (error) {
					return false;
				}
			}
		}

		return true;
	}

	path.replace(/^\/+/, '').split(/\/+/).reduce(function (previousValue, currentValue) {
		create('/' + previousValue);

		return previousValue + '/' + currentValue;
	});

	return create(path);
}

function exit(code, message) {
	console.log(message);

	process.exit(code || 0);
}

var
fs = require('fs'),
path = require('path'),
manifestFile = 2 in process.argv ? path.resolve(process.argv[2]) : '',
baseDirectory = 3 in process.argv ? path.resolve(process.argv[3]).replace(/\/+$/, '') : path.dirname(manifestFile),
ascii = '                                       \r\n                  -:..``                         \r\n                +hhoohMMd+\/oo                    \r\n              +``+mmooydssdMM+--:-`              \r\n              No  mMh  yMN``+mmoosdyoyhy\/--:.    \r\n             .yy-.+NM: .MMo  mMd  yMN``\/Nmoos:   \r\n             -++++++++\/\/syy-.+NN: .NMs  dMd  s+  \r\n             \/+++++++++++++++++++\/\/oyy-.\/mN\/ `.  \r\n            `++++++++++++++++++++++++++++++++:   \r\n            .++++++++++++++++++++++++++++++++.   \r\n            :+++++++++++++++++++++++++++++++\/    \r\n            ++++++++++++++++++++++++++++++++-    \r\n           `++++++++++++++++++++++++++++++++     \r\n            `.--::\/\/+++++++++++++++++++++++:     \r\n                      ``..--:\/\/++++++++++++`     \r\n                                 ``..--::\/-      \r\n\r\n                                      \r\n _____                ______ _               _             \r\n\/  ___|               |  _  (_)             | |            \r\n\\ `--.  __ _ ___ ___  | | | |_ _ __ ___  ___| |_ ___  _ __ \r\n `--. \\\/ _` \/ __\/ __| | | | | | \'__\/ _ \\\/ __| __\/ _ \\| \'__|\r\n\/\\__\/ \/ (_| \\__ \\__ \\ | |\/ \/| | | |  __\/ (__| || (_) | |   \r\n\\____\/ \\__,_|___\/___\/ |___\/ |_|_|  \\___|\\___|\\__\\___\/|_|   \r\n\n';

if (process.argv.length < 3) {
	exit(1, ascii + 'Usage: sass-director <manifest-file>. Use sass-director -h for more information');
}

if (!fs.existsSync(manifestFile)) {
	exit(1, 'Sorry, sass-director could not access ' + manifestFile + '.');
}

if (!mkdir(baseDirectory)) {
	exit(1, 'Sorry, sass-director could not access ' + baseDirectory + '.');
}

fs.readFile(manifestFile, 'utf8', function (error, data) {
	if (error) {
		exit(1, 'Sorry, sass-director could not access ' + manifestFile + '.');
	}

	var
	importStatements = data.match(/^[ \t]*@import[ \t]+(['"])(.+?)\1/mg),
	importDirectories = [],
	importBasenames = [];

	if (importStatements) {
		importStatements.forEach(function (importStatement) {
			var
			importPath = importStatement.match(/^[ \t]*@import[ \t]+(['"])(.+?)\1/)[2];

			importPath = importPath.match(/\.scss$/) ? importPath : importPath + '.scss';

			var
			importDirectory = baseDirectory + '/' + path.dirname(importPath),
			importBasename = importDirectory + '/_' + path.basename(importPath);

			if (!fs.existsSync(importDirectory) && importDirectories.indexOf(importDirectory) === -1) {
				importDirectories.push(importDirectory);
			}

			if (!fs.existsSync(importBasename) && importDirectories.indexOf(importBasename) === -1) {
				importBasenames.push(importBasename);
			}
		});
	}

	importDirectories.forEach(function (importDirectory) {
		if (!mkdir(importDirectory)) {
			exit(1, 'Sorry, sass-director could not create the ' + importDirectory + ' directory.');
		}
	});

	importBasenames.forEach(function (importBasename) {
		try {
			fs.closeSync(fs.openSync(importBasename, 'w'));
		} catch (error) {
			exit(1, 'Sorry, sass-director could not create the ' + importBasename + ' file.');
		}
	});

	exit(0, 'Hurray, sass-director created ' + importDirectories.length + ' directories and ' + importBasenames.length + ' files!');
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

CLASS({
  package: 'foam.flow',
  name: 'Slides',
  extendsModel: 'foam.flow.Element',

  properties: [
    {
      name: 'slides',
      singular: 'slide',
      factory: function() { return []; }
    },
    {
      name: 'currentSlide',
      getter: function() { return this.slides[this.position-1]; },
      transient: true
    },
    {
      model_: 'IntProperty',
      name: 'position',
      displayWidth: 5,
      defaultValue: 1,
      preSet: function(o, n) {
        return Math.max(1, Math.min(n, this.slides.length));
      },
      postSet: function(_, p) {
        if ( ! this.$ ) return;
        this.currentSlide_ && this.currentSlide_.destroy && this.currentSlide_.destroy();
        var v = this.currentSlide_ = this.currentSlide();
        this.$.querySelector('deck').innerHTML = v.toHTML();
        v.initHTML();
      }
    }
  ],

  methods: {
    fromElement: function(e) {
      var slides = [];
      for ( var i = 0 ; i < e.children.length ; i++ )
        if ( e.children[i].nodeName === 'slide' )
          slides.push(ViewFactoryProperty.ADAPT.defaultValue(null, e.children[i].innerHTML));
      this.slides = slides;
    }
  },

  actions: [
    {
      name: 'back',
      label: '<',
      isEnabled: function() { return this.position > 1; },
      action: function() {
        this.position--;
      }
    },
    {
      name: 'forth',
      label: '>',
      isEnabled: function() { return this.position < this.slides.length; },
      action: function() {
        this.position++;
      }
    }
  ],

  templates: [
    function CSS() {/*
      slides * {
        box-sizing: border-box;
      }
      slides, slides > deck, slides > controls {
        display: block;
      }
      slides > deck {
        width: 100%;
        height: 90%;
        border: 1px solid black;
        overflow: auto;
        border: 1px solid gray;
      }
      slides > controls {
        width: 100%;
        height: 10%;
        border: 1px solid black;
        padding: 10px;
      }
      slides > controls input {
        vertical-align: top;
        width: 40px;
      }
      slides > controls .actionButton-back {
        margin-left: 100px;
      }
    */},
    function toInnerHTML() {/*
      <deck>
        <%= this.currentSlide() %>
      </deck>
      <controls>
        $$position of {{this.slides.length}} $$back $$forth
      </controls>
    */}
  ]
});
<commit_msg>Slides wasn't destroying the first slide.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

CLASS({
  package: 'foam.flow',
  name: 'Slides',
  extendsModel: 'foam.flow.Element',

  properties: [
    {
      name: 'slides',
      singular: 'slide',
      factory: function() { return []; }
    },
    {
      name: 'currentSlide',
      getter: function() { return this.slides[this.position-1]; },
      transient: true
    },
    {
      model_: 'IntProperty',
      name: 'position',
      displayWidth: 5,
      defaultValue: 1,
      preSet: function(o, n) {
        return Math.max(1, Math.min(n, this.slides.length));
      },
      postSet: function(_, p) {
        if ( ! this.$ ) return;
        this.currentSlide_ && this.currentSlide_.destroy && this.currentSlide_.destroy();
        var v = this.currentSlide_ = this.currentSlide();
        this.$.querySelector('deck').innerHTML = v.toHTML();
        v.initHTML();
      }
    }
  ],

  methods: {
    fromElement: function(e) {
      var slides = [];
      for ( var i = 0 ; i < e.children.length ; i++ )
        if ( e.children[i].nodeName === 'slide' )
          slides.push(ViewFactoryProperty.ADAPT.defaultValue(null, e.children[i].innerHTML));
      this.slides = slides;
    }
  },

  actions: [
    {
      name: 'back',
      label: '<',
      isEnabled: function() { return this.position > 1; },
      action: function() {
        this.position--;
      }
    },
    {
      name: 'forth',
      label: '>',
      isEnabled: function() { return this.position < this.slides.length; },
      action: function() {
        this.position++;
      }
    }
  ],

  templates: [
    function CSS() {/*
      slides * {
        box-sizing: border-box;
      }
      slides, slides > deck, slides > controls {
        display: block;
      }
      slides > deck {
        width: 100%;
        height: 90%;
        border: 1px solid black;
        overflow: auto;
        border: 1px solid gray;
      }
      slides > controls {
        width: 100%;
        height: 10%;
        border: 1px solid black;
        padding: 10px;
      }
      slides > controls input {
        vertical-align: top;
        width: 40px;
      }
      slides > controls .actionButton-back {
        margin-left: 100px;
      }
    */},
    function toInnerHTML() {/*
      <deck>
        <%= this.currentSlide_ = this.currentSlide() %>
      </deck>
      <controls>
        $$position of {{this.slides.length}} $$back $$forth
      </controls>
    */}
  ]
});
<|endoftext|>


<commit_before>/**#ADSR - Modulation
The cannonical four stage envelope.
## Example Usage##
`a = Sine();
e = ADSR();
a.mod("amp", e, "=");
e.trigger();

## Constructors
### syntax 1:
**param** *attack*: Integer in samples. The length of time in samples that it takes the envelope to reach its peak amplitude.
**param** *decay* : Integer in samples. The length of time in samples that it takes the envelope to decay from its peak to its sustain level.
**param** *sustain*: Integer in samples. The length of time the envelope maintains its sustain level
**param** *release* : Integer in samples. The length of time the envelope takes to fade from its sustain level to 0.
**param** *attackLevel* : Float. The peak level of the envelope, reached at the end of the attack stage.
**param** *sustainLevel* : Float. The sustain level of the envelope, reached at the end of the decay stage.
**/

/**###ADSR.run : method
Put the envelope at the start of its attack stage and run it.
**/

function ADSR(attack, decay, sustain, release, attackLevel, sustainLevel) {
	that = Gibberish.ADSR(G.time(attack), G.time(decay), G.time(sustain), G.time(release), attackLevel, sustainLevel);
	return that;
}

/**#Step- Modulation
A basic step sequencer
## Example Usage##
`a = Sine();
f = Step([140,280,100,200], _4);
a.mod("frequency", f);
`
## Constructors
### syntax 1:
**param** *values*: Array. An array of values to step through.
**param** *speed* : Integer in samples. The length of time for each step.
**/
function Step(steps, time) {
	that = Gibberish.Step(steps, G.time(time));
	return that;
}

/**#Line- Modulation
A simple one-directional ramp
## Example Usage##
`a = Sine();
l = Line(0, .5, _1, true);
a.mod("amp", l, "=");
`
## Constructor
**param** *startingValue*: Float. The starting value for the Line.
**param** *endingValue* : Float. The ending value for the Line.
**param** *time* : Integer (samples). The time it takes to travel from the start value to the end value.
**param** *shouldLoop* : Boolean. Whether or not the line should repeatedly travel from start to finish.
**/
function Line(start, end, time, loops){
	var that = Gibberish.Line(start, end, G.time(time), loops);

	return that;
}

function Follow(){
	var that = Gibberish.Follow();
	return that;
}

/**#Env- Modulation
A two-stage attack / decay envelope
## Example Usage##
`a = Sine();
l = Line(0, .5, _1, true);
a.mod("amp", l, "=");
`
## Constructor
**param** *attack*: Integer in samples. The length of time in samples that it takes the envelope to reach its peak amplitude.
**param** *decay* : Integer in samples. The length of time in samples that it takes the envelope to decay from its peak to 0.
**/
/**###Env.run : method
Put the envelope at the start of its attack stage and run it.
**/
function Env(attack, decay){
	var that = Gibberish.Env(G.time(attack), G.time(decay));

	return that;
}

// TODO: recreate this in Gibberish as a multi-break-point envelope
function Env2() {
	that = {
		value : 0,
		position : 0,
		values : [],
		durations : [],
		shouldLoop : false,
		phase : 0,
		active : true,
		increment : 0,
		modded : [],
		endFunction : null,
		mix: 1,
		end : function(func) {
			if(typeof func === "function") this.endFunction = func;
			return this;
		},

		generate : function() {
			if(this.active) {
				this.phase++;
				if(this.phase >= this.durations[this.position]) {
					this.phase = 0;
					this.position++;
					if(this.position >= this.durations.length) {
						// TODO: INTERESTING. Because this.active is set to false during one cycle, the value
						// is not restored in the audio callback. Oddly enough, this creates the expected behavior.
						this.active= false;
						this.position = 0;
						//G.log("NOT ACTIVE");
						if(this.endFunction != null) {
							this.endFunction();
						}
					}
					this.increment = (this.values[this.position] - this.value) / this.durations[this.position];
				}
				this.value += this.increment;
			}
		},

		trigger : function() {
			var start = (arguments.length % 2 === 0) ? 0 : 1;
			if(start) that.value = arguments[0];
			this.phase = 0;
			this.position = 0;
		},

		advance : function() {
			this.phase = 0;
			this.position++;

			this.increment = (this.values[this.position] - this.value) / this.durations[this.position];
		},
	};

	var start = (arguments.length % 2 === 0) ? 0 : 1;
	if(start) that.value = arguments[0];

	for(i = start; i < arguments.length - 1; i+=2) {
		that.values.push(arguments[i]);
		that.durations.push(arguments[i + 1]);
	}

	that.increment = (that.values[that.position] - that.value) / that.durations[that.position];

	function bpmCallback() {
		return function(percentageChangeForBPM) {
			for(var i = 0; i < this.durations.length; i++) {
				this.durations[i] *= percentageChangeForBPM;
			}
		}
	}

	Gibber.registerObserver("bpm", bpmCallback());

	Gibber.addModsAndFX.call(that);

	// define after addModsAndFX since it overrides the out function assigned by it
	that.out = function() {
		this.generate();
		return this.value;
	};

	return that;
}
<commit_msg>Follow bugfix<commit_after>/**#ADSR - Modulation
The cannonical four stage envelope.
## Example Usage##
`a = Sine();
e = ADSR();
a.mod("amp", e, "=");
e.trigger();

## Constructors
### syntax 1:
**param** *attack*: Integer in samples. The length of time in samples that it takes the envelope to reach its peak amplitude.
**param** *decay* : Integer in samples. The length of time in samples that it takes the envelope to decay from its peak to its sustain level.
**param** *sustain*: Integer in samples. The length of time the envelope maintains its sustain level
**param** *release* : Integer in samples. The length of time the envelope takes to fade from its sustain level to 0.
**param** *attackLevel* : Float. The peak level of the envelope, reached at the end of the attack stage.
**param** *sustainLevel* : Float. The sustain level of the envelope, reached at the end of the decay stage.
**/

/**###ADSR.run : method
Put the envelope at the start of its attack stage and run it.
**/

function ADSR(attack, decay, sustain, release, attackLevel, sustainLevel) {
	that = Gibberish.ADSR(G.time(attack), G.time(decay), G.time(sustain), G.time(release), attackLevel, sustainLevel);
	return that;
}

/**#Step- Modulation
A basic step sequencer
## Example Usage##
`a = Sine();
f = Step([140,280,100,200], _4);
a.mod("frequency", f);
`
## Constructors
### syntax 1:
**param** *values*: Array. An array of values to step through.
**param** *speed* : Integer in samples. The length of time for each step.
**/
function Step(steps, time) {
	that = Gibberish.Step(steps, G.time(time));
	return that;
}

/**#Line- Modulation
A simple one-directional ramp
## Example Usage##
`a = Sine();
l = Line(0, .5, _1, true);
a.mod("amp", l, "=");
`
## Constructor
**param** *startingValue*: Float. The starting value for the Line.
**param** *endingValue* : Float. The ending value for the Line.
**param** *time* : Integer (samples). The time it takes to travel from the start value to the end value.
**param** *shouldLoop* : Boolean. Whether or not the line should repeatedly travel from start to finish.
**/
function Line(start, end, time, loops){
	var that = Gibberish.Line(start, end, G.time(time), loops);

	return that;
}

function Follow(foo){
	var that = Gibberish.Follow(foo);
	return that;
}

/**#Env- Modulation
A two-stage attack / decay envelope
## Example Usage##
`a = Sine();
l = Line(0, .5, _1, true);
a.mod("amp", l, "=");
`
## Constructor
**param** *attack*: Integer in samples. The length of time in samples that it takes the envelope to reach its peak amplitude.
**param** *decay* : Integer in samples. The length of time in samples that it takes the envelope to decay from its peak to 0.
**/
/**###Env.run : method
Put the envelope at the start of its attack stage and run it.
**/
function Env(attack, decay){
	var that = Gibberish.Env(G.time(attack), G.time(decay));

	return that;
}

// TODO: recreate this in Gibberish as a multi-break-point envelope
function Env2() {
	that = {
		value : 0,
		position : 0,
		values : [],
		durations : [],
		shouldLoop : false,
		phase : 0,
		active : true,
		increment : 0,
		modded : [],
		endFunction : null,
		mix: 1,
		end : function(func) {
			if(typeof func === "function") this.endFunction = func;
			return this;
		},

		generate : function() {
			if(this.active) {
				this.phase++;
				if(this.phase >= this.durations[this.position]) {
					this.phase = 0;
					this.position++;
					if(this.position >= this.durations.length) {
						// TODO: INTERESTING. Because this.active is set to false during one cycle, the value
						// is not restored in the audio callback. Oddly enough, this creates the expected behavior.
						this.active= false;
						this.position = 0;
						//G.log("NOT ACTIVE");
						if(this.endFunction != null) {
							this.endFunction();
						}
					}
					this.increment = (this.values[this.position] - this.value) / this.durations[this.position];
				}
				this.value += this.increment;
			}
		},

		trigger : function() {
			var start = (arguments.length % 2 === 0) ? 0 : 1;
			if(start) that.value = arguments[0];
			this.phase = 0;
			this.position = 0;
		},

		advance : function() {
			this.phase = 0;
			this.position++;

			this.increment = (this.values[this.position] - this.value) / this.durations[this.position];
		},
	};

	var start = (arguments.length % 2 === 0) ? 0 : 1;
	if(start) that.value = arguments[0];

	for(i = start; i < arguments.length - 1; i+=2) {
		that.values.push(arguments[i]);
		that.durations.push(arguments[i + 1]);
	}

	that.increment = (that.values[that.position] - that.value) / that.durations[that.position];

	function bpmCallback() {
		return function(percentageChangeForBPM) {
			for(var i = 0; i < this.durations.length; i++) {
				this.durations[i] *= percentageChangeForBPM;
			}
		}
	}

	Gibber.registerObserver("bpm", bpmCallback());

	Gibber.addModsAndFX.call(that);

	// define after addModsAndFX since it overrides the out function assigned by it
	that.out = function() {
		this.generate();
		return this.value;
	};

	return that;
}
<|endoftext|>