<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var scenery = require( 'SCENERY/scenery' );

  // phet-io modules
  var assertInstanceOf = require( 'ifphetio!PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'ifphetio!PHET_IO/phetioInherit' );
  var TBoolean = require( 'ifphetio!PHET_IO/types/TBoolean' );
  var TFunctionWrapper = require( 'ifphetio!PHET_IO/types/TFunctionWrapper' );
  var TNumber = require( 'ifphetio!PHET_IO/types/TNumber' );
  var TObject = require( 'ifphetio!PHET_IO/types/TObject' );
  var TVoid = require( 'ifphetio!PHET_IO/types/TVoid' );

  /**
   * Wrapper type for phet/scenery's Node
   * @param node
   * @param phetioID
   * @constructor
   */
  function TNode( node, phetioID ) {
    TObject.call( this, node, phetioID );
    assertInstanceOf( node, phet.scenery.Node );
  }

  phetioInherit( TObject, 'TNode', TNode, {

    detach: {
      returnType: TVoid,
      parameterTypes: [],
      implementation: function() {
        this.instance.detach();
      },
      documentation: 'Detaches the node from its parents (if any)'
    },
    isVisible: {
      returnType: TBoolean,
      parameterTypes: [],
      implementation: function() {
        return this.instance.visible;
      },
      documentation: 'Gets a Boolean value indicating whether the node can be seen and interacted with'
    },

    setVisible: {
      returnType: TVoid,
      parameterTypes: [ TBoolean ],
      implementation: function( visible ) {
        this.instance.visible = visible;
      },
      documentation: 'Set whether the node will be visible (and interactive)'
    },

    setPickable: {
      returnType: TVoid,
      parameterTypes: [ TBoolean ],
      implementation: function( pickable ) {
        this.instance.pickable = pickable;
      },
      documentation: 'Set whether the node will be pickable (and hence interactive)'
    },

    isPickable: {
      returnType: TBoolean,
      parameterTypes: [],
      implementation: function() {
        return this.instance.pickable;
      },
      documentation: 'Gets whether the node is pickable (and hence interactive)'
    },

    addPickableListener: {
      returnType: TVoid,
      parameterTypes: [ TFunctionWrapper( TVoid, [ TBoolean ] ) ],
      implementation: function( callback ) {
        var inst = this.instance;
        this.instance.on( 'pickability', function() {
          callback( inst.isPickable() );
        } );
      },
      documentation: 'Adds a listener for when pickability of the node changes'
    },

    addVisibleListener: {
      returnType: TVoid,
      parameterTypes: [ TFunctionWrapper( TVoid, [ TBoolean ] ) ],
      implementation: function( callback ) {
        var inst = this.instance;
        this.instance.on( 'visibility', function() {
          callback( inst.isVisible() );
        } );
      },
      documentation: 'Adds a listener for when visibility of the node changes'
    },

    setOpacity: {
      returnType: TVoid,
      parameterTypes: [ TNumber ],
      implementation: function( opacity ) {
        this.instance.opacity = opacity;
      },
      documentation: 'Set opacity between 0-1 (inclusive)'
    },

    setRotation: {
      returnType: TVoid,
      parameterTypes: [ TNumber ],
      implementation: function( rotation ) {
        this.instance.rotation = rotation;
      },
      documentation: 'Set the rotation of the node, in radians'
    }
  }, {
    documentation: 'The base type for graphical and potentially interactive objects'
  } );

  scenery.register( 'TNode', TNode );

  return TNode;
} );

<commit_msg>Use toStateObject instead of phetioInstanceMetadata, see https://github.com/phetsims/phet-io/issues/1213<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var scenery = require( 'SCENERY/scenery' );

  // phet-io modules
  var assertInstanceOf = require( 'ifphetio!PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'ifphetio!PHET_IO/phetioInherit' );
  var TBoolean = require( 'ifphetio!PHET_IO/types/TBoolean' );
  var TFunctionWrapper = require( 'ifphetio!PHET_IO/types/TFunctionWrapper' );
  var TNumber = require( 'ifphetio!PHET_IO/types/TNumber' );
  var TObject = require( 'ifphetio!PHET_IO/types/TObject' );
  var TVoid = require( 'ifphetio!PHET_IO/types/TVoid' );

  /**
   * Wrapper type for phet/scenery's Node
   * @param node
   * @param phetioID
   * @constructor
   */
  function TNode( node, phetioID ) {
    TObject.call( this, node, phetioID );
    assertInstanceOf( node, phet.scenery.Node );
  }

  phetioInherit( TObject, 'TNode', TNode, {

    detach: {
      returnType: TVoid,
      parameterTypes: [],
      implementation: function() {
        this.instance.detach();
      },
      documentation: 'Detaches the node from its parents (if any)'
    },
    isVisible: {
      returnType: TBoolean,
      parameterTypes: [],
      implementation: function() {
        return this.instance.visible;
      },
      documentation: 'Gets a Boolean value indicating whether the node can be seen and interacted with'
    },

    setVisible: {
      returnType: TVoid,
      parameterTypes: [ TBoolean ],
      implementation: function( visible ) {
        this.instance.visible = visible;
      },
      documentation: 'Set whether the node will be visible (and interactive)'
    },

    setPickable: {
      returnType: TVoid,
      parameterTypes: [ TBoolean ],
      implementation: function( pickable ) {
        this.instance.pickable = pickable;
      },
      documentation: 'Set whether the node will be pickable (and hence interactive)'
    },

    isPickable: {
      returnType: TBoolean,
      parameterTypes: [],
      implementation: function() {
        return this.instance.pickable;
      },
      documentation: 'Gets whether the node is pickable (and hence interactive)'
    },

    addPickableListener: {
      returnType: TVoid,
      parameterTypes: [ TFunctionWrapper( TVoid, [ TBoolean ] ) ],
      implementation: function( callback ) {
        var inst = this.instance;
        this.instance.on( 'pickability', function() {
          callback( inst.isPickable() );
        } );
      },
      documentation: 'Adds a listener for when pickability of the node changes'
    },

    addVisibleListener: {
      returnType: TVoid,
      parameterTypes: [ TFunctionWrapper( TVoid, [ TBoolean ] ) ],
      implementation: function( callback ) {
        var inst = this.instance;
        this.instance.on( 'visibility', function() {
          callback( inst.isVisible() );
        } );
      },
      documentation: 'Adds a listener for when visibility of the node changes'
    },

    setOpacity: {
      returnType: TVoid,
      parameterTypes: [ TNumber ],
      implementation: function( opacity ) {
        this.instance.opacity = opacity;
      },
      documentation: 'Set opacity between 0-1 (inclusive)'
    },

    setRotation: {
      returnType: TVoid,
      parameterTypes: [ TNumber ],
      implementation: function( rotation ) {
        this.instance.rotation = rotation;
      },
      documentation: 'Set the rotation of the node, in radians'
    }
  }, {
    toStateObject: function( node ) {
      return {
        visible: node.isVisible(),
        pickable: node.isPickable(),
        opacity: node.opacity
      };
    },
    documentation: 'The base type for graphical and potentially interactive objects'
  } );

  scenery.register( 'TNode', TNode );

  return TNode;
} );

<|endoftext|>


<commit_before>// Copyright 2015, University of Colorado Boulder

/**
 * Make the package.json contents available to the simulation, so it can access the version, sim name, etc.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var joist = require( 'JOIST/joist' );

  // strings
  var packageString = require( 'text!REPOSITORY/package.json' );

  var packageJSON = JSON.parse( packageString );

  joist.register( 'packageJSON', packageJSON );

  return packageJSON;
} );<commit_msg>Splice phet-io into version name, see https://github.com/phetsims/chipper/issues/507<commit_after>// Copyright 2015, University of Colorado Boulder

/**
 * Make the package.json contents available to the simulation, so it can access the version, sim name, etc.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var joist = require( 'JOIST/joist' );

  // strings
  var packageString = require( 'text!REPOSITORY/package.json' );

  // TODO: duplicated with getVersionForBrand.js in chipper
  // HACK ALERT: Patch in the phet-io substring if it is a phet-io brand.
  // See https://github.com/phetsims/chipper/issues/507
  var getVersionForBrand = function( brand, version ) {

    if ( brand === 'phet-io' ) {

      // Insert phetio into the version name
      // 1.2.0-dev.31 => 1.2.0-phetiodev.31
      // 1.2.0 => 1.2.0-phetio

      // if there is a hyphen, put phetio before it
      // if there is no hyphen, append phetio
      var hyphenIndex = version.indexOf( '-' );
      if ( hyphenIndex >= 0 ) {
        return version.substring( 0, hyphenIndex + 1 ) + 'phetio' + version.substring( hyphenIndex + 1 );
      }
      else {
        return version + '-phetio';
      }
    }
    return version;
  };

  var packageJSON = JSON.parse( packageString );

  packageJSON.version = getVersionForBrand( phet.chipper.brand, packageJSON.version );

  joist.register( 'packageJSON', packageJSON );

  return packageJSON;
} );<|endoftext|>


<commit_before>

function parsesize (size) {
	if (size == "T") size = "Tiny";
	if (size == "S") size = "Small";
	if (size == "M") size = "Medium";
	if (size == "L") size = "Large";
	if (size == "H") size = "Huge";
	if (size == "G") size = "Gargantuan";
	return size;
}

function parseschool (school) {
	if (school == "A") return "abjuration";
	if (school == "EV") return "evocation";
	if (school == "EN") return "enchantment";
	if (school == "I") return "illusion";
	if (school == "D") return "divination";
	if (school == "N") return "necromancy";
	if (school == "T") return "transmutation";
	if (school == "C") return "conjuration";
	return "";
}

function parsespelllevel (level) {
	if (isNaN (level)) return "";
	if (level === "0") return "cantrip"
	if (level === "2") return level+"nd";
	if (level === "3") return level+"rd";
	if (level === "1") return level+"st";
	return level+"th";
}

function asc_sort(a, b){
    return ($(b).text()) < ($(a).text()) ? 1 : -1;
}

function dec_sort(a, b){
    return ($(b).text()) > ($(a).text()) ? 1 : -1;
}

window.onload = loadspells;

function loadspells() {
	tabledefault = $("#stats").html();

	var spelllist = spelldata.compendium.spell;

		for (var i = 0; i < spelllist.length; i++) {
			var curspell = spelllist[i];
			var name = curspell.name;
			if (curspell.level[0] === "P") name += " (Psionics)";

			var leveltext = parsespelllevel(curspell.level);
			if (parseInt(curspell.level) > 0) leveltext += " level"
			if (curspell.ritual === "YES") leveltext += " (ritual)";

			var schooltext = parseschool(curspell.school);
			if (!schooltext) {
				if (curspell.level[1] === "D") {
					schooltext = curspell.classes.split(/Mystic \(/g)[1].split(")")[0];
					schooltext += " Discipline";
					leveltext = "Discipline";
				} else if (curspell.level[1] === "T") {
					schooltext = "Psionic Talent";
					leveltext = "Talent";
				}
			}

			$("ul.spells").append("
"+name+" "+leveltext+" "+schooltext+" "+curspell.classes+"
");

			if (!$("select.levelfilter:contains('"+parsespelllevel(curspell.level)+"')").length) {
				$("select.levelfilter").append("<option value='"+curspell.level+"'>"+parsespelllevel(curspell.level)+"</option>");
			}

			if (!$("select.schoolfilter:contains('"+parseschool (curspell.school)+"')").length) {
				$("select.schoolfilter").append("<option value='"+parseschool (curspell.school)+"'>"+parseschool (curspell.school)+"</option>");
			}

			var classlist = curspell.classes.split(",");
			for (var a = 0; a < classlist.length; a++) {
				if (classlist[a][0] === " ") classlist[a] = classlist[a].replace(/^\s+|\s+$/g, "")
				if (!$("select.classfilter option[value='"+classlist[a]+"']").length) {
					$("select.classfilter").append("<option title=\""+classlist[a]+"\" value='"+classlist[a]+"'>"+classlist[a]+"</option>")
				}
			}

		}

		$("select.levelfilter option").sort(asc_sort).appendTo('select.levelfilter');
		$("select.levelfilter option[value=1]").before($("select.levelfilter option[value=All]"));
		$("select.levelfilter option[value=1]").before($("select.levelfilter option[value=0]"));
		$("select.levelfilter").val("All");

		$("select.schoolfilter option").sort(asc_sort).appendTo('select.schoolfilter');
		$("select.schoolfilter").val("All");

		$("select.classfilter option").sort(asc_sort).appendTo('select.classfilter');
		$("select.classfilter").val("All");

		var options = {
			valueNames: ['name', 'level', 'school', 'classes'],
			listClass: "spells"
		}

		var spellslist = new List("listcontainer", options);
		spellslist.sort ("name")

		$("ul.list li").mousedown(function(e) {
			if (e.which === 2) {
				console.log("#"+$(this).attr("data-link").toLowerCase())
				window.open("#"+$(this).attr("data-link").toLowerCase(), "_blank").focus();
				e.preventDefault();
				e.stopPropagation();
				return;
			}
		});

		$("ul.list li").click(function(e) {
			usespell($(this).attr("id"));
			document.title = decodeURIComponent($(this).attr("data-name")).replace("%27","'") + " - 5etools Spells";
			window.location = "#"+$(this).attr("data-link").toLowerCase();
		});

		if (window.location.hash.length) {
			$("ul.list li[data-link='"+window.location.hash.split("#")[1].toLowerCase()+"']:eq(0)").click();
		} else $("ul.list li:eq(0)").click();

		$("form#filtertools select").change(function(){
			var levelfilter = $("select.levelfilter").val();
			if (levelfilter !== "All") {

				if (levelfilter[0] !== "d" && levelfilter[0] !== "t") {
					levelfilter = parsespelllevel (levelfilter);
					if (levelfilter !== "cantrip") {
						levelfilter = levelfilter + " level"
					} else levelfilter = "cantrip";
					if ($(".ritualfilter").val() === "Rituals") levelfilter = levelfilter + " (ritual)"
				}
			} else if ($(".ritualfilter").val() === "Rituals") levelfilter = "(ritual)"

			var schoolfilter = $("select.schoolfilter").val();
			var classfilter = $("select.classfilter").val();

			spellslist.filter(function(item) {
				var rightlevel = false;
				var rightschool = false;
				var rightclass = false;
				if (levelfilter === "All" || item.values().level.indexOf(levelfilter) !== -1) rightlevel = true;
				if (schoolfilter === "All" || item.values().school === schoolfilter) rightschool = true;
				var classes = item.values().classes.split(", ");
				for (var c = 0; c < classes.length; c++) {
					if (classes[c] === classfilter) rightclass = true;
				}
				if (classfilter === "All") rightclass = true;
				if (rightlevel && rightschool && rightclass) return true;
				return false;
			});
		});

		$("#filtertools small").click(function() {
			$("#search").val("psionics");
			spellslist.search("psionics");
		})

		$("#filtertools button.sort").on("click", function() {
			if ($(this).attr("sortby") === "asc") {
				$(this).attr("sortby", "desc");
			} else $(this).attr("sortby", "asc");
			spellslist.sort($(this).data("sort"), { order: $(this).attr("sortby"), sortFunction: sortspells });
		});

			// reset button
			$("button#reset").click(function() {
				$("#filtertools select").val("All");
				$("#search").val("");
				spellslist.search("");
				spellslist.filter();
				spellslist.sort("name");
				spellslist.update();
			})
}

function sortspells(a, b, o) {
	if (o.valueName === "name") {
		return ((b._values.name.toLowerCase()) > (a._values.name.toLowerCase())) ? 1 : -1;
	}

	if (o.valueName === "school") {
		return ((b._values.school.toLowerCase()) > (a._values.school.toLowerCase())) ? 1 : -1;
	}

	if (o.valueName === "level") {
		var alevel = a._values.level.replace(" ", "").replace("cantrip", "0")[0];
		var blevel = b._values.level.replace(" ", "").replace("cantrip", "0")[0];
		if (alevel === "D") alevel = "10";
		if (blevel === "D") blevel = "10";
		if (alevel === "T") alevel = "11";
		if (blevel === "T") blevel = "11";
		return (parseInt(blevel) > parseInt(alevel)) ? 1 : -1;
	}

	return 1;

}

function usespell (id) {
			$("#stats").html(tabledefault);
			var spelllist = spelldata.compendium.spell;
			var curspell = spelllist[id];

			$("th#name").html(curspell.name);

			if (curspell.level[0] !== "P") {
				$("td span#school").html(parseschool(curspell.school));
				if (curspell.level === "0") {
					$("td span#school").css('textTransform', 'capitalize');
					$("td span#level").css('textTransform', 'lowercase!important');
					$("td span#level").html(" cantrip").detach().appendTo("td span#school");
				} else {
					$("td span#school").css('textTransform', 'lowercase');
					$("td span#level").html(parsespelllevel (curspell.level)+"-level");
				}

				if (curspell.ritual === "YES") {
					$("td span#ritual").show();
				} else $("td span#ritual").hide();

				$("td#components span").html(curspell.components);
				$("td#range span").html(curspell.range);
				$("td#castingtime span").html(curspell.time);
				$("td#duration span").html(curspell.duration);
			} else {
				var psitype = "";
				if (curspell.level[1] === "D") {
					psitype = curspell.classes.split(/Mystic \(/g)[1].split(")")[0];
					psitype += " Discipline";
				} else if (curspell.level[1] === "T") {
					psitype = "Psionic Talent";
				}
				$("td#levelschoolritual").html(psitype);
				$("td#castingtime").html("");
				$("td#range").html("");
				$("td#components").html("");
				$("td#duration").html("");
			}

			$("tr.text").remove();
			var textlist = curspell.text;
			var texthtml = "";

			if (textlist[0].length === 1) {
				texthtml = "
"+textlist+"
";
			} else for (var i = 0; i < textlist.length; i++) {
				if (!textlist[i]) continue;
				if (curspell.level[0] !== "P") {
					texthtml = texthtml + "
"+textlist[i].replace("At Higher Levels: ", "At Higher Levels: ").replace("This spell can be found in the Elemental Evil Player's Companion","")+"
";
				} else {
					texthtml = texthtml + "
"+textlist[i].replace(/^.*(\(.*psi.*?\)|Psychic Focus)\./g,"$&")+"
";
				}
			}
			$("tr#text").after("
"+texthtml+"
");

			$("td#classes span").html(curspell.classes);

			return;
		};
<commit_msg>Revert "Revert "Fixed bestial form formatting""<commit_after>

function parsesize (size) {
	if (size == "T") size = "Tiny";
	if (size == "S") size = "Small";
	if (size == "M") size = "Medium";
	if (size == "L") size = "Large";
	if (size == "H") size = "Huge";
	if (size == "G") size = "Gargantuan";
	return size;
}

function parseschool (school) {
	if (school == "A") return "abjuration";
	if (school == "EV") return "evocation";
	if (school == "EN") return "enchantment";
	if (school == "I") return "illusion";
	if (school == "D") return "divination";
	if (school == "N") return "necromancy";
	if (school == "T") return "transmutation";
	if (school == "C") return "conjuration";
	return "";
}

function parsespelllevel (level) {
	if (isNaN (level)) return "";
	if (level === "0") return "cantrip"
	if (level === "2") return level+"nd";
	if (level === "3") return level+"rd";
	if (level === "1") return level+"st";
	return level+"th";
}

function asc_sort(a, b){
    return ($(b).text()) < ($(a).text()) ? 1 : -1;
}

function dec_sort(a, b){
    return ($(b).text()) > ($(a).text()) ? 1 : -1;
}

window.onload = loadspells;

function loadspells() {
	tabledefault = $("#stats").html();

	var spelllist = spelldata.compendium.spell;

		for (var i = 0; i < spelllist.length; i++) {
			var curspell = spelllist[i];
			var name = curspell.name;
			if (curspell.level[0] === "P") name += " (Psionics)";

			var leveltext = parsespelllevel(curspell.level);
			if (parseInt(curspell.level) > 0) leveltext += " level"
			if (curspell.ritual === "YES") leveltext += " (ritual)";

			var schooltext = parseschool(curspell.school);
			if (!schooltext) {
				if (curspell.level[1] === "D") {
					schooltext = curspell.classes.split(/Mystic \(/g)[1].split(")")[0];
					schooltext += " Discipline";
					leveltext = "Discipline";
				} else if (curspell.level[1] === "T") {
					schooltext = "Psionic Talent";
					leveltext = "Talent";
				}
			}

			$("ul.spells").append("
"+name+" "+leveltext+" "+schooltext+" "+curspell.classes+"
");

			if (!$("select.levelfilter:contains('"+parsespelllevel(curspell.level)+"')").length) {
				$("select.levelfilter").append("<option value='"+curspell.level+"'>"+parsespelllevel(curspell.level)+"</option>");
			}

			if (!$("select.schoolfilter:contains('"+parseschool (curspell.school)+"')").length) {
				$("select.schoolfilter").append("<option value='"+parseschool (curspell.school)+"'>"+parseschool (curspell.school)+"</option>");
			}

			var classlist = curspell.classes.split(",");
			for (var a = 0; a < classlist.length; a++) {
				if (classlist[a][0] === " ") classlist[a] = classlist[a].replace(/^\s+|\s+$/g, "")
				if (!$("select.classfilter option[value='"+classlist[a]+"']").length) {
					$("select.classfilter").append("<option title=\""+classlist[a]+"\" value='"+classlist[a]+"'>"+classlist[a]+"</option>")
				}
			}

		}

		$("select.levelfilter option").sort(asc_sort).appendTo('select.levelfilter');
		$("select.levelfilter option[value=1]").before($("select.levelfilter option[value=All]"));
		$("select.levelfilter option[value=1]").before($("select.levelfilter option[value=0]"));
		$("select.levelfilter").val("All");

		$("select.schoolfilter option").sort(asc_sort).appendTo('select.schoolfilter');
		$("select.schoolfilter").val("All");

		$("select.classfilter option").sort(asc_sort).appendTo('select.classfilter');
		$("select.classfilter").val("All");

		var options = {
			valueNames: ['name', 'level', 'school', 'classes'],
			listClass: "spells"
		}

		var spellslist = new List("listcontainer", options);
		spellslist.sort ("name")

		$("ul.list li").mousedown(function(e) {
			if (e.which === 2) {
				console.log("#"+$(this).attr("data-link").toLowerCase())
				window.open("#"+$(this).attr("data-link").toLowerCase(), "_blank").focus();
				e.preventDefault();
				e.stopPropagation();
				return;
			}
		});

		$("ul.list li").click(function(e) {
			usespell($(this).attr("id"));
			document.title = decodeURIComponent($(this).attr("data-name")).replace("%27","'") + " - 5etools Spells";
			window.location = "#"+$(this).attr("data-link").toLowerCase();
		});

		if (window.location.hash.length) {
			$("ul.list li[data-link='"+window.location.hash.split("#")[1].toLowerCase()+"']:eq(0)").click();
		} else $("ul.list li:eq(0)").click();

		$("form#filtertools select").change(function(){
			var levelfilter = $("select.levelfilter").val();
			if (levelfilter !== "All") {

				if (levelfilter[0] !== "d" && levelfilter[0] !== "t") {
					levelfilter = parsespelllevel (levelfilter);
					if (levelfilter !== "cantrip") {
						levelfilter = levelfilter + " level"
					} else levelfilter = "cantrip";
					if ($(".ritualfilter").val() === "Rituals") levelfilter = levelfilter + " (ritual)"
				}
			} else if ($(".ritualfilter").val() === "Rituals") levelfilter = "(ritual)"

			var schoolfilter = $("select.schoolfilter").val();
			var classfilter = $("select.classfilter").val();

			spellslist.filter(function(item) {
				var rightlevel = false;
				var rightschool = false;
				var rightclass = false;
				if (levelfilter === "All" || item.values().level.indexOf(levelfilter) !== -1) rightlevel = true;
				if (schoolfilter === "All" || item.values().school === schoolfilter) rightschool = true;
				var classes = item.values().classes.split(", ");
				for (var c = 0; c < classes.length; c++) {
					if (classes[c] === classfilter) rightclass = true;
				}
				if (classfilter === "All") rightclass = true;
				if (rightlevel && rightschool && rightclass) return true;
				return false;
			});
		});

		$("#filtertools small").click(function() {
			$("#search").val("psionics");
			spellslist.search("psionics");
		})

		$("#filtertools button.sort").on("click", function() {
			if ($(this).attr("sortby") === "asc") {
				$(this).attr("sortby", "desc");
			} else $(this).attr("sortby", "asc");
			spellslist.sort($(this).data("sort"), { order: $(this).attr("sortby"), sortFunction: sortspells });
		});

			// reset button
			$("button#reset").click(function() {
				$("#filtertools select").val("All");
				$("#search").val("");
				spellslist.search("");
				spellslist.filter();
				spellslist.sort("name");
				spellslist.update();
			})
}

function sortspells(a, b, o) {
	if (o.valueName === "name") {
		return ((b._values.name.toLowerCase()) > (a._values.name.toLowerCase())) ? 1 : -1;
	}

	if (o.valueName === "school") {
		return ((b._values.school.toLowerCase()) > (a._values.school.toLowerCase())) ? 1 : -1;
	}

	if (o.valueName === "level") {
		var alevel = a._values.level.replace(" ", "").replace("cantrip", "0")[0];
		var blevel = b._values.level.replace(" ", "").replace("cantrip", "0")[0];
		if (alevel === "D") alevel = "10";
		if (blevel === "D") blevel = "10";
		if (alevel === "T") alevel = "11";
		if (blevel === "T") blevel = "11";
		return (parseInt(blevel) > parseInt(alevel)) ? 1 : -1;
	}

	return 1;

}

function usespell (id) {
			$("#stats").html(tabledefault);
			var spelllist = spelldata.compendium.spell;
			var curspell = spelllist[id];

			$("th#name").html(curspell.name);

			if (curspell.level[0] !== "P") {
				$("td span#school").html(parseschool(curspell.school));
				if (curspell.level === "0") {
					$("td span#school").css('textTransform', 'capitalize');
					$("td span#level").css('textTransform', 'lowercase!important');
					$("td span#level").html(" cantrip").detach().appendTo("td span#school");
				} else {
					$("td span#school").css('textTransform', 'lowercase');
					$("td span#level").html(parsespelllevel (curspell.level)+"-level");
				}

				if (curspell.ritual === "YES") {
					$("td span#ritual").show();
				} else $("td span#ritual").hide();

				$("td#components span").html(curspell.components);
				$("td#range span").html(curspell.range);
				$("td#castingtime span").html(curspell.time);
				$("td#duration span").html(curspell.duration);
			} else {
				var psitype = "";
				if (curspell.level[1] === "D") {
					psitype = curspell.classes.split(/Mystic \(/g)[1].split(")")[0];
					psitype += " Discipline";
				} else if (curspell.level[1] === "T") {
					psitype = "Psionic Talent";
				}
				$("td#levelschoolritual").html(psitype);
				$("td#castingtime").html("");
				$("td#range").html("");
				$("td#components").html("");
				$("td#duration").html("");
			}

			$("tr.text").remove();
			var textlist = curspell.text;
			var texthtml = "";

			if (textlist[0].length === 1) {
				texthtml = "
"+textlist+"
";
			} else for (var i = 0; i < textlist.length; i++) {
				if (!textlist[i]) continue;
				if (curspell.level[0] !== "P") {
					texthtml = texthtml + "
"+textlist[i].replace("At Higher Levels: ", "At Higher Levels: ").replace("This spell can be found in the Elemental Evil Player's Companion","")+"
";
				} else {
					texthtml = texthtml + "
"+textlist[i].replace(/^.*(\(.*psi.*?\)|Psychic Focus|Bestial Transformation)\./g,"$&")+"
";
				}
			}
			$("tr#text").after("
"+texthtml+"
");

			$("td#classes span").html(curspell.classes);

			return;
		};
<|endoftext|>


<commit_before>define(["underscore", "jquery"], function(_, $) {
    var utils = new (function() {

        this.initialize = function() {

        };

        this.httpRequest = function(method, url, callback, disableCaching) {
            var requestObj = {
                type: method,
                url: url
            };
            if (disableCaching === true) {
                requestObj.cache = false;
            }

            $.ajax(requestObj).always(callback); // the callback is called also if the request fails
        };

        // Call onComplete with an array containing the files data.
        // filesBasePath is an optional string that will be used as base for the urls.
        this.fetchData = function(fileURLs, filesBasePath, onComplete, disableCaching) {
            var files = [];

            var filesLoaded = 0;
            _.each(fileURLs, function(fileURL, index) {
                var fileURL = fileURL;
                if (filesBasePath) fileURL = filesBasePath+"/"+fileURL;

                this.httpRequest("get", fileURL, _.bind(function(data) {
                    files[index] = data; // replace script relative url with its content
                    filesLoaded++;

                    if (filesLoaded === fileURLs.length) {
                        // files fetch complete
                        onComplete(files);
                    }
                }, this), disableCaching);
            }, this);
        };

        // String utility functions.
        this.string = {

            // Based on http://stackoverflow.com/a/498995
            trim: function(target) {
                return target.replace(/^\s+|\s+$/g, '');
            },

            // Based on http://stackoverflow.com/a/1981366
            removeMultipleSpaces: function(target) {
                return target.replace(/\s{2,}/g, ' ');
            },

            // Return the simplified version of target, i.e. a trimmed string with multiple spaces removed
            simplify: function(target) {
                return this.removeMultipleSpaces(this.trim(target));
            },

            // Based on http://stackoverflow.com/a/646643
            startsWith: function(target, str) {
                return target.slice(0, str.length) == str;
            },
            endsWith: function(target, str) {
                return target.slice(-str.length) == str;
            },

            // remove first and last char
            removeBorders: function(target) {
                target = target.substring(1); // first
                target = target.substring(0, target.length-1); // last
                return target;
            }
        }

        this.initialize();
    })();
    return utils;
});
<commit_msg>#52 | $.ajax: prevent automatic js execution<commit_after>define(["underscore", "jquery"], function(_, $) {
    var utils = new (function() {

        this.initialize = function() {

        };

        this.httpRequest = function(method, url, callback, disableCaching) {
            var requestObj = {
                type: method,
                url: url,
                dataType: 'text' // disable automatic js execution
            };
            if (disableCaching === true) {
                requestObj.cache = false;
            }

            $.ajax(requestObj)
                .done(function(data) {
                    callback(data);
                })
                .fail(function(jqXHR, textStatus, errorThrown) {
                    console.error('httpRequest fail', url, textStatus, errorThrown);
                })
        };

        // Call onComplete with an array containing the files data.
        // filesBasePath is an optional string that will be used as base for the urls.
        this.fetchData = function(fileURLs, filesBasePath, onComplete, disableCaching) {
            var files = [];

            var filesLoaded = 0;
            _.each(fileURLs, function(fileURL, index) {
                var fileURL = fileURL;
                if (filesBasePath) fileURL = filesBasePath+"/"+fileURL;

                this.httpRequest("get", fileURL, _.bind(function(data) {
                    files[index] = data; // replace script relative url with its content
                    filesLoaded++;

                    if (filesLoaded === fileURLs.length) {
                        // files fetch complete
                        onComplete(files);
                    }
                }, this), disableCaching);
            }, this);
        };

        // String utility functions.
        this.string = {

            // Based on http://stackoverflow.com/a/498995
            trim: function(target) {
                return target.replace(/^\s+|\s+$/g, '');
            },

            // Based on http://stackoverflow.com/a/1981366
            removeMultipleSpaces: function(target) {
                return target.replace(/\s{2,}/g, ' ');
            },

            // Return the simplified version of target, i.e. a trimmed string with multiple spaces removed
            simplify: function(target) {
                return this.removeMultipleSpaces(this.trim(target));
            },

            // Based on http://stackoverflow.com/a/646643
            startsWith: function(target, str) {
                return target.slice(0, str.length) == str;
            },
            endsWith: function(target, str) {
                return target.slice(-str.length) == str;
            },

            // remove first and last char
            removeBorders: function(target) {
                target = target.substring(1); // first
                target = target.substring(0, target.length-1); // last
                return target;
            }
        }

        this.initialize();
    })();
    return utils;
});
<|endoftext|>


<commit_before>var HTML_base = "http://projectchrono.org/metrics/api";
google.charts.load("current", {"packages":["corechart"]});

var charts = [];
var color_list = ['#274EC0','#D12411','#1E8E1B'];

// Shows dropdown menu of all tests available
function showTestNames(test_list) {
    for (i = 0; i < test_list.length; i++) {
        test = test_list[i];
        // Makes a dropdown list of each available test
        var x = document.getElementById("test_names");
        var option = document.createElement("option");
        option.text = test.name;
        option.value = test.name;
        x.add(option);
    }
}
// Parses data for a given test and plots charts for each metric
function drawCharts(test_runs) {
    var run_names = []; // Number of machines + name
    var runs = []; //  2D Array containing. Cols =  Number of machines, Rows = Run
    var metrics =[];

    run_names = test_runs["run_names"];
    var len = run_names.length;

    /* Load runs for each machine */
    for (var i = 0; i < len; i++){
        runs.push(test_runs[run_names[i]]);
    }
    /* Load metric names */
    for (metric in runs[0][0]["metrics"]) {
        metrics.push(metric);
    }
    console.log(run_names, runs, metrics);
    showlegend(run_names);
    plotProps(metrics, run_names, runs);

}
function showlegend(run_names) {
    var table = document.createElement("table");
    for (var n = 0; n < run_names.length; n++) {
        var tr = document.createElement("tr");
        var colorbox = document.createElement("td");
        colorbox.setAttribute("style", "background-color:" + color_list[n]);
        colorbox.innerHTML = "
";
        tr.appendChild(colorbox);

        var buildername = document.createElement("td");
        buildername.innerHTML = run_names[n];

        tr.appendChild(buildername);
        table.appendChild(tr);
    }
    legendtitle = document.createElement("div");
    legendtitle.innerHTML="
 Legend
";
    document.getElementById("metrics").appendChild(legendtitle);
    document.getElementById("metrics").appendChild(table);

}
function makeChart(data, prop_name) {
    var options = {
        title: prop_name,
        legend: "none",
            // vAxis: {title: metric_name},
            // hAxis: {title: "timestamp"},
            explorer: {
                axis: "horizontal",
                actions: ["dragToZoom","rightClickToReset"],
                keepInBounds: true,
                maxZoomIn: .1
            },
            chartArea: {
                height: "50%",
                width: "90%"
            },
            colors: color_list
        };

        var div = document.createElement("div");
        div.setAttribute("id", prop_name);
        div.setAttribute("class", "metric");
        document.getElementById("metrics").appendChild(div);
        var chart = new google.visualization.ScatterChart(document.getElementById(prop_name));
        chart.draw(data, options);
        charts.push(chart);
    }

// Plots charts for each property (metrics and execution time) of a given test
function plotProps(metrics, run_names, runs) {
    var timestamps = [];
    var commit_ids = [];
    var base_table = [["x"]];
    console.log(base_table);

    // Sets up table of timestamps
    for (var n = 0; n < run_names.length; n++) {
        // Iterate through each run for that name
        base_table[0].push(run_names[n]);
        for (var m = 0; m < runs[n].length; m++) {
            var test_run = runs[n][m];
            var ts = new Date(test_run["timestamp"]);
            // Adds timestamp to list of timestamps iff not already in array
            var index = getObjectIndex(ts, timestamps);
            if ( index == -1) {
                timestamps.push(ts);
                base_table.push([ts]);
                // table[timestamps.length][n + 1] = test_run["metrics"][metric_name];
            } //else {
                // table[index + 1][n + 1].push(test_run["metrics"][metric_name]);
            // }
        }
    }

    // Ensures each row has same length
    for (var n = 0; n < base_table.length; n++) {
        base_table[n].length = run_names.length + 1;
    }
    var table = base_table;
    // Plots execution times
    for (var n = 0; n < run_names.length; n++) {
        // Iterate through each run for that name
        for (var m = 0; m < runs[n].length; m++) {
            var test_run = runs[n][m];
            var ts = new Date(test_run["timestamp"]);
            var index = getObjectIndex(ts, timestamps);
            table[index + 1][n + 1] = test_run["execution_time"];
        }
    }
    console.log(table);
    var data = google.visualization.arrayToDataTable(table);

    makeChart(data, "Execution Times");
    // console.log(metrics);
    for (var i = 0; i < metrics.length; i++) {
        var metric = metrics[i];
        // console.log(i + ": " + metric);
        table = base_table;
        // Plots a chart for each metric
        for (var n = 0; n < run_names.length; n++) {
            // Iterate through each run for that name
            for (var m = 0; m < runs[n].length; m++) {
                var test_run = runs[n][m];
                // console.log(test_run['metrics'][metric]);
                var ts = new Date(test_run["timestamp"]);
                var index = getObjectIndex(ts, timestamps);
                table[index + 1][n + 1] = test_run["metrics"][metric];
            }
        }
            // console.log(table);
            data = google.visualization.arrayToDataTable(table);
            makeChart(data, metric);
        }

    }

    // Finds index of specified object in an array
    function getObjectIndex(obj, arr) {
        for (var test_idx = 0; test_idx < arr.length; test_idx++) {
            if (arr[test_idx].valueOf() == obj.valueOf()) {
                return test_idx;
            }
        }
        return -1;
    }

// Sets up authentication info
$.ajaxSetup({
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    },
    headers: {
        "Access-Control-Allow-Credentials": true,
        "Authorization": "Basic " + btoa("User:Password")
    }
});
// Gets list of test names
$.ajax({
    url: HTML_base + "/tests",
    method: "GET",
    data: "{};",
    dataType:"json",
    success: function (response, status, xhr) {
        console.log(response);
            // Changes "Test Loading!" text
            $("#test_names option:selected").html(" --- Select A Test --- ");
            showTestNames(response);
        },
        error: function (xhr, status, error_code) {
            console.log("Error:" + status + ": " + error_code);
        }
    })

// Shows a test when selected from the dropdown menu
function showTest(test_name) {
    $("#metrics").empty(); // Clears metrics div so new charts can be shown
    if (test_name == "default") {
        return; //If the "Select A Test" option is selected
    }
    $.ajaxSetup({
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        headers: {
            "Access-Control-Allow-Credentials": true,
            "Authorization": "Basic " + btoa("User:Password")
        }
    });
    // Gets all test data for a given test
    $.ajax({
        url: HTML_base + "/tests/" + test_name,
        method: "GET",
        data: "{};",
        dataType:"json",
        success: function (response, status, xhr) {
            console.log(response);
            google.charts.setOnLoadCallback(drawCharts(response));
        },
        error: function (xhr, status, error_code) {
            console.log("Error:" + status + ": " + error_code);
        }
    })
}<commit_msg>Hopefully added commit id as tooltip<commit_after>var HTML_base = "http://projectchrono.org/metrics/api";
google.charts.load("current", {
    "packages": ["corechart"]
});
var charts = [];
var color_list = ['#274EC0', '#D12411', '#1E8E1B'];
// Shows dropdown menu of all tests available
function showTestNames(test_list) {
    for (i = 0; i < test_list.length; i++) {
        test = test_list[i];
        // Makes a dropdown list of each available test
        var x = document.getElementById("test_names");
        var option = document.createElement("option");
        option.text = test.name;
        option.value = test.name;
        x.add(option);
    }
}
// Parses data for a given test and plots charts for each metric
function drawCharts(test_runs) {
    var run_names = []; // Number of machines + name
    var runs = []; //  2D Array containing. Cols =  Number of machines, Rows = Run
    var metrics = [];
    run_names = test_runs["run_names"];
    var len = run_names.length;
    /* Load runs for each machine */
    for (var i = 0; i < len; i++) {
        runs.push(test_runs[run_names[i]]);
    }
    /* Load metric names */
    for (metric in runs[0][0]["metrics"]) {
        metrics.push(metric);
    }
    console.log(run_names, runs, metrics);
    showlegend(run_names);
    plotProps(metrics, run_names, runs);
}

function showlegend(run_names) {
    var table = document.createElement("table");
    for (var n = 0; n < run_names.length; n++) {
        var tr = document.createElement("tr");
        var colorbox = document.createElement("td");
        colorbox.setAttribute("style", "background-color:" + color_list[n]);
        colorbox.innerHTML = "
";
        tr.appendChild(colorbox);
        var buildername = document.createElement("td");
        buildername.innerHTML = run_names[n];
        tr.appendChild(buildername);
        table.appendChild(tr);
    }
    legendtitle = document.createElement("div");
    legendtitle.innerHTML = "
 Legend
";
    document.getElementById("metrics").appendChild(legendtitle);
    document.getElementById("metrics").appendChild(table);
}

function makeChart(data, prop_name) {
    var options = {
        title: prop_name,
        legend: "none",
        // vAxis: {title: metric_name},
        // hAxis: {title: "timestamp"},
        explorer: {
            axis: "horizontal",
            actions: ["dragToZoom", "rightClickToReset"],
            keepInBounds: true,
            maxZoomIn: .1
        },
        chartArea: {
            height: "50%",
            width: "90%"
        },
        colors: color_list
    };
    var div = document.createElement("div");
    div.setAttribute("id", prop_name);
    div.setAttribute("class", "metric");
    document.getElementById("metrics").appendChild(div);
    var chart = new google.visualization.ScatterChart(document.getElementById(prop_name));
    chart.draw(data, options);
    charts.push(chart);
}
// Plots charts for each property (metrics and execution time) of a given test
function plotProps(metrics, run_names, runs) {
    var timestamps = [];
    var commit_ids = [];
    var base_table = [
        ["x"]
    ];
    console.log(base_table);
    // Sets up table of timestamps
    for (var n = 0; n < run_names.length; n++) {
        // Iterate through each run for that name
        base_table[0].push(run_names[n]);
        for (var m = 0; m < runs[n].length; m++) {
            var test_run = runs[n][m];
            var ts = new Date(test_run["timestamp"]);
            // Adds timestamp to list of timestamps iff not already in array
            var index = getObjectIndex(ts, timestamps);
            if (index == -1) {
                timestamps.push(ts);
                base_table.push([ts]);
                // table[timestamps.length][n + 1] = test_run["metrics"][metric_name];
            } //else {
            // table[index + 1][n + 1].push(test_run["metrics"][metric_name]);
            // }
        }
    }
    // Ensures each row has same length
    for (var n = 0; n < base_table.length; n++) {
        base_table[n].length = run_names.length + 1;
    }
    var table = base_table;
    // Plots execution times
    for (var n = 0; n < run_names.length; n++) {
        // Iterate through each run for that name
        for (var m = 0; m < runs[n].length; m++) {
            var test_run = runs[n][m];
            var ts = new Date(test_run["timestamp"]);
            var index = getObjectIndex(ts, timestamps);
            table[index + 1][n + 1] = test_run["commit_id"];
            table[index + 1][n + 2] = test_run["execution_time"];
        }
    }
    console.log(table);
    var data = google.visualization.arrayToDataTable(table);
    data.setColumnProperty(1, 'role', 'tooltip');
    makeChart(data, "Execution Times");
    // console.log(metrics);
    for (var i = 0; i < metrics.length; i++) {
        var metric = metrics[i];
        // console.log(i + ": " + metric);
        table = base_table;
        // Plots a chart for each metric
        for (var n = 0; n < run_names.length; n++) {
            // Iterate through each run for that name
            for (var m = 0; m < runs[n].length; m++) {
                var test_run = runs[n][m];
                // console.log(test_run['metrics'][metric]);
                var ts = new Date(test_run["timestamp"]);
                var index = getObjectIndex(ts, timestamps);
                table[index + 1][n + 1] = test_run["commit_id"];
                table[index + 1][n + 2] = test_run["metrics"][metric];
            }
        }
        // console.log(table);
        data = google.visualization.arrayToDataTable(table);
        data.setColumnProperty(1, 'role', 'tooltip');
        makeChart(data, metric);
    }
}
// Finds index of specified object in an array
function getObjectIndex(obj, arr) {
    for (var test_idx = 0; test_idx < arr.length; test_idx++) {
        if (arr[test_idx].valueOf() == obj.valueOf()) {
            return test_idx;
        }
    }
    return -1;
}
// Sets up authentication info
$.ajaxSetup({
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    },
    headers: {
        "Access-Control-Allow-Credentials": true,
        "Authorization": "Basic " + btoa("User:Password")
    }
});
// Gets list of test names
$.ajax({
        url: HTML_base + "/tests",
        method: "GET",
        data: "{};",
        dataType: "json",
        success: function(response, status, xhr) {
            console.log(response);
            // Changes "Test Loading!" text
            $("#test_names option:selected").html(" --- Select A Test --- ");
            showTestNames(response);
        },
        error: function(xhr, status, error_code) {
            console.log("Error:" + status + ": " + error_code);
        }
    })
    // Shows a test when selected from the dropdown menu
function showTest(test_name) {
    $("#metrics").empty(); // Clears metrics div so new charts can be shown
    if (test_name == "default") {
        return; //If the "Select A Test" option is selected
    }
    $.ajaxSetup({
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        headers: {
            "Access-Control-Allow-Credentials": true,
            "Authorization": "Basic " + btoa("User:Password")
        }
    });
    // Gets all test data for a given test
    $.ajax({
        url: HTML_base + "/tests/" + test_name,
        method: "GET",
        data: "{};",
        dataType: "json",
        success: function(response, status, xhr) {
            console.log(response);
            google.charts.setOnLoadCallback(drawCharts(response));
        },
        error: function(xhr, status, error_code) {
            console.log("Error:" + status + ": " + error_code);
        }
    })
}<|endoftext|>


<commit_before>var qq = (function() {
    'use strict';

    function htmlDecode(value){
      return $('<div/>').html(value).text();
    }

    var qq_show_playlist = function(url, hm) {

        var offset = Number(getParameterByName("offset", url)) || 0;
        var target_url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg' +
            '?rnd=0.4781484879517406&g_tk=732560869&jsonpCallback=MusicJsonCallback' +
            '&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8' +
            '&notice=0&platform=yqq&needNewCode=0' +
            '&categoryId=10000000&sortId=5&sin=' + offset + '&ein=' + (49 + offset);

        return {
            success: function(fn) {
                var result = [];
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                }).then(function(response) {
                    var data = response.data;
                    data = data.slice('MusicJsonCallback('.length, -')'.length);
                    data = JSON.parse(data);

                    var playlists = [];
                    $.each(data.data.list, function(index, item){
                        var d = {
                            'cover_img_url': item.imgurl,
                            'title': htmlDecode(item.dissname),
                            'id':'qqplaylist_' + item.dissid,
                            'source_url': 'http://y.qq.com/#type=taoge&id=' + item.dissid

                        };
                        playlists.push(d);
                    });

                    return fn({"result":playlists});
                });
            }
        };
    }

    function qq_get_image_url(qqimgid, img_type) {
        if (qqimgid == null) {
            return '';
        }
        var category = '';
        if(img_type == 'artist') {
            category = 'mid_singer_300'
        }
        if(img_type == 'album') {
            category = 'mid_album_300';
        }

        var s = [category, qqimgid[qqimgid.length - 2], qqimgid[qqimgid.length - 1], qqimgid].join('/');
        var url = 'http://imgcache.qq.com/music/photo/' + s + '.jpg';
        return url;
    }

    function qq_convert_song(song) {
        var d = {
            'id': 'qqtrack_' + song.songmid,
            'title': htmlDecode(song.songname),
            'artist': htmlDecode(song.singer[0].name),
            'artist_id': 'qqartist_' + song.singer[0].mid,
            'album': htmlDecode(song.albumname),
            'album_id': 'qqalbum_' + song.albummid,
            'img_url': qq_get_image_url(song.albummid, 'album'),
            'source': 'qq',
            'source_url': 'http://y.qq.com/#type=song&mid=' +
            song.songmid + '&tpl=yqq_song_detail',
            'url': 'qqtrack_' + song.songmid,
            'disabled': !qq_is_playable(song)
        }
        return d
    }

    function qq_is_playable(song) {
        var switch_flag = song['switch'].toString(2).split('');
        switch_flag.pop();
        switch_flag.reverse();
        // flag switch table meaning:
        // ["play_lq", "play_hq", "play_sq", "down_lq", "down_hq", "down_sq", "soso", "fav", "share", "bgm", "ring", "sing", "radio", "try", "give"]
        var play_flag = switch_flag[0];
        var try_flag = switch_flag[13];
        return ((play_flag == 1) || ((play_flag == 1) && (try_flag == 1)));
    }

    var qq_get_playlist = function(url, hm, se) {
        var list_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/qzone-music/fcg-bin/fcg_ucc_getcdinfo_' +
                    'byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&jsonpCallback=' +
                    'jsonCallback&nosign=1&disstid=' + list_id +'&g_tk=5381&loginUin=0&hostUin=0' +
                    '&format=jsonp&inCharset=GB2312&outCharset=utf-8&notice=0' +
                    '&platform=yqq&jsonpCallback=jsonCallback&needNewCode=0';
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice('jsonCallback('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': data.cdlist[0].logo,
                        'title': data.cdlist[0].dissname,
                        'id': 'qqplaylist_' + list_id,
                        'source_url': 'http://y.qq.com/#type=taoge&id=' + list_id
                    };

                    var tracks = [];
                    $.each(data.cdlist[0].songlist, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_album = function(url, hm) {
        var album_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/v8/fcg-bin/fcg_v8_album_info_cp.fcg' +
                    '?platform=h5page&albummid=' + album_id + '&g_tk=938407465' +
                    '&uin=0&format=jsonp&inCharset=utf-8&outCharset=utf-8' +
                    '&notice=0&platform=h5&needNewCode=1&_=1459961045571' +
                    '&jsonpCallback=asonglist1459961045566';
                hm({
                    url: target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice(' asonglist1459961045566('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': qq_get_image_url(album_id, 'album'),
                        'title': data.data.name,
                        'id': 'qqalbum_' + album_id,
                        'source_url': 'http://y.qq.com/#type=album&mid=' + album_id
                    };

                    var tracks = [];
                    $.each(data.data.list, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_artist = function(url, hm) {
        var artist_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg' +
                    '?platform=h5page&order=listen&begin=0&num=50&singermid=' + artist_id +
                    '&g_tk=938407465&uin=0&format=jsonp&' +
                    'inCharset=utf-8&outCharset=utf-8&notice=0&platform=' +
                    'h5&needNewCode=1&from=h5&_=1459960621777&' +
                    'jsonpCallback=ssonglist1459960621772';
                hm({
                    url: target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice(' ssonglist1459960621772('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': qq_get_image_url(artist_id, 'artist'),
                        'title': data.data.singer_name,
                        'id': 'qqartist_' + artist_id,
                        'source_url': 'http://y.qq.com/#type=singer&mid=' + artist_id
                    };

                    var tracks = [];
                    $.each(data.data.list, function(index, item){
                        var track = qq_convert_song(item.musicData);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_search = function(url, hm, se) {
        return {
            success: function(fn) {
                var keyword = getParameterByName('keywords', url);
                var curpage = getParameterByName('curpage', url);
                var target_url = 'http://i.y.qq.com/s.music/fcgi-bin/search_for_qq_cp?' +
                'g_tk=938407465&uin=0&format=jsonp&inCharset=utf-8' +
                '&outCharset=utf-8&notice=0&platform=h5&needNewCode=1' +
                '&w=' + keyword + '&zhidaqu=1&catZhida=1' +
                '&t=0&flag=1&ie=utf-8&sem=1&aggr=0&perpage=20&n=20&p=' + curpage +
                '&remoteplace=txt.mqq.all&_=1459991037831&jsonpCallback=jsonp4';
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice('jsonp4('.length, -')'.length);
                    data = JSON.parse(data);
                    var tracks = [];
                    $.each(data.data.song.list, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"result":tracks,"total":data.data.song.totalnum});
                });
            }
        };
    }

    var qq_bootstrap_track = function(sound, track, success, failure, hm, se) {
        var target_url ='https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg' +
            '?g_tk=195219765&jsonpCallback=MusicJsonCallback004680169373158849' +
            '&loginUin=1297716249&hostUin=0&format=json&inCharset=utf8' +
            '&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0' +
            '&cid=205361747&callback=MusicJsonCallback004680169373158849' +
            '&uin=1297716249&songmid='+ track.id.slice('qqtrack_'.length) +
            '&filename=C400'+ track.id.slice('qqtrack_'.length) + '.m4a&guid=7332953645';

        hm({
            url:target_url,
            method: 'GET',
            transformResponse: undefined
        })
        .then(function(response) {
            var data = response.data;
            data = data.slice(data.indexOf('(')+1,data.length-1);
            data = JSON.parse(data);
            var token = data.data.items[0].vkey;
            var url = 'http://dl.stream.qqmusic.qq.com/C400' +
              track.id.slice('qqtrack_'.length)  +
              '.m4a?vkey=' + token +
              '&uin=1297716249&fromtag=0&guid=7332953645';
            sound.url = url;
            success();
        });
    }

    function str2ab(str) {
      // string to array buffer.
      var buf = new ArrayBuffer(str.length);
      var bufView = new Uint8Array(buf);
      for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
      }
      return buf;
    }

    var qq_lyric = function(url, hm, se) {
        var track_id = getParameterByName('track_id', url).split('_').pop();
        // use chrome extension to modify referer.
        var target_url = 'http://i.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?' +
            'songmid=' + track_id +
            '&loginUin=0&hostUin=0&format=jsonp&inCharset=GB2312' +
            '&outCharset=utf-8&notice=0&platform=yqq&jsonpCallback=MusicJsonCallback&needNewCode=0';
        return {
            success: function(fn) {
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                }).then(function(response) {
                    var data = response.data;
                    data = data.slice('MusicJsonCallback('.length, -')'.length);
                    data = JSON.parse(data);
                    var lrc = '';
                    if (data.lyric != null) {
                        var td = new TextDecoder('utf8');
                        lrc = td.decode(str2ab(atob(data.lyric)));
                    }
                    return fn({"lyric":lrc});
                });
            }
        };
    }

    var qq_parse_url = function(url) {
        var result = undefined;
        var match = /\/\/y.qq.com\/n\/yqq\/playlist\/([0-9]+)/.exec(url);
        if (match != null) {
            var playlist_id = match[1];
            result = {'type': 'playlist', 'id': 'qqplaylist_' + playlist_id};
        }
        return result;
    }

var get_playlist = function(url, hm, se) {
    var list_id = getParameterByName('list_id', url).split('_')[0];
    if (list_id == 'qqplaylist') {
        return qq_get_playlist(url, hm, se);
    }
    if (list_id == 'qqalbum') {
        return qq_album(url, hm, se);
    }
    if (list_id == 'qqartist') {
        return qq_artist(url, hm, se);
    }
}

return {
    show_playlist: qq_show_playlist,
    get_playlist: get_playlist,
    parse_url: qq_parse_url,
    bootstrap_track: qq_bootstrap_track,
    search: qq_search,
    lyric: qq_lyric,
};

})();

<commit_msg>add more playlist url patten for qq music<commit_after>var qq = (function() {
    'use strict';

    function htmlDecode(value){
      return $('<div/>').html(value).text();
    }

    var qq_show_playlist = function(url, hm) {

        var offset = Number(getParameterByName("offset", url)) || 0;
        var target_url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg' +
            '?rnd=0.4781484879517406&g_tk=732560869&jsonpCallback=MusicJsonCallback' +
            '&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8' +
            '&notice=0&platform=yqq&needNewCode=0' +
            '&categoryId=10000000&sortId=5&sin=' + offset + '&ein=' + (49 + offset);

        return {
            success: function(fn) {
                var result = [];
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                }).then(function(response) {
                    var data = response.data;
                    data = data.slice('MusicJsonCallback('.length, -')'.length);
                    data = JSON.parse(data);

                    var playlists = [];
                    $.each(data.data.list, function(index, item){
                        var d = {
                            'cover_img_url': item.imgurl,
                            'title': htmlDecode(item.dissname),
                            'id':'qqplaylist_' + item.dissid,
                            'source_url': 'http://y.qq.com/#type=taoge&id=' + item.dissid

                        };
                        playlists.push(d);
                    });

                    return fn({"result":playlists});
                });
            }
        };
    }

    function qq_get_image_url(qqimgid, img_type) {
        if (qqimgid == null) {
            return '';
        }
        var category = '';
        if(img_type == 'artist') {
            category = 'mid_singer_300'
        }
        if(img_type == 'album') {
            category = 'mid_album_300';
        }

        var s = [category, qqimgid[qqimgid.length - 2], qqimgid[qqimgid.length - 1], qqimgid].join('/');
        var url = 'http://imgcache.qq.com/music/photo/' + s + '.jpg';
        return url;
    }

    function qq_convert_song(song) {
        var d = {
            'id': 'qqtrack_' + song.songmid,
            'title': htmlDecode(song.songname),
            'artist': htmlDecode(song.singer[0].name),
            'artist_id': 'qqartist_' + song.singer[0].mid,
            'album': htmlDecode(song.albumname),
            'album_id': 'qqalbum_' + song.albummid,
            'img_url': qq_get_image_url(song.albummid, 'album'),
            'source': 'qq',
            'source_url': 'http://y.qq.com/#type=song&mid=' +
            song.songmid + '&tpl=yqq_song_detail',
            'url': 'qqtrack_' + song.songmid,
            'disabled': !qq_is_playable(song)
        }
        return d
    }

    function qq_is_playable(song) {
        var switch_flag = song['switch'].toString(2).split('');
        switch_flag.pop();
        switch_flag.reverse();
        // flag switch table meaning:
        // ["play_lq", "play_hq", "play_sq", "down_lq", "down_hq", "down_sq", "soso", "fav", "share", "bgm", "ring", "sing", "radio", "try", "give"]
        var play_flag = switch_flag[0];
        var try_flag = switch_flag[13];
        return ((play_flag == 1) || ((play_flag == 1) && (try_flag == 1)));
    }

    var qq_get_playlist = function(url, hm, se) {
        var list_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/qzone-music/fcg-bin/fcg_ucc_getcdinfo_' +
                    'byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&jsonpCallback=' +
                    'jsonCallback&nosign=1&disstid=' + list_id +'&g_tk=5381&loginUin=0&hostUin=0' +
                    '&format=jsonp&inCharset=GB2312&outCharset=utf-8&notice=0' +
                    '&platform=yqq&jsonpCallback=jsonCallback&needNewCode=0';
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice('jsonCallback('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': data.cdlist[0].logo,
                        'title': data.cdlist[0].dissname,
                        'id': 'qqplaylist_' + list_id,
                        'source_url': 'http://y.qq.com/#type=taoge&id=' + list_id
                    };

                    var tracks = [];
                    $.each(data.cdlist[0].songlist, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_album = function(url, hm) {
        var album_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/v8/fcg-bin/fcg_v8_album_info_cp.fcg' +
                    '?platform=h5page&albummid=' + album_id + '&g_tk=938407465' +
                    '&uin=0&format=jsonp&inCharset=utf-8&outCharset=utf-8' +
                    '&notice=0&platform=h5&needNewCode=1&_=1459961045571' +
                    '&jsonpCallback=asonglist1459961045566';
                hm({
                    url: target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice(' asonglist1459961045566('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': qq_get_image_url(album_id, 'album'),
                        'title': data.data.name,
                        'id': 'qqalbum_' + album_id,
                        'source_url': 'http://y.qq.com/#type=album&mid=' + album_id
                    };

                    var tracks = [];
                    $.each(data.data.list, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_artist = function(url, hm) {
        var artist_id = getParameterByName('list_id', url).split('_').pop();

        return {
            success: function(fn) {
                var target_url = 'http://i.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg' +
                    '?platform=h5page&order=listen&begin=0&num=50&singermid=' + artist_id +
                    '&g_tk=938407465&uin=0&format=jsonp&' +
                    'inCharset=utf-8&outCharset=utf-8&notice=0&platform=' +
                    'h5&needNewCode=1&from=h5&_=1459960621777&' +
                    'jsonpCallback=ssonglist1459960621772';
                hm({
                    url: target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice(' ssonglist1459960621772('.length, -')'.length);
                    data = JSON.parse(data);

                    var info = {
                        'cover_img_url': qq_get_image_url(artist_id, 'artist'),
                        'title': data.data.singer_name,
                        'id': 'qqartist_' + artist_id,
                        'source_url': 'http://y.qq.com/#type=singer&mid=' + artist_id
                    };

                    var tracks = [];
                    $.each(data.data.list, function(index, item){
                        var track = qq_convert_song(item.musicData);
                        tracks.push(track);
                    });
                    return fn({"tracks":tracks, "info":info});
                });
            }
        };
    }

    var qq_search = function(url, hm, se) {
        return {
            success: function(fn) {
                var keyword = getParameterByName('keywords', url);
                var curpage = getParameterByName('curpage', url);
                var target_url = 'http://i.y.qq.com/s.music/fcgi-bin/search_for_qq_cp?' +
                'g_tk=938407465&uin=0&format=jsonp&inCharset=utf-8' +
                '&outCharset=utf-8&notice=0&platform=h5&needNewCode=1' +
                '&w=' + keyword + '&zhidaqu=1&catZhida=1' +
                '&t=0&flag=1&ie=utf-8&sem=1&aggr=0&perpage=20&n=20&p=' + curpage +
                '&remoteplace=txt.mqq.all&_=1459991037831&jsonpCallback=jsonp4';
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                })
                .then(function(response) {
                    var data = response.data;
                    data = data.slice('jsonp4('.length, -')'.length);
                    data = JSON.parse(data);
                    var tracks = [];
                    $.each(data.data.song.list, function(index, item){
                        var track = qq_convert_song(item);
                        tracks.push(track);
                    });
                    return fn({"result":tracks,"total":data.data.song.totalnum});
                });
            }
        };
    }

    var qq_bootstrap_track = function(sound, track, success, failure, hm, se) {
        var target_url ='https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg' +
            '?g_tk=195219765&jsonpCallback=MusicJsonCallback004680169373158849' +
            '&loginUin=1297716249&hostUin=0&format=json&inCharset=utf8' +
            '&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0' +
            '&cid=205361747&callback=MusicJsonCallback004680169373158849' +
            '&uin=1297716249&songmid='+ track.id.slice('qqtrack_'.length) +
            '&filename=C400'+ track.id.slice('qqtrack_'.length) + '.m4a&guid=7332953645';

        hm({
            url:target_url,
            method: 'GET',
            transformResponse: undefined
        })
        .then(function(response) {
            var data = response.data;
            data = data.slice(data.indexOf('(')+1,data.length-1);
            data = JSON.parse(data);
            var token = data.data.items[0].vkey;
            var url = 'http://dl.stream.qqmusic.qq.com/C400' +
              track.id.slice('qqtrack_'.length)  +
              '.m4a?vkey=' + token +
              '&uin=1297716249&fromtag=0&guid=7332953645';
            sound.url = url;
            success();
        });
    }

    function str2ab(str) {
      // string to array buffer.
      var buf = new ArrayBuffer(str.length);
      var bufView = new Uint8Array(buf);
      for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
      }
      return buf;
    }

    var qq_lyric = function(url, hm, se) {
        var track_id = getParameterByName('track_id', url).split('_').pop();
        // use chrome extension to modify referer.
        var target_url = 'http://i.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?' +
            'songmid=' + track_id +
            '&loginUin=0&hostUin=0&format=jsonp&inCharset=GB2312' +
            '&outCharset=utf-8&notice=0&platform=yqq&jsonpCallback=MusicJsonCallback&needNewCode=0';
        return {
            success: function(fn) {
                hm({
                    url:target_url,
                    method: 'GET',
                    transformResponse: undefined
                }).then(function(response) {
                    var data = response.data;
                    data = data.slice('MusicJsonCallback('.length, -')'.length);
                    data = JSON.parse(data);
                    var lrc = '';
                    if (data.lyric != null) {
                        var td = new TextDecoder('utf8');
                        lrc = td.decode(str2ab(atob(data.lyric)));
                    }
                    return fn({"lyric":lrc});
                });
            }
        };
    }

    var qq_parse_url = function(url) {
        var result = undefined;
        var match = /\/\/y.qq.com\/n\/yqq\/playlist\/([0-9]+)/.exec(url);
        if (match != null) {
            var playlist_id = match[1];
            result = {'type': 'playlist', 'id': 'qqplaylist_' + playlist_id};
        }
        match = /\/\/y.qq.com\/n\/yqq\/playsquare\/([0-9]+)/.exec(url);
        if (match != null) {
            var playlist_id = match[1];
            result = {'type': 'playlist', 'id': 'qqplaylist_' + playlist_id};
        }
        match = /\/\/y.qq.com\/n\/m\/detail\/taoge\/index.html\?id=([0-9]+)/.exec(url);
        if (match != null) {
            var playlist_id = match[1];
            result = {'type': 'playlist', 'id': 'qqplaylist_' + playlist_id};
        }
        return result;
    }

var get_playlist = function(url, hm, se) {
    var list_id = getParameterByName('list_id', url).split('_')[0];
    if (list_id == 'qqplaylist') {
        return qq_get_playlist(url, hm, se);
    }
    if (list_id == 'qqalbum') {
        return qq_album(url, hm, se);
    }
    if (list_id == 'qqartist') {
        return qq_artist(url, hm, se);
    }
}

return {
    show_playlist: qq_show_playlist,
    get_playlist: get_playlist,
    parse_url: qq_parse_url,
    bootstrap_track: qq_bootstrap_track,
    search: qq_search,
    lyric: qq_lyric,
};

})();

<|endoftext|>


<commit_before>/**
* @class solgs
* general solGS app wide and misc functions
* @author Isaak Y Tecle <iyt2@cornell.edu>
*
*/

JSAN.use('jquery.blockUI');
JSAN.use('jquery.form');

function solGS () {};

solGS.waitPage = function (page) {

    if ( page.match(/solgs\/trait\//)) {
    	askUser(page);
    } else {
    	blockPage(page);
    }

}

function  askUser(page, args) {

    var t = '
This analysis may take longer than 20 min. '
	+ 'Would you like to be emailed when it is done?
';

    jQuery('
')
	.html(t)
	.dialog({
	    height : 200,
	    width  : 400,
	    modal  : true,
	    title  : "Analysis update message",
 	    buttons: {
		No: { text: "No, I will wait...",
                      click: function() {
			  jQuery(this).dialog("close");

			  displayAnalysisNow(page, args);
		      },
		    },

		Yes: { text: "Yes",
                       click: function() {
			   jQuery(this).dialog("close");

			   checkUserLogin(page, args);
		       },
		     }
	    }
	});

}

function checkUserLogin (page, args) {

    jQuery.ajax({
	type    : 'POST',
	dataType: 'json',
	url     : '/solgs/check/user/login/',
	success : function(response) {
            if (response.loggedin) {
		//include in response user data
		getProfileDialog(page, args);
            } else {
		loginAlert();
	    }
	}
    });

}

function loginAlert () {

    jQuery('
')
	.html('To use this feature, you need to log in and start over the process.')
	.dialog({
	    height : 200,
	    width  : 250,
	    modal  : true,
	    title  : 'Login Alert',
	    buttons: {
		OK: function () {
		    jQuery(this).dialog('close');

		    loginUser();
		}
	    }
	});

}

function loginUser () {

   window.location = '/solpeople/login.pl?goto_url=' + window.location.pathname;

}

function displayAnalysisNow (page, args) {

    blockPage(page, args);

 }

function blockPage (page, args) {

    goToPage(page, args);

    jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
    jQuery.blockUI({message: 'Please wait..'});

    jQuery(window).unload(function()  {
	jQuery.unblockUI();
    });

}

function goToPage (page, args) {

    alert('gotopage: ' + page)
    if (page.match(/solgs\/confirm\/request/)) {

	window.location = page;

    } else if (page.match(/solgs\/analyze\/traits\/population\//)) {

	submitTraitSelections();

	if (args.analysis_name == null) {

	    var popId  = jQuery('#population_id').val();

	    if (page.match(/solgs\/trait\//)) {
		alert('going to: ' + page)
		window.location = page;
	    } else {

		window.location = '/solgs/analyze/traits/population/' + popId;
	    }
	}
    } else if (page.match(/solgs\/trait\//)) {

		alert('going to: ' + page)
		window.location = page;

    }

}

function submitTraitSelections () {

    wrapTraitsForm();
    jQuery('#traits_selection_form').ajaxSubmit();

}

function wrapTraitsForm () {

    var popId  = jQuery('#population_id').val();
    var formId = ' id="traits_selection_form"';
    var action = ' action="/solgs/analyze/traits/population/' + popId + '"';
    var method = ' method="POST"';

    var traitsForm = '<form'
	+ formId
	+ action
	+ method
	+ '>'
	+ '</form>';

    jQuery('#population_traits_list').wrap(traitsForm);

}

function getProfileDialog (page, args) {
    var form = getProfileForm();

    if (args) {
	args = JSON.stringify(args);
    }

    jQuery('
', {id: 'email-form'})
	.html(form)
	.dialog({
	    height : 300,
	    width  : 300,
	    modal  : true,
	    title  : 'Submit your email',
 	    buttons: {
		Submit: function() {
		    var userName     = jQuery('#user_name').val();
		    var userEmail    = jQuery('#user_email').val();
		    var analysisName = jQuery('#analysis_name').val();
		     //validate input
		    var analysisProfile = {
			'user_name'    : userName,
			'user_email'   : userEmail,
			'analysis_name': analysisName,
			'analysis_page': page,
			'arguments'    : args,
		    }

		    jQuery(this).dialog('close');

		    saveAnalysisProfile(analysisProfile);
		},
		Cancel:  function() {
		    jQuery(this).dialog('close');
		},
	    }
	});

}

function getProfileForm () {
  //remove user name; ask for email depending on whether there is one in the db or not.
    var emailForm = '
Please fill in your email.
'
	+'
'
	+ '
'
	+  'Your name:	'
	+  '<input  type="text" name="user_name" id="user_name">	'
	+ '
'
	+ '
'
	+  'Your analysis name:	'
	+  '<input  type="text" name="analysis_name" id="analysis_name">	'
	+  '
'
	+ '
'
	+  'Email:	'
	+  '<input type="text" name="user_email" id="user_email">	'
	+ '
'
	+'
';

    return emailForm;
}

jQuery(document).ready(function (){

     jQuery('#runGS').on('click',  function() {

	 var popId = jQuery('#population_id').val();

	 var hostName = window.location.protocol
	     + '//'
	     + window.location.host;

	 var page;

	 var traitIds = jQuery("#traits_selection_div :checkbox").fieldValue();

	 if (traitIds.length == 1) {
	     page = hostName + '/solgs/trait/' + traitIds[0] + '/population/' + popId;
	 } else {
	     page = hostName + '/solgs/analyze/traits/population/' + popId;
	 }

	 var args = {'trait_id' :  traitIds};

	 askUser(page, args);

     });

});

function saveAnalysisProfile (profile) {

    //make an ajax request
    //save analysis details in a file
    //run analysis, when complete, retrieve analysis owner and send an email

    jQuery.ajax({
	type    : 'POST',
	dataType: 'json',
	data    : profile,
	url     : '/solgs/save/analysis/profile/',
	success : function(response) {
            if (response.result) {
		runAnalysis(profile);
		confirmRequest();

            } else {
		jQuery('
', {id: 'error-message'})
		    .html('Failed saving your analysis profile.')
		    .dialog({
			height : 200,
			width  : 250,
			modal  : true,
			title  : 'Error message',
			buttons: {
			    OK: function () {
				jQuery(this).dialog('close');
				window.location = window.location.href;
			    }
			}
		    });
            }
	},
	error: function () {
	    jQuery('
')
		.html('Error occured calling the function to save your analysis profile.')
		.dialog({
		    height : 200,
		    width  : 250,
		    modal  : true,
		    title  : 'Error message',
		    buttons: {
			OK: function () {
			    jQuery(this).dialog('close');
			    window.location = window.location.href;
			}
		    }
		});
	}
    });

}

function runAnalysis (profile) {

    jQuery.ajax({
 	data: profile,
	url: '/solgs/run/saved/analysis/',
    });

}

function confirmRequest () {

    blockPage('/solgs/confirm/request');

}

//executes two functions alternately
jQuery.fn.alternateFunctions = function(a, b) {
    return this.each(function() {
        var clicked = false;
        jQuery(this).bind("click", function() {
            if (clicked) {
                clicked = false;
                return b.apply(this, arguments);

            }
            clicked = true;
             return a.apply(this, arguments);

        });
    });
};
//

 //  $(function() {
//     var dialog, form,

//       // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
//       emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
//       name = $( "#name" ),
//       email = $( "#email" ),
//       password = $( "#password" ),
//       allFields = $( [] ).add( name ).add( email ).add( password ),
//       tips = $( ".validateTips" );

//     function updateTips( t ) {
//       tips
//         .text( t )
//         .addClass( "ui-state-highlight" );
//       setTimeout(function() {
//         tips.removeClass( "ui-state-highlight", 1500 );
//       }, 500 );
//     }

//     function checkLength( o, n, min, max ) {
//       if ( o.val().length > max || o.val().length < min ) {
//         o.addClass( "ui-state-error" );
//         updateTips( "Length of " + n + " must be between " +
//           min + " and " + max + "." );
//         return false;
//       } else {
//         return true;
//       }
//     }

//     function checkRegexp( o, regexp, n ) {
//       if ( !( regexp.test( o.val() ) ) ) {
//         o.addClass( "ui-state-error" );
//         updateTips( n );
//         return false;
//       } else {
//         return true;
//       }
//     }

//     function addUser() {
//       var valid = true;
//       allFields.removeClass( "ui-state-error" );

//       valid = valid && checkLength( name, "username", 3, 16 );
//       valid = valid && checkLength( email, "email", 6, 80 );
//       valid = valid && checkLength( password, "password", 5, 16 );

//       valid = valid && checkRegexp( name, /^[a-z]([0-9a-z_\s])+$/i, "Username may consist of a-z, 0-9, underscores, spaces and must begin with a letter." );
//       valid = valid && checkRegexp( email, emailRegex, "eg. ui@jquery.com" );
//       valid = valid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" );

//       if ( valid ) {
//         $( "#users tbody" ).append( "
" +
//           "" + name.val() + "	" +
//           "" + email.val() + "	" +
//           "" + password.val() + "	" +
//         "
" );
//         dialog.dialog( "close" );
//       }
//       return valid;
//     }

//     dialog = $( "#dialog-form" ).dialog({
//       autoOpen: false,
//       height: 300,
//       width: 350,
//       modal: true,
//       buttons: {
//         "Create an account": addUser,
//         Cancel: function() {
//           dialog.dialog( "close" );
//         }
//       },
//       close: function() {
//         form[ 0 ].reset();
//         allFields.removeClass( "ui-state-error" );
//       }
//     });

//     form = dialog.find( "form" ).on( "submit", function( event ) {
//       event.preventDefault();
//       addUser();
//     });

//     $( "#create-user" ).button().on( "click", function() {
//       dialog.dialog( "open" );
//     });
//   });
//   </script>
//
//

<commit_msg>refactored form submission logic..<commit_after>/**
* @class solgs
* general solGS app wide and misc functions
* @author Isaak Y Tecle <iyt2@cornell.edu>
*
*/

JSAN.use('jquery.blockUI');
JSAN.use('jquery.form');

function solGS () {};

solGS.waitPage = function (page) {

    if ( page.match(/solgs\/trait\//)) {
    	askUser(page);
    } else {
    	blockPage(page);
    }

}

function  askUser(page, args) {

    var t = '
This analysis may take longer than 20 min. '
	+ 'Would you like to be emailed when it is done?
';

    jQuery('
')
	.html(t)
	.dialog({
	    height : 200,
	    width  : 400,
	    modal  : true,
	    title  : "Analysis update message",
 	    buttons: {
		No: { text: "No, I will wait...",
                      click: function() {
			  jQuery(this).dialog("close");

			  displayAnalysisNow(page, args);
		      },
		    },

		Yes: { text: "Yes",
                       click: function() {
			   jQuery(this).dialog("close");

			   checkUserLogin(page, args);
		       },
		     }
	    }
	});

}

function checkUserLogin (page, args) {

    jQuery.ajax({
	type    : 'POST',
	dataType: 'json',
	url     : '/solgs/check/user/login/',
	success : function(response) {
            if (response.loggedin) {
		//include in response user data
		getProfileDialog(page, args);
            } else {
		loginAlert();
	    }
	}
    });

}

function loginAlert () {

    jQuery('
')
	.html('To use this feature, you need to log in and start over the process.')
	.dialog({
	    height : 200,
	    width  : 250,
	    modal  : true,
	    title  : 'Login Alert',
	    buttons: {
		OK: function () {
		    jQuery(this).dialog('close');

		    loginUser();
		}
	    }
	});

}

function loginUser () {

   window.location = '/solpeople/login.pl?goto_url=' + window.location.pathname;

}

function displayAnalysisNow (page, args) {

    blockPage(page, args);

 }

function blockPage (page, args) {

    goToPage(page, args);

    jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
    jQuery.blockUI({message: 'Please wait..'});

    jQuery(window).unload(function()  {
	jQuery.unblockUI();
    });

}

function goToPage (page, args) {

    alert('gotopage: ' + page)
    if (page.match(/solgs\/confirm\/request/)) {

	window.location = page;

    } else if (page.match(/solgs\/analyze\/traits\/population\//)) {

	submitTraitSelections(page, args);

    } else if (page.match(/solgs\/trait\//)) {

	window.location = page;

    }

}

function submitTraitSelections (page, args) {

    wrapTraitsForm();

    if ( typeof args.analysis_name == 'undefined') {
	document.getElementById('traits_selection_form').submit();
	document.getElementById('traits_selection_form').reset();
    } else {

	jQuery('#traits_selection_form').ajaxSubmit();
	jQuery('#traits_selection_form').resetForm();
    }
}

function wrapTraitsForm () {

    var popId  = jQuery('#population_id').val();
    var formId = ' id="traits_selection_form"';
    var action = ' action="/solgs/analyze/traits/population/' + popId + '"';
    var method = ' method="POST"';

    var traitsForm = '<form'
	+ formId
	+ action
	+ method
	+ '>'
	+ '</form>';

    jQuery('#population_traits_list').wrap(traitsForm);

}

function getProfileDialog (page, args) {
    var form = getProfileForm();

    if (args) {
	args = JSON.stringify(args);
    }

    jQuery('
', {id: 'email-form'})
	.html(form)
	.dialog({
	    height : 300,
	    width  : 300,
	    modal  : true,
	    title  : 'Submit your email',
 	    buttons: {
		Submit: function() {
		    var userName     = jQuery('#user_name').val();
		    var userEmail    = jQuery('#user_email').val();
		    var analysisName = jQuery('#analysis_name').val();
		     //validate input
		    var analysisProfile = {
			'user_name'    : userName,
			'user_email'   : userEmail,
			'analysis_name': analysisName,
			'analysis_page': page,
			'arguments'    : args,
		    }

		    jQuery(this).dialog('close');

		    saveAnalysisProfile(analysisProfile);
		},
		Cancel:  function() {
		    jQuery(this).dialog('close');
		},
	    }
	});

}

function getProfileForm () {
  //remove user name; ask for email depending on whether there is one in the db or not.
    var emailForm = '
Please fill in your email.
'
	+'
'
	+ '
'
	+  'Your name:	'
	+  '<input  type="text" name="user_name" id="user_name">	'
	+ '
'
	+ '
'
	+  'Your analysis name:	'
	+  '<input  type="text" name="analysis_name" id="analysis_name">	'
	+  '
'
	+ '
'
	+  'Email:	'
	+  '<input type="text" name="user_email" id="user_email">	'
	+ '
'
	+'
';

    return emailForm;
}

jQuery(document).ready(function (){

     jQuery('#runGS').on('click',  function() {

	 var popId = jQuery('#population_id').val();

	 var hostName = window.location.protocol
	     + '//'
	     + window.location.host;

	 var page;
	 var analysisType;

	 var traitIds = jQuery("#traits_selection_div :checkbox").fieldValue();

	 if (traitIds.length == 1) {
	     page = hostName + '/solgs/trait/' + traitIds[0] + '/population/' + popId;
	     analysisType = 'single model';
	 } else {
	     page = hostName + '/solgs/analyze/traits/population/' + popId;
	     analysisType = 'multiple models';
	 }

	 var args = {'trait_id' :  traitIds, 'population_id' :  [ popId ], 'analysis_type' : [analysisType] };

	 askUser(page, args);

     });

});

function saveAnalysisProfile (profile) {

    //make an ajax request
    //save analysis details in a file
    //run analysis, when complete, retrieve analysis owner and send an email

    jQuery.ajax({
	type    : 'POST',
	dataType: 'json',
	data    : profile,
	url     : '/solgs/save/analysis/profile/',
	success : function(response) {
            if (response.result) {
		runAnalysis(profile);
		confirmRequest();

            } else {
		jQuery('
', {id: 'error-message'})
		    .html('Failed saving your analysis profile.')
		    .dialog({
			height : 200,
			width  : 250,
			modal  : true,
			title  : 'Error message',
			buttons: {
			    OK: function () {
				jQuery(this).dialog('close');
				window.location = window.location.href;
			    }
			}
		    });
            }
	},
	error: function () {
	    jQuery('
')
		.html('Error occured calling the function to save your analysis profile.')
		.dialog({
		    height : 200,
		    width  : 250,
		    modal  : true,
		    title  : 'Error message',
		    buttons: {
			OK: function () {
			    jQuery(this).dialog('close');
			    window.location = window.location.href;
			}
		    }
		});
	}
    });

}

function runAnalysis (profile) {

    jQuery.ajax({
 	data: profile,
	url: '/solgs/run/saved/analysis/',
    });

}

function confirmRequest () {

    blockPage('/solgs/confirm/request');

}

//executes two functions alternately
jQuery.fn.alternateFunctions = function(a, b) {
    return this.each(function() {
        var clicked = false;
        jQuery(this).bind("click", function() {
            if (clicked) {
                clicked = false;
                return b.apply(this, arguments);

            }
            clicked = true;
             return a.apply(this, arguments);

        });
    });
};
//

 //  $(function() {
//     var dialog, form,

//       // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
//       emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
//       name = $( "#name" ),
//       email = $( "#email" ),
//       password = $( "#password" ),
//       allFields = $( [] ).add( name ).add( email ).add( password ),
//       tips = $( ".validateTips" );

//     function updateTips( t ) {
//       tips
//         .text( t )
//         .addClass( "ui-state-highlight" );
//       setTimeout(function() {
//         tips.removeClass( "ui-state-highlight", 1500 );
//       }, 500 );
//     }

//     function checkLength( o, n, min, max ) {
//       if ( o.val().length > max || o.val().length < min ) {
//         o.addClass( "ui-state-error" );
//         updateTips( "Length of " + n + " must be between " +
//           min + " and " + max + "." );
//         return false;
//       } else {
//         return true;
//       }
//     }

//     function checkRegexp( o, regexp, n ) {
//       if ( !( regexp.test( o.val() ) ) ) {
//         o.addClass( "ui-state-error" );
//         updateTips( n );
//         return false;
//       } else {
//         return true;
//       }
//     }

//     function addUser() {
//       var valid = true;
//       allFields.removeClass( "ui-state-error" );

//       valid = valid && checkLength( name, "username", 3, 16 );
//       valid = valid && checkLength( email, "email", 6, 80 );
//       valid = valid && checkLength( password, "password", 5, 16 );

//       valid = valid && checkRegexp( name, /^[a-z]([0-9a-z_\s])+$/i, "Username may consist of a-z, 0-9, underscores, spaces and must begin with a letter." );
//       valid = valid && checkRegexp( email, emailRegex, "eg. ui@jquery.com" );
//       valid = valid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" );

//       if ( valid ) {
//         $( "#users tbody" ).append( "
" +
//           "" + name.val() + "	" +
//           "" + email.val() + "	" +
//           "" + password.val() + "	" +
//         "
" );
//         dialog.dialog( "close" );
//       }
//       return valid;
//     }

//     dialog = $( "#dialog-form" ).dialog({
//       autoOpen: false,
//       height: 300,
//       width: 350,
//       modal: true,
//       buttons: {
//         "Create an account": addUser,
//         Cancel: function() {
//           dialog.dialog( "close" );
//         }
//       },
//       close: function() {
//         form[ 0 ].reset();
//         allFields.removeClass( "ui-state-error" );
//       }
//     });

//     form = dialog.find( "form" ).on( "submit", function( event ) {
//       event.preventDefault();
//       addUser();
//     });

//     $( "#create-user" ).button().on( "click", function() {
//       dialog.dialog( "open" );
//     });
//   });
//   </script>
//
//

<|endoftext|>