<commit_before>angular.module('selectbox', [])
    .directive('selectbox', function () {
        return {
            replace : true,
            restrict: 'E',
            scope: {
                options: '=',
                model: '=',
                width: '='
            },
            template:
                '
' +
                '

' +
                '
{{lookup[model] || placeholder}}
' +
                '
' +
                '
{{option.description}}
' +
                '
' +
                '
',
            link : function($scope, $element, $attributes) {
                $scope.inited = false;
                $scope.placeholder = $attributes.placeholder;
                $scope.style = {
                    main : {},
                    options : {}
                };
                $scope.$watch('model', function(newValue, oldValue) {
                    if (newValue != oldValue) {
                        if (!$scope.inited || typeof oldValue != 'undefined') {
                            $scope.inited = true;
                            if ($attributes.onInit)
                                $scope.$parent.$eval($attributes.onInit);
                        } else {
                            if ($attributes.onChange)
                                $scope.$parent.$eval($attributes.onChange);
                        }
                    }
                });
                $scope.$watchCollection('options', function(newValue, oldValue) {
                    if (typeof $scope.options != 'undefined') {
                        $scope.lookup = createLookup($scope.options, 'code', 'description');
                    }
                });
                if ($scope.width) {
                    $scope.style.main.width = $scope.width + 'px';
                    $scope.style.options.width = $scope.width + 'px';
                }
            }
        }
    })
    .directive('valueSelectbox', function () {
        return {
            replace : true,
            restrict: 'E',
            scope: {
                options: '=',
                width: '=',
            },
            template:
                '
' +
                '

' +
                '
{{lookup[val] || placeholder}}
' +
                '
' +
                '
{{option.description}}
' +
                '
' +
                '
',
            link : function($scope, $element, $attributes) {
                $scope.placeholder = $attributes.placeholder;
                $scope.style = {
                    main : {},
                    options : {}
                };
                $scope.changed = function($value, $event) {
                    var $subScope = $scope.$parent.$new();
                    $subScope.$value = $value;
                    $subScope.$event = $event;
                    $subScope.$eval($attributes.onChange);
                };
                $scope.$parent.$watch($attributes.value, function(newValue, oldValue) {
                    $scope.val = $scope.$parent.$eval($attributes.value);
                    $scope._disabled = $scope.$parent.$eval($attributes.disabled || 'false');
                });

                $scope.$watchCollection('options', function(newValue, oldValue) {
                    $scope.lookup = createLookup($scope.options, 'code', 'description');
                });
                if ($scope.width) {
                    $scope.style.main.width = $scope.width + 'px';
                    $scope.style.options.width = $scope.width + 'px';
                }
            }
        }
    })
    ;
<commit_msg>loginc correction<commit_after>angular.module('selectbox', [])
    .directive('selectbox', function () {
        return {
            replace : true,
            restrict: 'E',
            scope: {
                options: '=',
                model: '=',
                width: '='
            },
            template:
                '
' +
                '

' +
                '
{{lookup[model] || placeholder}}
' +
                '
' +
                '
{{option.description}}
' +
                '
' +
                '
',
            link : function($scope, $element, $attributes) {
                $scope.inited = false;
                $scope.placeholder = $attributes.placeholder;
                $scope.style = {
                    main : {},
                    options : {}
                };
                $scope.$watch('model', function(newValue, oldValue) {
                    if (newValue != oldValue) {
                        if (!$scope.inited) {
                            $scope.inited = true;
                            if ($attributes.onInit)
                                $scope.$parent.$eval($attributes.onInit);
                        } else {
                            if ($attributes.onChange)
                                $scope.$parent.$eval($attributes.onChange);
                        }
                    }
                });
                $scope.$watchCollection('options', function(newValue, oldValue) {
                    if (typeof $scope.options != 'undefined') {
                        $scope.lookup = createLookup($scope.options, 'code', 'description');
                    }
                });
                if ($scope.width) {
                    $scope.style.main.width = $scope.width + 'px';
                    $scope.style.options.width = $scope.width + 'px';
                }
            }
        }
    })
    .directive('valueSelectbox', function () {
        return {
            replace : true,
            restrict: 'E',
            scope: {
                options: '=',
                width: '=',
            },
            template:
                '
' +
                '

' +
                '
{{lookup[val] || placeholder}}
' +
                '
' +
                '
{{option.description}}
' +
                '
' +
                '
',
            link : function($scope, $element, $attributes) {
                $scope.placeholder = $attributes.placeholder;
                $scope.style = {
                    main : {},
                    options : {}
                };
                $scope.changed = function($value, $event) {
                    var $subScope = $scope.$parent.$new();
                    $subScope.$value = $value;
                    $subScope.$event = $event;
                    $subScope.$eval($attributes.onChange);
                };
                $scope.$parent.$watch($attributes.value, function(newValue, oldValue) {
                    $scope.val = $scope.$parent.$eval($attributes.value);
                    $scope._disabled = $scope.$parent.$eval($attributes.disabled || 'false');
                });

                $scope.$watchCollection('options', function(newValue, oldValue) {
                    $scope.lookup = createLookup($scope.options, 'code', 'description');
                });
                if ($scope.width) {
                    $scope.style.main.width = $scope.width + 'px';
                    $scope.style.options.width = $scope.width + 'px';
                }
            }
        }
    })
    ;
<|endoftext|>


<commit_before>function HighlightDirective () {
	return {
		restrict: 'E',
		transclude: true,
		scope: {
			language: '@'
		},
		template: '

',
		compile: function (element, attrs) {
			var tagsToReplace = {
		    '&': '&',
		    '<': '<',
		    '>': '>'
			};

			function replaceTag(tag) {
			  return tagsToReplace[tag] || tag;
			}

			function safe_tags_replace(str) {
			  return str.replace(/[&<>]/g, replaceTag);
			}

			return function (scope, element, attrs) {
				if(!_.isObject(scope.classes)) {
					scope.classes = {};
				}

				if(_.isUndefined(scope.language)) {
					scope.classes.javascript = true;
				} else if (_.isString(scope.language)) {
					scope.classes[scope.language] = true;
				}

				var el = element[0].querySelector('.highlight pre code');

				// Remove all 'ng-scope' classes from all elements (esthetic purposes)
				_.forEach(element[0].querySelectorAll('.ng-scope'), function (el) {
					el.classList.remove('ng-scope');
					// And remove all the ugly empty attribute class (why is it there anyway?)
					el.outerHTML = el.outerHTML.replace(/(class="")/g, '');
				});

				if(scope.language === 'html') {
					el.innerHTML = safe_tags_replace(el.innerHTML).trim();
				}

				// Keep the identation with 2 spaces
				el.innerHTML = el.innerHTML.replace(/\t/g, '  ');

				hljs.highlightBlock(el);
			};
		}
	};
}

angular.module('docsApp.highlight', []).directive('mbHighlight', HighlightDirective);<commit_msg>documentation/mb-highlight: match "html" string in language name, instead of checking if the language is strict "html" which it can be more than one language type, like "html xml"<commit_after>function HighlightDirective () {
	return {
		restrict: 'E',
		transclude: true,
		scope: {
			language: '@'
		},
		template: '

',
		compile: function (element, attrs) {
			var tagsToReplace = {
		    '&': '&',
		    '<': '<',
		    '>': '>'
			};

			function replaceTag(tag) {
			  return tagsToReplace[tag] || tag;
			}

			function safe_tags_replace(str) {
			  return str.replace(/[&<>]/g, replaceTag);
			}

			return function (scope, element, attrs) {
				if(!_.isObject(scope.classes)) {
					scope.classes = {};
				}

				if(_.isUndefined(scope.language)) {
					scope.classes.javascript = true;
				} else if (_.isString(scope.language)) {
					scope.classes[scope.language] = true;
				}

				var el = element[0].querySelector('.highlight pre code');

				// Remove all 'ng-scope' classes from all elements (esthetic purposes)
				_.forEach(element[0].querySelectorAll('.ng-scope'), function (el) {
					el.classList.remove('ng-scope');
					// And remove all the ugly empty attribute class (why is it there anyway?)
					el.outerHTML = el.outerHTML.replace(/(class="")/g, '');
				});

				if(/html/.test(scope.language)) {
					el.innerHTML = safe_tags_replace(el.innerHTML).trim();
				}

				// Keep the identation with 2 spaces
				el.innerHTML = el.innerHTML.replace(/\t/g, '  ');

				hljs.highlightBlock(el);
			};
		}
	};
}

angular.module('docsApp.highlight', []).directive('mbHighlight', HighlightDirective);<|endoftext|>


<commit_before>import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
// import 'react-datepicker/dist/react-datepicker.css';
import moment from 'moment';

class FilterByDate extends Component {
  constructor() {
    super();
    this.state = {
      startDate: moment('2016/07/01', 'YYYY/MM/DD', true),
      endDate: moment('2016/12/31', 'YYYY/MM/DD', true)
    };

    // to do: these will become action creators
    this.handleStartChange = this.handleStartChange.bind(this);
    this.handleEndChange = this.handleEndChange.bind(this);
  }

  handleStartChange(date) {
    // to do: make sure date is less than endDate
    // make sure date does not go below min date of data
    this.setState({
      startDate: date
    });
  }

  handleEndChange(date) {
    // to do: make sure date is greater than startDate
    // make sure date does not go above last date in data
    this.setState({
      endDate: date
    });
  }

  render() {
    const { startDate, endDate } = this.state;

    return (

Start Date:

          <DatePicker
            selected={startDate}
            onChange={this.handleStartChange}
          />

End Date:

          <DatePicker
            selected={endDate}
            onChange={this.handleStartChange}
          />

    );
  }
}

export default FilterByDate;
<commit_msg>Make sure FilterByDate end date sets end date not start date<commit_after>import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';

class FilterByDate extends Component {
  constructor() {
    super();
    this.state = {
      startDate: moment('2016/07/01', 'YYYY/MM/DD', true),
      endDate: moment('2016/12/31', 'YYYY/MM/DD', true)
    };

    // to do: these will become action creators
    this.handleStartChange = this.handleStartChange.bind(this);
    this.handleEndChange = this.handleEndChange.bind(this);
  }

  handleStartChange(date) {
    // to do: make sure date is less than endDate
    // make sure date does not go below min date of data
    this.setState({
      startDate: date
    });
  }

  handleEndChange(date) {
    // to do: make sure date is greater than startDate
    // make sure date does not go above last date in data
    this.setState({
      endDate: date
    });
  }

  render() {
    const { startDate, endDate } = this.state;

    return (

Start Date:

          <DatePicker
            selected={startDate}
            onChange={this.handleStartChange}
          />

End Date:

          <DatePicker
            selected={endDate}
            onChange={this.handleEndChange}
          />

    );
  }
}

export default FilterByDate;
<|endoftext|>


<commit_before>var dulcimer = require('dulcimer');

var SongRowFactory = new dulcimer.Model({
	// TODO: this is conceptually a 'weak' ref, should I still use a foreignkey here?
	pattern: {
		type: 'string',
		required: true,
		default: 'default'
	},
	offset: {
		type: 'integer',
		required: true,
		default: 0
	},
	len: {
		type: 'integer'
		required: true,
		default: -1  // -> natural pattern length
	},
	count: {
		type: 'integer'
		required: true,
		default: 1
	}
}, {
	name: 'song-row',
	keyType: 'uuid'
});

module.exports = SongRowFactory;
<commit_msg>...and now I have to fix this.<commit_after>var dulcimer = require('dulcimer');

var SongRowFactory = new dulcimer.Model({
	// TODO: this is conceptually a 'weak' ref, should I still use a foreignkey here?
	pattern: {
		type: 'string',
		required: true,
		default: 'default'
	},
	offset: {
		type: 'integer',
		required: true,
		default: 0
	},
	len: {
		type: 'integer',
		required: true,
		default: -1  // -> natural pattern length
	},
	count: {
		type: 'integer',
		required: true,
		default: 1
	}
}, {
	name: 'song-row',
	keyType: 'uuid'
});

module.exports = SongRowFactory;
<|endoftext|>


<commit_before>/*
 * accordion_methods.js
 */
(function($) {

function state(accordion) {
	var expected = $.makeArray(arguments).slice(1);
	var actual = [];
	$.each(expected, function(i, n) {
		actual.push( accordion.find(".ui-accordion-content").eq(i).is(":visible") ? 1 : 0 );
	});
	same(actual, expected)
}

module("accordion: methods");

test("init", function() {
	$("

").appendTo('body').accordion().remove();
	ok(true, '.accordion() called on element');

	$([]).accordion().remove();
	ok(true, '.accordion() called on empty collection');

	$('

').accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - never connected');

	$('

').appendTo('body').remove().accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - removed');

	$('

').accordion().accordion("foo").remove();
	ok(true, 'arbitrary method called after init');

	var el = $('

').accordion();
	var foo = el.data("foo.accordion");
	el.remove();
	ok(true, 'arbitrary option getter after init');

	$('

').accordion().data("foo.accordion", "bar").remove();
	ok(true, 'arbitrary option setter after init');
});

test("destroy", function() {
	$("

").appendTo('body').accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on element');

	$([]).accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on empty collection');

	$('

').accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on disconnected DOMElement');

	$('

').accordion().accordion("destroy").accordion("foo").remove();
	ok(true, 'arbitrary method called after destroy');

	var el = $('

').accordion();
	var foo = el.accordion("destroy").data("foo.accordion");
	el.remove();
	ok(true, 'arbitrary option getter after destroy');

	$('

').accordion().accordion("destroy").data("foo.accordion", "bar").remove();
	ok(true, 'arbitrary option setter after destroy');

	var expected = $('

').accordion(),
		actual = expected.accordion('destroy');
	equals(actual, expected, 'destroy is chainable');
});

test("enable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('enable');
	equals(actual, expected, 'enable is chainable');
	state(expected, 1, 0, 0)
});

test("disable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('disable');
	equals(actual, expected, 'disable is chainable');

	state(expected, 1, 0, 0)
	expected.accordion("activate", 1);
	state(expected, 1, 0, 0)
	expected.accordion("enable");
	expected.accordion("activate", 1);
	state(expected, 0, 1, 0)
});

test("activate", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('activate', 2);
	equals(actual, expected, 'activate is chainable');
});

test("activate, numeric", function() {
	var ac = $('#list1').accordion({ active: 1 });
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ac.accordion("activate", 1);
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
});

test("activate, boolean and numeric, collapsible:true", function() {
	var ac = $('#list1').accordion({collapsible: true}).accordion("activate", 2);
	state(ac, 0, 0, 1);
	ok("x", "----");
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ok("x", "----");
	ac.accordion("activate", -1);
	state(ac, 0, 0, 0);
});

test("activate, boolean, collapsible: false", function() {
	var ac = $('#list1').accordion().accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", false);
	state(ac, 0, 0, 1);
});

test("activate, string expression", function() {
	var ac = $('#list1').accordion({ active: "a:last" });
	state(ac, 0, 0, 1);
	ac.accordion("activate", ":first");
	state(ac, 1, 0, 0);
	ac.accordion("activate", ":eq(1)");
	state(ac, 0, 1, 0);
	ac.accordion("activate", ":last");
	state(ac, 0, 1, 1);
});
//[ 0, 1, 1 ] result: [ 0, 0, 1 ]
//[   0,   1,   1] result: [   0,   0,   1]
test("activate, jQuery or DOM element", function() {
	var ac = $('#list1').accordion({ active: $("#list1 a:last") });
	state(ac, 0, 0, 1);
	ac.accordion("activate", $("#list1 a:first"));
	state(ac, 1, 0, 0);
	ac.accordion("activate", $("#list1 a")[1]);
	state(ac, 0, 1, 0);
});

test("resize", function() {
	var expected = $('#list1').accordion();

	var sizes = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes.push($(this).outerHeight());
	});

	var actual = expected.accordion('resize');
	equals(actual, expected, 'resize is chainable');

	var sizes2 = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes2.push($(this).outerHeight());
	});
	same(sizes, sizes2);

	expected.find(".ui-accordion-content:first").height(500)
	var sizes3 = [];
});

})(jQuery);
<commit_msg>accordion: reverted previous change to test<commit_after>/*
 * accordion_methods.js
 */
(function($) {

function state(accordion) {
	var expected = $.makeArray(arguments).slice(1);
	var actual = [];
	$.each(expected, function(i, n) {
		actual.push( accordion.find(".ui-accordion-content").eq(i).is(":visible") ? 1 : 0 );
	});
	same(actual, expected)
}

module("accordion: methods");

test("init", function() {
	$("

").appendTo('body').accordion().remove();
	ok(true, '.accordion() called on element');

	$([]).accordion().remove();
	ok(true, '.accordion() called on empty collection');

	$('

').accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - never connected');

	$('

').appendTo('body').remove().accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - removed');

	$('

').accordion().accordion("foo").remove();
	ok(true, 'arbitrary method called after init');

	var el = $('

').accordion();
	var foo = el.data("foo.accordion");
	el.remove();
	ok(true, 'arbitrary option getter after init');

	$('

').accordion().data("foo.accordion", "bar").remove();
	ok(true, 'arbitrary option setter after init');
});

test("destroy", function() {
	$("

").appendTo('body').accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on element');

	$([]).accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on empty collection');

	$('

').accordion().accordion("destroy").remove();
	ok(true, '.accordion("destroy") called on disconnected DOMElement');

	$('

').accordion().accordion("destroy").accordion("foo").remove();
	ok(true, 'arbitrary method called after destroy');

	var el = $('

').accordion();
	var foo = el.accordion("destroy").data("foo.accordion");
	el.remove();
	ok(true, 'arbitrary option getter after destroy');

	$('

').accordion().accordion("destroy").data("foo.accordion", "bar").remove();
	ok(true, 'arbitrary option setter after destroy');

	var expected = $('

').accordion(),
		actual = expected.accordion('destroy');
	equals(actual, expected, 'destroy is chainable');
});

test("enable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('enable');
	equals(actual, expected, 'enable is chainable');
	state(expected, 1, 0, 0)
});

test("disable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('disable');
	equals(actual, expected, 'disable is chainable');

	state(expected, 1, 0, 0)
	expected.accordion("activate", 1);
	state(expected, 1, 0, 0)
	expected.accordion("enable");
	expected.accordion("activate", 1);
	state(expected, 0, 1, 0)
});

test("activate", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('activate', 2);
	equals(actual, expected, 'activate is chainable');
});

test("activate, numeric", function() {
	var ac = $('#list1').accordion({ active: 1 });
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ac.accordion("activate", 1);
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
});

test("activate, boolean and numeric, collapsible:true", function() {
	var ac = $('#list1').accordion({collapsible: true}).accordion("activate", 2);
	state(ac, 0, 0, 1);
	ok("x", "----");
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ok("x", "----");
	ac.accordion("activate", -1);
	state(ac, 0, 0, 0);
});

test("activate, boolean, collapsible: false", function() {
	var ac = $('#list1').accordion().accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", false);
	state(ac, 0, 0, 1);
});

test("activate, string expression", function() {
	var ac = $('#list1').accordion({ active: "a:last" });
	state(ac, 0, 0, 1);
	ac.accordion("activate", ":first");
	state(ac, 1, 0, 0);
	ac.accordion("activate", ":eq(1)");
	state(ac, 0, 1, 0);
	ac.accordion("activate", ":last");
	state(ac, 0, 0, 1);
});
//[ 0, 1, 1 ] result: [ 0, 0, 1 ]
//[   0,   1,   1] result: [   0,   0,   1]
test("activate, jQuery or DOM element", function() {
	var ac = $('#list1').accordion({ active: $("#list1 a:last") });
	state(ac, 0, 0, 1);
	ac.accordion("activate", $("#list1 a:first"));
	state(ac, 1, 0, 0);
	ac.accordion("activate", $("#list1 a")[1]);
	state(ac, 0, 1, 0);
});

test("resize", function() {
	var expected = $('#list1').accordion();

	var sizes = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes.push($(this).outerHeight());
	});

	var actual = expected.accordion('resize');
	equals(actual, expected, 'resize is chainable');

	var sizes2 = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes2.push($(this).outerHeight());
	});
	same(sizes, sizes2);

	expected.find(".ui-accordion-content:first").height(500)
	var sizes3 = [];
});

})(jQuery);
<|endoftext|>


<commit_before>$(function() {
	if (!window.localStorage) return;

	var now = new Date().getTime();
	var KEY = 'op_province';
	var province = null;

	var save_province = function(province) {
		var expires = now + (60 * 60 * 24 * 20);
		try {
			window.localStorage.setItem(KEY, expires + ',' + province);
		}
		catch (error) {
			// iOS loves throwing localStorage errors, e.g. whenever in private browsing
			return false;
		}
	};

	var show_province_alert = function(province) {
		var msg = null;
		if (province == 'NS') {
			msg = 'Are you in Nova Scotia? Visit OpenHouseNS for the latest from your provincial legislature.';
		}
		else if (province == 'NT') {
			msg = 'Are you in the Northwest Territories? Visit OpenNWT for the latest from your territorial legislature.';
		}
		if (msg) {
			OP.utils.notify(msg, 'success', {
				animateIn: false,
				hideAfter: 0,
				allowHTML: true,
				onClose: function() {save_province('NO');}
			});
		}
	};

	var stored = window.localStorage.getItem(KEY);
	if (stored) {
		stored = stored.split(',');
		if (now < parseInt(stored[0], 10)) {
			province = stored[1];
		}
	}

	if (province) {
		return show_province_alert(province);
	}

	$.getJSON('https://freegeoip.tahini.michaelmulley.com/json/', function(data) {
		if (data) {
			if (data.country_code == 'CA' && data.region_code) {
				save_province(data.region_code);
				show_province_alert(data.region_code);
			}
			else if (data.country_code && data.country_code !== 'CA') {
				save_province('NO');
			}
		}
	});
})<commit_msg>Don't keep geolocating when freegeoip doesn't know your province<commit_after>$(function() {
	if (!window.localStorage) return;

	var now = new Date().getTime();
	var KEY = 'op_province';
	var province = null;

	var save_province = function(province) {
		var expires = now + (60 * 60 * 24 * 20);
		try {
			window.localStorage.setItem(KEY, expires + ',' + province);
		}
		catch (error) {
			// iOS loves throwing localStorage errors, e.g. whenever in private browsing
			return false;
		}
	};

	var show_province_alert = function(province) {
		var msg = null;
		if (province == 'NS') {
			msg = 'Are you in Nova Scotia? Visit OpenHouseNS for the latest from your provincial legislature.';
		}
		else if (province == 'NT') {
			msg = 'Are you in the Northwest Territories? Visit OpenNWT for the latest from your territorial legislature.';
		}
		if (msg) {
			OP.utils.notify(msg, 'success', {
				animateIn: false,
				hideAfter: 0,
				allowHTML: true,
				onClose: function() {save_province('NO');}
			});
		}
	};

	var stored = window.localStorage.getItem(KEY);
	if (stored) {
		stored = stored.split(',');
		if (now < parseInt(stored[0], 10)) {
			province = stored[1];
		}
	}

	if (province) {
		return show_province_alert(province);
	}

	$.getJSON('https://freegeoip.tahini.michaelmulley.com/json/', function(data) {
		if (data) {
			if (data.country_code == 'CA' && data.region_code) {
				save_province(data.region_code);
				show_province_alert(data.region_code);
			}
			else if (data.country_code) {
				save_province('NO');
			}
		}
	});
})<|endoftext|>


<commit_before>//get ค่าการ sort ปัจจุบัน
function getOrderBy(){
    var strOrderBy = "&orderBy=" + orderByOld + "&orderByType=" + orderByTypeOld;
    return strOrderBy;
}

//Paging, Sorting, Search
function getHtml(numPage, orderBy){
    var recordValue = $(".record").val();
    var textSearch = $("#tbxSearch").val();
    var send = "?numPage=" + numPage + "&record=" + recordValue + "&textSearch=" + textSearch + orderBy;
    reloadId('#innerPanel', urlPost + send);
//    $.post(urlPost + send, function(data) {
//
//    });
}

//Set time
var timeUp = 300;
var timeOut = 400;
var timeDelay = 800;

//Show id
function showId(id){
    $(id).fadeIn(timeOut);
}

//Hide id
function hideId(id){
    $(id).fadeOut(timeOut);
}

//Reload id
function reloadId(id, url){
    $(id).load(url).fadeOut(timeOut).fadeIn(timeUp);
}

//Show data
$(document).ready(function() {

    // คลิกปุ่ม New
    $("#btnNew").click(function(){
        hideId("#btnShowHide");
        reloadId('#panelEvent', urlPostNew);
        return false;
    });

    // คลิกปุ่ม Edit
    $(".btnEdit").click(function(){
        hideId("#btnShowHide");
        reloadId('#panelEvent', this.href);
        document.getElementById('containerwrap').scrollIntoView(true);
        return false;
    });

    // คลิกปุ่ม Delete
    $(".btnDelete").click(function(){
        if (!confirm("คุณต้องการลบ " + namePage + " นี้ใช่หรือไม่")){
            return false;
        }
        var url = this.href;
        $.ajax({
            type : "POST",
            url : url,
            data : {checkPost: 'delete'},
            success : function(msg) {
                if (msg == "finish_math"){
                    alert('!!! ' + namePage + ' นี้มีการใช้งานอยู่ \nไม่สามารถลบออกได้');
                }else if (msg == 'finish') {
                    reloadId('#innerPanel', urlPost);
                    alert('√ ทำการลบ ' + namePage + ' เรียบร้อยแล้ว');
                } else {
                    reloadId('#panelEvent', msg);
                    alert('เกิดการผิดพลาด\n** กรุณาตรวจสอบ **');
                }
            }
        });
        return false;
    });

    // Paging
    $(".inPage").click(function(){
        var numPage = this.value;
        getHtml(numPage, getOrderBy());
        return false;
    });

    //กำหนดจำนวนหน้า
    $(".record").change(function(){
        var numPage = 1
        getHtml(numPage, getOrderBy());
        return false;
    });

    //ค้นหาด้วยข้อความ
    $("#tbxSearch").change(function(){
        var numPage = 1;
        getHtml(numPage, getOrderBy());
        return false;
    });

    //Order by
    $(".btnOrderBy").click(function(){
        var type = this.id;
        type = type.replace('sort_', '');
        var numPage = $(".disableBtn").val();
        var orderBy = "&orderBy=" + type;
        if (orderByOld == type){
            if (orderByTypeOld == 'asc'){
                orderBy += "&orderByType=desc";
            }else{
                orderBy += "&orderByType=asc";
            }
        }else{
            orderBy += "&orderByType=desc";
        }
        getHtml(numPage, orderBy);
        return false;
    });
});
<commit_msg>ยกเลิกการ reload แล้ว swarp<commit_after>//get ค่าการ sort ปัจจุบัน
function getOrderBy(){
    var strOrderBy = "&orderBy=" + orderByOld + "&orderByType=" + orderByTypeOld;
    return strOrderBy;
}

//Paging, Sorting, Search
function getHtml(numPage, orderBy){
    var recordValue = $(".record").val();
    var textSearch = $("#tbxSearch").val().trim();
    var send = "?numPage=" + numPage + "&record=" + recordValue + "&textSearch=" + textSearch + orderBy;
//    reloadId('#innerPanel', urlPost + send);
    $.post(urlPost + send, function(data) {
        $('#innerPanel').html(data);
//        reloadId('#innerPanel', data);
    });
}

//Set time
var timeUp = 300;
var timeOut = 400;
var timeDelay = 800;

//Show id
function showId(id){
    $(id).fadeIn(timeOut);
}

//Hide id
function hideId(id){
    $(id).fadeOut(timeOut);
}

//Reload id
function reloadId(id, url){
    $(id).load(url).fadeOut(timeDelay).fadeIn(timeUp);
}

//Show data
$(document).ready(function() {

    // คลิกปุ่ม New
    $("#btnNew").click(function(){
        hideId("#btnShowHide");
        reloadId('#panelEvent', urlPostNew);
        return false;
    });

    // คลิกปุ่ม Edit
    $(".btnEdit").click(function(){
        hideId("#btnShowHide");
        reloadId('#panelEvent', this.href);
        document.getElementById('containerwrap').scrollIntoView(true);
        return false;
    });

    // คลิกปุ่ม Delete
    $(".btnDelete").click(function(){
        if (!confirm("คุณต้องการลบ " + namePage + " นี้ใช่หรือไม่")){
            return false;
        }
        var url = this.href;
        $.ajax({
            type : "POST",
            url : url,
            data : {checkPost: 'delete'},
            success : function(msg) {
                if (msg == "finish_math"){
                    alert('!!! ' + namePage + ' นี้มีการใช้งานอยู่ \nไม่สามารถลบออกได้');
                }else if (msg == 'finish') {
                    reloadId('#innerPanel', urlPost);
                    alert('√ ทำการลบ ' + namePage + ' เรียบร้อยแล้ว');
                } else {
                    reloadId('#panelEvent', msg);
                    alert('เกิดการผิดพลาด\n** กรุณาตรวจสอบ **');
                }
            }
        });
        return false;
    });

    // Paging
    $(".inPage").click(function(){
        var numPage = this.value;
        getHtml(numPage, getOrderBy());
        return false;
    });

    //กำหนดจำนวนหน้า
    $(".record").change(function(){
        var numPage = 1
        getHtml(numPage, getOrderBy());
        return false;
    });

    //ค้นหาด้วยข้อความ
    $("#tbxSearch").change(function(){
        var numPage = 1;
        getHtml(numPage, getOrderBy());
        return false;
    });

    //Order by
    $(".btnOrderBy").click(function(){
        var type = this.id;
        type = type.replace('sort_', '');
        var numPage = $(".disableBtn").val();
        var orderBy = "&orderBy=" + type;
        if (orderByOld == type){
            if (orderByTypeOld == 'asc'){
                orderBy += "&orderByType=desc";
            }else{
                orderBy += "&orderByType=asc";
            }
        }else{
            orderBy += "&orderByType=desc";
        }
        getHtml(numPage, orderBy);
        return false;
    });
});
<|endoftext|>


<commit_before>define('echoContent', ['text!../views/echoContent.html', 'utils', 'jquery'], function(html, utils, $) {
    'use strict';

    // ===================================
    // ECHO CONTENT
    // ===================================

    var _echoContent = function(posts) {
        var container = utils._getId('container'),
            miniPanel = null,
            title = null,
            link = null,
            postsContainer = null,
            pContainer = null,
            i = 0,
            entries = null,
            subDiv = null,
            subLink = null;

        if (!utils._isUnd(posts) && !utils._isUnd(html)) {
            container.innerHTML = html;
            miniPanel = utils._getId('echoMiniPanel');

            if (!utils._isUnd(miniPanel)) {
                title = utils._create('h5');
                link = utils._create('a');
                postsContainer = utils._create('div');
                pContainer = utils._getId('echoContentPanel');

                title.innerHTML = posts.title;
                utils._setAttr(link, 'href', posts.link + '.html');
                link.innerHTML = posts.link;
                postsContainer.className = 'postMenu';

                if (!utils._isUnd(posts.entries) && posts.entries.length > 0) {
                    entries = posts.entries.length;
                    for (i; i < entries; i++) {
                        subDiv = utils._create('div');
                        subLink = utils._create('a');
                        utils._setAttr(subLink, 'href', '#');
                        utils._setAttr(subLink, 'data', posts.entries[i].link);
                        subLink.className = 'subMenuLink';
                        subLink.innerHTML = posts.entries[i].title;

                        subDiv.appendChild(subLink);
                        postsContainer.appendChild(subDiv);
                    }
                }
                utils._appendArr(miniPanel, [title, link, postsContainer]);
                container.appendChild(miniPanel);

                window.setTimeout(function() {
                    if (miniPanel.childNodes.length > 0) {
                        var j = 0,
                            minLength = miniPanel.childNodes.length,
                            firstNode = null;
                        for (j; j < minLength; j++) {
                            if (typeof miniPanel.childNodes[j] === 'object' && miniPanel.childNodes[j].tagName === 'DIV') {
                                firstNode = miniPanel.childNodes[j].childNodes[0].childNodes[0].getAttribute('data');
                                break;
                            }
                        }
                        utils._appendContent(pContainer, firstNode);
                    }
                }, 100);
            }

            if (!utils._isUnd(utils._getClass('subMenuLink'))) {
                $('.subMenuLink').on('click', function(ev) {
                    utils._emptyContentContainer();

                    var panel = miniPanel.childNodes[3].childNodes,
                        currentLink = ev.currentTarget.attributes.data.value,
                        i = 0,
                        panelLength = panel.length,
                        links = null;

                    for (i; i < panelLength; i++) {
                        links = panel[i].childNodes[0];
                        if ($(links).hasClass('now')) {
                            $(links).removeClass('now');
                        }
                    }

                    $(this).addClass('selected');
                    $(this).addClass('now');
                    utils._appendContent(pContainer, currentLink);
                });
            }
        }
    };

    return {
        echoContent: _echoContent
    };
});
<commit_msg>Improve code<commit_after>define('echoContent', ['utils', 'jquery'], function(utils, $) {
    'use strict';

    // ===================================
    // ECHO CONTENT
    // ===================================

    var _echoContent = function(posts) {
        var container = utils._getId('container'),
            miniPanel = null,
            title = null,
            link = null,
            postsContainer = null,
            pContainer = null,
            i = 0,
            entries = null,
            subDiv = null,
            subLink = null;

        if (!utils._isUnd(posts)) {
            miniPanel = utils._getId('echoMiniPanel');

            if (!utils._isUnd(miniPanel)) {
                title = utils._create('h5');
                link = utils._create('a');
                postsContainer = utils._create('div');
                pContainer = utils._getId('echoContentPanel');

                title.innerHTML = posts.title;
                utils._setAttr(link, 'href', posts.link + '.html');
                link.innerHTML = posts.link;
                postsContainer.className = 'postMenu';

                if (!utils._isUnd(posts.entries) && posts.entries.length > 0) {
                    entries = posts.entries.length;
                    for (i; i < entries; i++) {
                        subDiv = utils._create('div');
                        subLink = utils._create('a');
                        utils._setAttr(subLink, 'href', '#');
                        utils._setAttr(subLink, 'data', posts.entries[i].link);
                        subLink.className = 'subMenuLink';
                        subLink.innerHTML = posts.entries[i].title;

                        subDiv.appendChild(subLink);
                        postsContainer.appendChild(subDiv);
                    }
                }
                utils._appendArr(miniPanel, [title, link, postsContainer]);
                container.appendChild(miniPanel);

                window.setTimeout(function() {
                    if (miniPanel.childNodes.length > 0) {
                        var j = 0,
                            minLength = miniPanel.childNodes.length,
                            firstNode = null;
                        for (j; j < minLength; j++) {
                            if (typeof miniPanel.childNodes[j] === 'object' && miniPanel.childNodes[j].tagName === 'DIV') {
                                firstNode = miniPanel.childNodes[j].childNodes[0].childNodes[0].getAttribute('data');
                                break;
                            }
                        }
                        utils._appendContent(pContainer, firstNode);
                    }
                }, 100);
            }

            if (!utils._isUnd(utils._getClass('subMenuLink'))) {
                $('.subMenuLink').on('click', function(ev) {
                    utils._emptyContentContainer();

                    var panel = miniPanel.childNodes[2].childNodes,
                        currentLink = ev.currentTarget.attributes.data.value,
                        i = 0,
                        panelLength = panel.length,
                        links = null;

                    for (i; i < panelLength; i++) {
                        links = panel[i].childNodes[0];
                        if ($(links).hasClass('now')) {
                            $(links).removeClass('now');
                        }
                    }

                    $(this).addClass('selected');
                    $(this).addClass('now');
                    utils._appendContent(pContainer, currentLink);
                });
            }
        }
    };

    return {
        echoContent: _echoContent
    };
});
<|endoftext|>


<commit_before>'use strict';

angular.module('polls').controller('PollsSearchController', [
  '$location',
  '$scope',
  '$state',
  'Authentication',
  'CategorysService',
  'Action',
  '$stateParams',
  'Storages',
  'Constants',
  'toastr',
  'ngDialog',
  'Profile',
  function ($location, $scope, $state, Authentication, Categorys, Action, $stateParams, Storages, Constants, toast, dialog, Profile) {
    $scope.user = Authentication.user;
    $scope.isLogged = ($scope.user) ? true : false;
    $scope.detailToggle = -1;
    $scope.form = {};
    $scope.categorys = Categorys.query();

    $scope.condition = {};
    $scope.condition.key = $stateParams.key;
    $scope.condition.in = $stateParams.in;
    $scope.condition.status = $stateParams.status;
    $scope.condition.ctgr = $stateParams.ctgr;

    $scope.condition.cmt = $stateParams.cmt;
    $scope.condition.compare = $stateParams.compare;

    $scope.condition.created = $stateParams.created;
    $scope.condition.timing = $stateParams.timing;

    $scope.condition.sort = $stateParams.sort;
    $scope.condition.sortkind = $stateParams.sortkind;

    $scope.condition.by = $stateParams.by;
    if ($scope.condition.by) {
      $scope.selectedUser = Profile.get({ id: $scope.condition.by });
    }
    $scope.search = () => {
      $state.go('search', $scope.condition);
    };

    $scope.busy = false;
    $scope.polls = [];
    $scope.sort = '-poll.created';
    excute();
    function excute() {
      if (check_params()) {
        $scope.busy = true;
        Action.search($scope.condition)
          .then(res => {
            $scope.polls = res.data;
            var promise = [];
            $scope.polls.forEach(function (item) {
              promise.push(get_owner_follow(item.poll));
              promise.push(get_reported(item.poll));
              promise.push(get_bookmarked(item.poll));
            }, this);
            return Promise.all(promise);
          })
          .then(res => {
            create_sort();
            $scope.busy = false;
          })
          .catch(err => {
            $scope.busy = false;
            console.log(err);
          });
      } else {
        $scope.condition = JSON.parse(Storages.get_local(Constants.storages.preferences, JSON.stringify({})));
      }
    }
    function check_params() {
      if ($scope.condition.key || $scope.condition.status || $scope.condition.by || $scope.condition.ctgr || $scope.condition.cmt || $scope.condition.created) {
        return true;
      }
      return false;
    }
    function create_sort() {
      if ($scope.condition.sort) {
        var prefix = ($scope.condition.sort === 'created') ? 'poll.' : 'report.';
        var kind = ($scope.condition.sortkind === 'desc') ? '-' : '';
        $scope.sort = kind + prefix + $scope.condition.sort;
      }
    }

    function get_owner_follow(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.follow = {};
          return resolve();
        }
        Action.get_follow(poll._id)
          .then(res => {
            poll.follow = res.data || { poll: poll._id };
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    function get_reported(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.reported = false;
          return resolve();
        }
        Action.get_report(poll._id)
          .then(res => {
            poll.reported = (res.data) ? res.data : false;
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    function get_bookmarked(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.bookmarked = false;
          return resolve();
        }
        Action.get_bookmark(poll._id)
          .then(res => {
            poll.bookmarked = (res.data) ? res.data : false;
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    $scope.selectedUserFn = function (selected) {
      if (selected) {
        $scope.condition.by = selected.originalObject._id;
        $scope.selectedUser = selected.originalObject;
      } else {
        $scope.condition.by = undefined;
        $scope.selectedUser = undefined;
      }
    };
    $scope.clear_preferences = () => {
      $scope.condition = {};
      Storages.set_local(Constants.storages.preferences, JSON.stringify($scope.condition));
      $location.url($location.path());
    };
    $scope.save_preferences = () => {
      Storages.set_local(Constants.storages.preferences, JSON.stringify($scope.condition));
    };
    $scope.delete_poll = (poll) => {
      if (poll.user._id !== $scope.user._id) {
        toast.error('You are not authorized.', 'Error!');
        return;
      }
      $scope.message_title = 'Delete poll!';
      $scope.message_content = 'Are you sure you want to delete this poll?';
      $scope.dialog_type = 3;
      $scope.buton_label = 'delete';
      dialog.openConfirm({
        scope: $scope,
        templateUrl: 'modules/core/client/views/templates/confirm.dialog.template.html'
      }).then(confirm => {
        handle_delete();
      }, reject => {
      });
      function handle_delete() {
        $scope.polls = _.reject($scope.polls, function (item) {
          return item.poll._id === poll._id;
        });
        // Action.delete_poll(poll);
      }
    };
    $scope.report_poll = (poll) => {
      if (poll.reported) {
        toast.error('You are already reported ' + poll.title, 'Error!');
        return;
      }
      dialog.openConfirm({
        scope: $scope,
        templateUrl: 'modules/core/client/views/templates/report.dialog.template.html'
      }).then(reason => {
        handle_confirm(reason);
      }, reject => {
      });
      function handle_confirm(reason) {
        Action.save_report(poll._id, reason)
          .then(res => {
            poll.reported = (res) ? true : false;
            toast.success('You have successfully reported ' + poll.title, 'Thank you!');
          })
          .catch(err => {
            toast.error(err.message, 'Error!');
          });
      }
    };
    $scope.bookmark_poll = (poll) => {
      if (poll.bookmarked) {
        toast.error('You are already bookmark ' + poll.title, 'Error!');
        return;
      }
      Action.save_bookmark(poll._id)
        .then(res => {
          poll.bookmarked = (res) ? true : false;
          toast.success('Added ' + poll.title + ' to bookmarks.', 'Success!');
        })
        .catch(err => {
          toast.error(err.message, 'Error!');
        });
    };
    $scope.follow_poll = (poll) => {
      if (!$scope.isLogged) {
        toast.error('You must login to follow poll.', 'Error!');
        return;
      }
      Action.save_follow(poll.follow)
        .then(res => {
          poll.follow = res;
          if (poll.follow.following) {
            toast.success('You followed ' + poll.title, 'Success!');
          }
        })
        .catch(err => {
          toast.error(err.message, 'Error!');
        });
    };
  }
]);
<commit_msg>Commited from lenh at Fri, Jul 21, 2017  4:34:09 PM<commit_after>'use strict';

angular.module('polls').controller('PollsSearchController', [
  '$location',
  '$scope',
  '$state',
  'Authentication',
  'CategorysService',
  'Action',
  '$stateParams',
  'Storages',
  'Constants',
  'toastr',
  'ngDialog',
  'Profile',
  function ($location, $scope, $state, Authentication, Categorys, Action, $stateParams, Storages, Constants, toast, dialog, Profile) {
    $scope.user = Authentication.user;
    $scope.isLogged = ($scope.user) ? true : false;
    $scope.detailToggle = -1;
    $scope.form = {};
    $scope.categorys = Categorys.query();

    $scope.condition = {};
    $scope.condition.key = $stateParams.key;
    $scope.condition.in = $stateParams.in;
    $scope.condition.status = $stateParams.status;
    $scope.condition.ctgr = $stateParams.ctgr;

    $scope.condition.cmt = $stateParams.cmt;
    $scope.condition.compare = $stateParams.compare;

    $scope.condition.created = $stateParams.created;
    $scope.condition.timing = $stateParams.timing;

    $scope.condition.sort = $stateParams.sort;
    $scope.condition.sortkind = $stateParams.sortkind;

    $scope.condition.by = $stateParams.by;
    if ($scope.condition.by) {
      $scope.selectedUser = Profile.get({ _id: $scope.condition.by });
    }
    $scope.search = () => {
      $state.go('search', $scope.condition);
    };

    $scope.busy = false;
    $scope.polls = [];
    $scope.sort = '-poll.created';
    excute();
    function excute() {
      if (check_params()) {
        $scope.busy = true;
        Action.search($scope.condition)
          .then(res => {
            $scope.polls = res.data;
            var promise = [];
            $scope.polls.forEach(function (item) {
              promise.push(get_owner_follow(item.poll));
              promise.push(get_reported(item.poll));
              promise.push(get_bookmarked(item.poll));
            }, this);
            return Promise.all(promise);
          })
          .then(res => {
            create_sort();
            $scope.busy = false;
          })
          .catch(err => {
            $scope.busy = false;
            console.log(err);
          });
      } else {
        $scope.condition = JSON.parse(Storages.get_local(Constants.storages.preferences, JSON.stringify({})));
      }
    }
    function check_params() {
      if ($scope.condition.key || $scope.condition.status || $scope.condition.by || $scope.condition.ctgr || $scope.condition.cmt || $scope.condition.created) {
        return true;
      }
      return false;
    }
    function create_sort() {
      if ($scope.condition.sort) {
        var prefix = ($scope.condition.sort === 'created') ? 'poll.' : 'report.';
        var kind = ($scope.condition.sortkind === 'desc') ? '-' : '';
        $scope.sort = kind + prefix + $scope.condition.sort;
      }
    }

    function get_owner_follow(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.follow = {};
          return resolve();
        }
        Action.get_follow(poll._id)
          .then(res => {
            poll.follow = res.data || { poll: poll._id };
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    function get_reported(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.reported = false;
          return resolve();
        }
        Action.get_report(poll._id)
          .then(res => {
            poll.reported = (res.data) ? res.data : false;
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    function get_bookmarked(poll) {
      return new Promise((resolve, reject) => {
        if (!$scope.isLogged) {
          poll.bookmarked = false;
          return resolve();
        }
        Action.get_bookmark(poll._id)
          .then(res => {
            poll.bookmarked = (res.data) ? res.data : false;
            return resolve(res.data);
          })
          .catch(err => {
            return reject(err);
          });
      });
    }
    $scope.selectedUserFn = function (selected) {
      if (selected) {
        $scope.condition.by = selected.originalObject._id;
        $scope.selectedUser = selected.originalObject;
      } else {
        $scope.condition.by = undefined;
        $scope.selectedUser = undefined;
      }
    };
    $scope.clear_preferences = () => {
      $scope.condition = {};
      Storages.set_local(Constants.storages.preferences, JSON.stringify($scope.condition));
      $location.url($location.path());
    };
    $scope.save_preferences = () => {
      Storages.set_local(Constants.storages.preferences, JSON.stringify($scope.condition));
    };
    $scope.delete_poll = (poll) => {
      if (poll.user._id !== $scope.user._id) {
        toast.error('You are not authorized.', 'Error!');
        return;
      }
      $scope.message_title = 'Delete poll!';
      $scope.message_content = 'Are you sure you want to delete this poll?';
      $scope.dialog_type = 3;
      $scope.buton_label = 'delete';
      dialog.openConfirm({
        scope: $scope,
        templateUrl: 'modules/core/client/views/templates/confirm.dialog.template.html'
      }).then(confirm => {
        handle_delete();
      }, reject => {
      });
      function handle_delete() {
        $scope.polls = _.reject($scope.polls, function (item) {
          return item.poll._id === poll._id;
        });
        // Action.delete_poll(poll);
      }
    };
    $scope.report_poll = (poll) => {
      if (poll.reported) {
        toast.error('You are already reported ' + poll.title, 'Error!');
        return;
      }
      dialog.openConfirm({
        scope: $scope,
        templateUrl: 'modules/core/client/views/templates/report.dialog.template.html'
      }).then(reason => {
        handle_confirm(reason);
      }, reject => {
      });
      function handle_confirm(reason) {
        Action.save_report(poll._id, reason)
          .then(res => {
            poll.reported = (res) ? true : false;
            toast.success('You have successfully reported ' + poll.title, 'Thank you!');
          })
          .catch(err => {
            toast.error(err.message, 'Error!');
          });
      }
    };
    $scope.bookmark_poll = (poll) => {
      if (poll.bookmarked) {
        toast.error('You are already bookmark ' + poll.title, 'Error!');
        return;
      }
      Action.save_bookmark(poll._id)
        .then(res => {
          poll.bookmarked = (res) ? true : false;
          toast.success('Added ' + poll.title + ' to bookmarks.', 'Success!');
        })
        .catch(err => {
          toast.error(err.message, 'Error!');
        });
    };
    $scope.follow_poll = (poll) => {
      if (!$scope.isLogged) {
        toast.error('You must login to follow poll.', 'Error!');
        return;
      }
      Action.save_follow(poll.follow)
        .then(res => {
          poll.follow = res;
          if (poll.follow.following) {
            toast.success('You followed ' + poll.title, 'Success!');
          }
        })
        .catch(err => {
          toast.error(err.message, 'Error!');
        });
    };
  }
]);
<|endoftext|>


<commit_before>/*
 * accordion_methods.js
 */
(function($) {

module("accordion: methods");

test("init", function() {
	$("

").appendTo('body').accordion().remove();
	ok(true, '.accordion() called on element');

	$([]).accordion().remove();
	ok(true, '.accordion() called on empty collection');

	$('

').accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - never connected');

	$('

').appendTo('body').remove().accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - removed');

	$('

').accordion().accordion("foo").remove();
	ok(true, 'arbitrary method called after init');

	var el = $('

').accordion();
	var foo = el.accordion("option", "foo");
	el.remove();
	ok(true, 'arbitrary option getter after init');

	$('

').accordion().accordion("option", "foo", "bar").remove();
	ok(true, 'arbitrary option setter after init');
});

test("destroy", function() {
	var beforeHtml = $("#list1").parent().html();
	var afterHtml = $("#list1").accordion().accordion("destroy").parent().html();
	equal( afterHtml, beforeHtml );
});

test("enable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('enable');
	equals(actual, expected, 'enable is chainable');
	state(expected, 1, 0, 0)
});

test("disable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('disable');
	equals(actual, expected, 'disable is chainable');

	state(expected, 1, 0, 0)
	expected.accordion("activate", 1);
	state(expected, 1, 0, 0)
	expected.accordion("enable");
	expected.accordion("activate", 1);
	state(expected, 0, 1, 0)
});

test("activate", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('activate', 2);
	equals(actual, expected, 'activate is chainable');
});

test("activate, numeric", function() {
	var ac = $('#list1').accordion({ active: 1 });
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ac.accordion("activate", 1);
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
});

test("activate, boolean and numeric, collapsible:true", function() {
	var ac = $('#list1').accordion({collapsible: true}).accordion("activate", 2);
	state(ac, 0, 0, 1);
	ok("x", "----");
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ok("x", "----");
	ac.accordion("activate", -1);
	state(ac, 0, 0, 0);
});

test("activate, boolean, collapsible: false", function() {
	var ac = $('#list1').accordion().accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", false);
	state(ac, 0, 0, 1);
});

test("activate, string expression", function() {
	var ac = $('#list1').accordion({ active: "a:last" });
	state(ac, 0, 0, 1);
	ac.accordion("activate", ":first");
	state(ac, 1, 0, 0);
	ac.accordion("activate", ":eq(1)");
	state(ac, 0, 1, 0);
	ac.accordion("activate", ":last");
	state(ac, 0, 0, 1);
});

test("activate, jQuery or DOM element", function() {
	var ac = $('#list1').accordion({ active: $("#list1 a:last") });
	state(ac, 0, 0, 1);
	ac.accordion("activate", $("#list1 a:first"));
	state(ac, 1, 0, 0);
	ac.accordion("activate", $("#list1 a")[1]);
	state(ac, 0, 1, 0);
});

test("resize", function() {
	var expected = $('#list1').parent().height(300).end().accordion({
		fillSpace: true
	});

	var sizes = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes.push($(this).outerHeight());
	});

	var actual = expected.accordion('resize');
	equals(actual, expected, 'resize is chainable');

	var sizes2 = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes2.push($(this).outerHeight());
	});
	same(sizes, [246, 246, 246]);

	expected.parent().height(500);
	expected.accordion("resize");
	var sizes2 = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes2.push($(this).outerHeight());
	});
	same(sizes2, [446, 446, 446]);
});

})(jQuery);
<commit_msg>Accordion unit tests: Cleaned and fixed resize-method test, using #navigation avoids the :visible matching display:none issue in IE8<commit_after>/*
 * accordion_methods.js
 */
(function($) {

module("accordion: methods");

test("init", function() {
	$("

").appendTo('body').accordion().remove();
	ok(true, '.accordion() called on element');

	$([]).accordion().remove();
	ok(true, '.accordion() called on empty collection');

	$('

').accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - never connected');

	$('

').appendTo('body').remove().accordion().remove();
	ok(true, '.accordion() called on disconnected DOMElement - removed');

	$('

').accordion().accordion("foo").remove();
	ok(true, 'arbitrary method called after init');

	var el = $('

').accordion();
	var foo = el.accordion("option", "foo");
	el.remove();
	ok(true, 'arbitrary option getter after init');

	$('

').accordion().accordion("option", "foo", "bar").remove();
	ok(true, 'arbitrary option setter after init');
});

test("destroy", function() {
	var beforeHtml = $("#list1").parent().html();
	var afterHtml = $("#list1").accordion().accordion("destroy").parent().html();
	equal( afterHtml, beforeHtml );
});

test("enable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('enable');
	equals(actual, expected, 'enable is chainable');
	state(expected, 1, 0, 0)
});

test("disable", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('disable');
	equals(actual, expected, 'disable is chainable');

	state(expected, 1, 0, 0)
	expected.accordion("activate", 1);
	state(expected, 1, 0, 0)
	expected.accordion("enable");
	expected.accordion("activate", 1);
	state(expected, 0, 1, 0)
});

test("activate", function() {
	var expected = $('#list1').accordion(),
		actual = expected.accordion('activate', 2);
	equals(actual, expected, 'activate is chainable');
});

test("activate, numeric", function() {
	var ac = $('#list1').accordion({ active: 1 });
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ac.accordion("activate", 1);
	state(ac, 0, 1, 0);
	ac.accordion("activate", 2);
	state(ac, 0, 0, 1);
});

test("activate, boolean and numeric, collapsible:true", function() {
	var ac = $('#list1').accordion({collapsible: true}).accordion("activate", 2);
	state(ac, 0, 0, 1);
	ok("x", "----");
	ac.accordion("activate", 0);
	state(ac, 1, 0, 0);
	ok("x", "----");
	ac.accordion("activate", -1);
	state(ac, 0, 0, 0);
});

test("activate, boolean, collapsible: false", function() {
	var ac = $('#list1').accordion().accordion("activate", 2);
	state(ac, 0, 0, 1);
	ac.accordion("activate", false);
	state(ac, 0, 0, 1);
});

test("activate, string expression", function() {
	var ac = $('#list1').accordion({ active: "a:last" });
	state(ac, 0, 0, 1);
	ac.accordion("activate", ":first");
	state(ac, 1, 0, 0);
	ac.accordion("activate", ":eq(1)");
	state(ac, 0, 1, 0);
	ac.accordion("activate", ":last");
	state(ac, 0, 0, 1);
});

test("activate, jQuery or DOM element", function() {
	var ac = $('#list1').accordion({ active: $("#list1 a:last") });
	state(ac, 0, 0, 1);
	ac.accordion("activate", $("#list1 a:first"));
	state(ac, 1, 0, 0);
	ac.accordion("activate", $("#list1 a")[1]);
	state(ac, 0, 1, 0);
});

test("resize", function() {
	var expected = $('#navigation').parent().height(300).end().accordion({
		fillSpace: true
	});

	var sizes = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes.push($(this).outerHeight());
	});
	same(sizes, [246, 246, 246]);

	expected.parent().height(500);
	expected.accordion("resize");
	var sizes2 = [];
	expected.find(".ui-accordion-content").each(function() {
		sizes2.push($(this).outerHeight());
	});
	same(sizes2, [446, 446, 446]);
});

})(jQuery);
<|endoftext|>


<commit_before>const got = require('got');

const cache = require('../utils/cache.js');
const time = require('../utils/time.js');

// Get trips for stop.
async function getTrips(id) {

	const now = time.getSeconds();
	const data = JSON.parse((await got(`http://elron.ee/api/v1/stop?stop=${encodeURIComponent(id)}`)).body).data;

	if (!data) throw new Error("Provider 'Elron' is not returning data");
	if (data.text) throw new Error(data.text);

	const trips = [];

	for (const trip of data) if (time.toSeconds(trip.plaaniline_aeg) > now) trips.push({
		time: time.toSeconds(trip.plaaniline_aeg),
		countdown: time.toSeconds(trip.plaaniline_aeg) - now,
		name: trip.reis,
		destination: trip.liin,
		type: 'train',
		live: false,
		provider: 'elron'
	});

	return trips.slice(0, 15);

}

module.exports = {
	getTrips
};
<commit_msg>Add caching to Elron provider (api)<commit_after>const got = require('got');

const cache = require('../utils/cache.js');
const time = require('../utils/time.js');

// Get trips for stop.
async function getTrips(id) {

	const now = time.getSeconds();

	return (await cache.use('elron-trips', id, async () => {

		const data = JSON.parse((await got(`http://elron.ee/api/v1/stop?stop=${encodeURIComponent(id)}`)).body).data;

		if (!data) throw new Error("Provider 'Elron' is not returning data");
		if (data.text) throw new Error(data.text);

		return data.map((trip) => ({
			time: time.toSeconds(trip.plaaniline_aeg),
			countdown: time.toSeconds(trip.plaaniline_aeg) - now,
			name: trip.reis,
			destination: trip.liin,
			type: 'train',
			live: false,
			provider: 'elron'
		}));

	})).filter((trip) => trip.time > now).slice(0, 15);

}

module.exports = {
	getTrips
};
<|endoftext|>


<commit_before>import React from 'react';

import SpellLink from 'common/SpellLink';
import SPELLS from 'common/SPELLS';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage, formatMilliseconds } from 'common/format';

import Analyzer from 'parser/core/Analyzer';

import StatisticListBoxItem from 'interface/others/StatisticListBoxItem';
import { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import ExpandableStatisticBox from 'interface/others/ExpandableStatisticBox';
import STATISTIC_CATEGORY from 'interface/others/STATISTIC_CATEGORY';

import Combatants from 'parser/shared/modules/Combatants';
import CooldownThroughputTracker from '../features/CooldownThroughputTracker';

class Wellspring extends Analyzer {
  static dependencies = {
    combatants: Combatants,
    cooldownThroughputTracker: CooldownThroughputTracker,
  };
  healing = 0;
  wellspringCasts = [];
  wellspringTimestamps = [];
  castNumber = 0;
  castEvent = {};

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTalent(SPELLS.WELLSPRING_TALENT.id);
  }

  on_byPlayer_begincast(event) {
    if (event.ability.guid !== SPELLS.WELLSPRING_TALENT.id || event.isCancelled) {
      return;
    }

    if (this.wellspringCasts[this.castNumber] && this.wellspringCasts[this.castNumber] < 6) {
      this.registerInefficientCast();
    }

    this.castNumber += 1;
    this.wellspringTimestamps[this.castNumber] = event.timestamp;
  }

  on_byPlayer_cast(event) {
    if (event.ability.guid !== SPELLS.WELLSPRING_TALENT.id || event.isCancelled) {
      return;
    }

    this.castEvent = event;
  }

  on_byPlayer_heal(event) {
    const spellId = event.ability.guid;

    if (spellId !== SPELLS.WELLSPRING_HEAL.id) {
      return;
    }

    if (!this.wellspringCasts[this.castNumber]) {
      this.wellspringCasts[this.castNumber] = 0;
    }

    this.healing += event.amount + (event.absorbed || 0);

    // Pets aren't really interesting to us as they don't work against the mechanic of wellspring
    const combatant = this.combatants.players[event.targetID];
    if (!combatant) {
      return;
    }

    // Fully overhealed events don't affect wellsprings cap and are discarded
    if (event.overheal && event.amount === 0) {
      return;
    }

    this.wellspringCasts[this.castNumber] += 1;
  }

  on_finished() {
    if (this.wellspringCasts[this.castNumber] && this.wellspringCasts[this.castNumber] < 6 && !this.castEvent.meta) {
      this.registerInefficientCast();
    }
  }

  registerInefficientCast() {
    // Avoid breaking the page on pre-combat casts
    if (!this.castEvent) {
      return;
    }
    this.castEvent.meta = this.castEvent.meta || {};
    this.castEvent.meta.isInefficientCast = true;
    this.castEvent.meta.inefficientCastReason = `This Wellspring cast hit less than 6 targets.`;
  }

  get averageHitsPerCast() {
    const totalHits = this.wellspringCasts.reduce((total, hits) => total + hits, 0);
    return totalHits / this.numberOfCasts;
  }

  get wellspringEfficiency() {
    return 1 - this.inefficientCasts / this.numberOfCasts;
  }

  get numberOfCasts() {
    // this.wellspringCasts[0] is there for pre-combat casts, most of the time this will be empty
    return this.wellspringCasts.length - (!this.wellspringCasts[0] ? 1 : 0);
  }

  get inefficientCasts() {
    return this.wellspringCasts.reduce((total, hits) => hits < 6 ? total + 1 : total, 0);
  }

  suggestions(when) {
    const suggestionThreshold = this.suggestionThreshold;
    when(suggestionThreshold.actual).isLessThan(suggestionThreshold.isLessThan.minor)
      .addSuggestion((suggest, actual, recommended) => {
        return suggest(You're not making full use of the potential of <SpellLink id={SPELLS.WELLSPRING_TALENT.id} />. Try to aim it towards stacks of injured players with 6 people or more.)
          .icon(SPELLS.WELLSPRING_TALENT.icon)
          .actual(`${formatPercentage(suggestionThreshold.actual)}% efficiency`)
          .recommended(`>${formatPercentage(suggestionThreshold.isLessThan.minor)}% efficiency is recommended`)
          .regular(suggestionThreshold.isLessThan.average).major(suggestionThreshold.isLessThan.average);
      });
  }

  get suggestionThreshold() {
    return {
      actual: this.wellspringEfficiency,
      isLessThan: {
        minor: 0.8,
        average: 0.6,
        major: 0.5,
      },
      style: 'percentage',
    };
  }

  statistic() {
    if (isNaN(this.averageHitsPerCast)) {
      return false;
    }

    return (
      <ExpandableStatisticBox
        icon={<SpellIcon id={SPELLS.WELLSPRING_TALENT.id} />}
        label="Wellspring target efficiency"
        value={`${formatPercentage(this.wellspringEfficiency)} %`}
        tooltip={`The average number of targets healed by Wellspring out of the minimum amount of 6 targets to archive the maximum potential healing.`}
        category={STATISTIC_CATEGORY.TALENTS}
        position={STATISTIC_ORDER.OPTIONAL(100)}
      >

              Cast
              Time
              # of Hits

            {
              this.wellspringCasts.map((hits, index) => (

                  { index }
                  { formatMilliseconds(this.wellspringTimestamps[index] - this.owner.fight.start_time) || 0 }
                  <td style={hits < 6 ? {color: 'red' , fontWeight: 'bold'} : {fontWeight: 'bold'}}>{ hits }

              ))
            }

      </ExpandableStatisticBox>
    );
  }

  subStatistic() {
    const feeding = this.cooldownThroughputTracker.getIndirectHealing(SPELLS.WELLSPRING_HEAL.id);
    return (
      <StatisticListBoxItem
        title={<SpellLink id={SPELLS.WELLSPRING_TALENT.id} />}
        value={`${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.healing + feeding))} %`}
      />
    );
  }

}

export default Wellspring;

<commit_msg>update formatting<commit_after>import React from 'react';

import SpellLink from 'common/SpellLink';
import SPELLS from 'common/SPELLS';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage, formatDuration } from 'common/format';

import Analyzer from 'parser/core/Analyzer';

import StatisticListBoxItem from 'interface/others/StatisticListBoxItem';
import { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import ExpandableStatisticBox from 'interface/others/ExpandableStatisticBox';
import STATISTIC_CATEGORY from 'interface/others/STATISTIC_CATEGORY';

import Combatants from 'parser/shared/modules/Combatants';
import CooldownThroughputTracker from '../features/CooldownThroughputTracker';

class Wellspring extends Analyzer {
  static dependencies = {
    combatants: Combatants,
    cooldownThroughputTracker: CooldownThroughputTracker,
  };
  healing = 0;
  wellspringCasts = [];
  wellspringTimestamps = [];
  castNumber = 0;
  castEvent = {};

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTalent(SPELLS.WELLSPRING_TALENT.id);
  }

  on_byPlayer_begincast(event) {
    if (event.ability.guid !== SPELLS.WELLSPRING_TALENT.id || event.isCancelled) {
      return;
    }

    if (this.wellspringCasts[this.castNumber] && this.wellspringCasts[this.castNumber] < 6) {
      this.registerInefficientCast();
    }

    this.castNumber += 1;
    this.wellspringTimestamps[this.castNumber] = event.timestamp;
  }

  on_byPlayer_cast(event) {
    if (event.ability.guid !== SPELLS.WELLSPRING_TALENT.id || event.isCancelled) {
      return;
    }

    this.castEvent = event;
  }

  on_byPlayer_heal(event) {
    const spellId = event.ability.guid;

    if (spellId !== SPELLS.WELLSPRING_HEAL.id) {
      return;
    }

    if (!this.wellspringCasts[this.castNumber]) {
      this.wellspringCasts[this.castNumber] = 0;
    }

    this.healing += event.amount + (event.absorbed || 0);

    // Pets aren't really interesting to us as they don't work against the mechanic of wellspring
    const combatant = this.combatants.players[event.targetID];
    if (!combatant) {
      return;
    }

    // Fully overhealed events don't affect wellsprings cap and are discarded
    if (event.overheal && event.amount === 0) {
      return;
    }

    this.wellspringCasts[this.castNumber] += 1;
  }

  on_finished() {
    if (this.wellspringCasts[this.castNumber] && this.wellspringCasts[this.castNumber] < 6 && !this.castEvent.meta) {
      this.registerInefficientCast();
    }
  }

  registerInefficientCast() {
    // Avoid breaking the page on pre-combat casts
    if (!this.castEvent) {
      return;
    }
    this.castEvent.meta = this.castEvent.meta || {};
    this.castEvent.meta.isInefficientCast = true;
    this.castEvent.meta.inefficientCastReason = `This Wellspring cast hit less than 6 targets.`;
  }

  get averageHitsPerCast() {
    const totalHits = this.wellspringCasts.reduce((total, hits) => total + hits, 0);
    return totalHits / this.numberOfCasts;
  }

  get wellspringEfficiency() {
    return 1 - this.inefficientCasts / this.numberOfCasts;
  }

  get numberOfCasts() {
    // this.wellspringCasts[0] is there for pre-combat casts, most of the time this will be empty
    return this.wellspringCasts.length - (!this.wellspringCasts[0] ? 1 : 0);
  }

  get inefficientCasts() {
    return this.wellspringCasts.reduce((total, hits) => hits < 6 ? total + 1 : total, 0);
  }

  suggestions(when) {
    const suggestionThreshold = this.suggestionThreshold;
    when(suggestionThreshold.actual).isLessThan(suggestionThreshold.isLessThan.minor)
      .addSuggestion((suggest, actual, recommended) => {
        return suggest(You're not making full use of the potential of <SpellLink id={SPELLS.WELLSPRING_TALENT.id} />. Try to aim it towards stacks of injured players with 6 people or more.)
          .icon(SPELLS.WELLSPRING_TALENT.icon)
          .actual(`${formatPercentage(suggestionThreshold.actual)}% efficiency`)
          .recommended(`>${formatPercentage(suggestionThreshold.isLessThan.minor)}% efficiency is recommended`)
          .regular(suggestionThreshold.isLessThan.average).major(suggestionThreshold.isLessThan.average);
      });
  }

  get suggestionThreshold() {
    return {
      actual: this.wellspringEfficiency,
      isLessThan: {
        minor: 0.8,
        average: 0.6,
        major: 0.5,
      },
      style: 'percentage',
    };
  }

  statistic() {
    if (isNaN(this.averageHitsPerCast)) {
      return false;
    }
    const nth = (number) => ["st","nd","rd"][((number+90)%100-10)%10-1]||"th";

    return (
      <ExpandableStatisticBox
        icon={<SpellIcon id={SPELLS.WELLSPRING_TALENT.id} />}
        label="Wellspring target efficiency"
        value={`${formatPercentage(this.wellspringEfficiency)} %`}
        tooltip={`The average number of targets healed by Wellspring out of the minimum amount of 6 targets to archive the maximum potential healing.`}
        category={STATISTIC_CATEGORY.TALENTS}
        position={STATISTIC_ORDER.OPTIONAL(100)}
      >

              Cast
              Time

            {
              this.wellspringCasts.map((hits, index) => (

                  { index }{ nth(index) }
                  { formatDuration((this.wellspringTimestamps[index] - this.owner.fight.start_time) / 1000) || 0 }
                  <td style={hits < 6 ? {color: 'red' , fontWeight: 'bold'} : {fontWeight: 'bold'}}>{ hits } hits

              ))
            }

      </ExpandableStatisticBox>
    );
  }

  subStatistic() {
    const feeding = this.cooldownThroughputTracker.getIndirectHealing(SPELLS.WELLSPRING_HEAL.id);
    return (
      <StatisticListBoxItem
        title={<SpellLink id={SPELLS.WELLSPRING_TALENT.id} />}
        value={`${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.healing + feeding))} %`}
      />
    );
  }

}

export default Wellspring;

<|endoftext|>


<commit_before>// From https://gist.github.com/1343518
// Modified by Hakim to handle Markdown indented with tabs
(function(){

    if( typeof marked === 'undefined' ) {
        throw 'The reveal.js Markdown plugin requires marked to be loaded';
    }

    if (typeof hljs !== 'undefined') {
        marked.setOptions({
            highlight: function (lang, code) {
                return hljs.highlightAuto(lang, code).value;
            }
        });
    }

    var stripLeadingWhitespace = function(section) {

        var template = section.querySelector( 'script' );

        // strip leading whitespace so it isn't evaluated as code
        var text = ( template || section ).textContent;

        var leadingWs = text.match(/^\n?(\s*)/)[1].length,
            leadingTabs = text.match(/^\n?(\t*)/)[1].length;

        if( leadingTabs > 0 ) {
            text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
        }
        else if( leadingWs > 1 ) {
            text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
        }

        return text;

    };

    var twrap = function(el) {
        var content = el.content || el;
        content += el.asideContent ? ('' + el.asideContent + '') : '';
        return '';
    };

    var getForwardedAttributes = function(section) {
        var attributes = section.attributes;
        var result = [];

        for( var i = 0, len = attributes.length; i < len; i++ ) {
            var name = attributes[i].name,
                value = attributes[i].value;

            // disregard attributes that are used for markdown loading/parsing
            if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;

            if( value ) {
                result.push( name + '=' + value );
            }
            else {
                result.push( name );
            }
        }

        return result.join( ' ' );
    };

    var slidifyMarkdown = function(markdown, separator, vertical, notes, attributes) {

        separator = separator || '^\n---\n$';
        notes = notes || 'note:';

        var separatorRegex = new RegExp( separator + ( vertical ? '|' + vertical : '' ), 'mg' ),
            horizontalSeparatorRegex = new RegExp( separator ),
            notesSeparatorRegex = new RegExp( notes, 'mgi' ),
            matches,
            noteMatch,
            lastIndex = 0,
            isHorizontal,
            wasHorizontal = true,
            content,
            asideContent,
            slide,
            sectionStack = [],
            markdownSections = '';

        // iterate until all blocks between separators are stacked up
        while( matches = separatorRegex.exec( markdown ) ) {
            asideContent = null;

            // determine direction (horizontal by default)
            isHorizontal = horizontalSeparatorRegex.test( matches[0] );

            if( !isHorizontal && wasHorizontal ) {
                // create vertical stack
                sectionStack.push( [] );
            }

            // pluck slide content from markdown input
            content = markdown.substring( lastIndex, matches.index );
            noteMatch = content.split( notesSeparatorRegex );

            if( noteMatch.length === 2 ) {
                content = noteMatch[0];
                asideContent = noteMatch[1].trim();
            }

            slide = {
                content: content,
                asideContent: asideContent || ""
            };

            if( isHorizontal && wasHorizontal ) {
                // add to horizontal stack
                sectionStack.push(slide);
            } else {
                // add to vertical stack
                sectionStack[sectionStack.length-1].push(slide);
            }

            lastIndex = separatorRegex.lastIndex;
            wasHorizontal = isHorizontal;
        }

        // add the remaining slide
        (wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1]).push(markdown.substring(lastIndex));

        // flatten the hierarchical stack, and insert
 tags
        for( var k = 0, klen = sectionStack.length; k < klen; k++ ) {
            // vertical
            if( sectionStack[k].propertyIsEnumerable(length) && typeof sectionStack[k].splice === 'function' ) {
                markdownSections += '
' +
                                        '
' +  sectionStack[k].map(twrap).join('

') + '
' +
                                    '
';
            } else {
                markdownSections += '
' + twrap( sectionStack[k] ) + '
';
            }
        }

        return markdownSections;
    };

    var querySlidingMarkdown = function() {

        var sections = document.querySelectorAll( '[data-markdown]'),
            section;

        for( var j = 0, jlen = sections.length; j < jlen; j++ ) {

            section = sections[j];

            if( section.getAttribute('data-markdown').length ) {

                var xhr = new XMLHttpRequest(),
                    url = section.getAttribute('data-markdown');

                datacharset = section.getAttribute('data-charset');
                // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
                if (datacharset != null && datacharset != '') {
                    xhr.overrideMimeType('text/html; charset=' + datacharset);
                }

                xhr.onreadystatechange = function () {
                    if( xhr.readyState === 4 ) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), section.getAttribute('data-notes'), getForwardedAttributes(section) );
                        } else {
                            section.outerHTML = '
ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status +
                                '. Check your browser\'s JavaScript console for more details.' +
                                '
Remember that you need to serve the presentation HTML from a HTTP server and the Markdown file must be there too.

';
                        }
                    }
                };

                xhr.open('GET', url, false);
                try {
                    xhr.send();
                } catch (e) {
                    alert('Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e);
                }

            } else if( section.getAttribute('data-separator') ) {

                var markdown = stripLeadingWhitespace(section);
                section.outerHTML = slidifyMarkdown( markdown, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), section.getAttribute('data-notes'), getForwardedAttributes(section) );

            }
        }

    };

    var queryMarkdownSlides = function() {

        var sections = document.querySelectorAll( '[data-markdown]');

        for( var j = 0, jlen = sections.length; j < jlen; j++ ) {

            makeHtml(sections[j]);

        }

    };

    var makeHtml = function(section) {

        var notes = section.querySelector( 'aside.notes' );

        var markdown = stripLeadingWhitespace(section);

        section.innerHTML = marked(markdown);

        if( notes ) {
            section.appendChild( notes );
        }

    };

    querySlidingMarkdown();

    queryMarkdownSlides();

})();
<commit_msg>update markdown plugin formatting to match reveal.js core<commit_after>// From https://gist.github.com/1343518
// Modified by Hakim to handle Markdown indented with tabs
(function(){

	if( typeof marked === 'undefined' ) {
		throw 'The reveal.js Markdown plugin requires marked to be loaded';
	}

	if( typeof hljs !== 'undefined' ) {
		marked.setOptions({
			highlight: function( lang, code ) {
				return hljs.highlightAuto( lang, code ).value;
			}
		});
	}

	var stripLeadingWhitespace = function( section ) {

		var template = section.querySelector( 'script' );

		// strip leading whitespace so it isn't evaluated as code
		var text = ( template || section ).textContent;

		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;

		if( leadingTabs > 0 ) {
			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
		}
		else if( leadingWs > 1 ) {
			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
		}

		return text;

	};

	var twrap = function( el ) {

		var content = el.content || el;

		if( el.asideContent ) {
			content += '' + el.asideContent + '';
		}

		return '';

	};

	var getForwardedAttributes = function( section ) {

		var attributes = section.attributes;
		var result = [];

		for( var i = 0, len = attributes.length; i < len; i++ ) {
			var name = attributes[i].name,
				value = attributes[i].value;

			// disregard attributes that are used for markdown loading/parsing
			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;

			if( value ) {
				result.push( name + '=' + value );
			}
			else {
				result.push( name );
			}
		}

		return result.join( ' ' );

	};

	var slidifyMarkdown = function( markdown, separator, vertical, notes, attributes ) {

		separator = separator || '^\n---\n$';
		notes = notes || 'note:';

		var separatorRegex = new RegExp( separator + ( vertical ? '|' + vertical : '' ), 'mg' ),
			horizontalSeparatorRegex = new RegExp( separator ),
			notesSeparatorRegex = new RegExp( notes, 'mgi' ),
			matches,
			noteMatch,
			lastIndex = 0,
			isHorizontal,
			wasHorizontal = true,
			content,
			asideContent,
			slide,
			sectionStack = [],
			markdownSections = '';

		// iterate until all blocks between separators are stacked up
		while( matches = separatorRegex.exec( markdown ) ) {
			asideContent = null;

			// determine direction (horizontal by default)
			isHorizontal = horizontalSeparatorRegex.test( matches[0] );

			if( !isHorizontal && wasHorizontal ) {
				// create vertical stack
				sectionStack.push( [] );
			}

			// pluck slide content from markdown input
			content = markdown.substring( lastIndex, matches.index );
			noteMatch = content.split( notesSeparatorRegex );

			if( noteMatch.length === 2 ) {
				content = noteMatch[0];
				asideContent = noteMatch[1].trim();
			}

			slide = {
				content: content,
				asideContent: asideContent || ''
			};

			if( isHorizontal && wasHorizontal ) {
				// add to horizontal stack
				sectionStack.push(slide);
			} else {
				// add to vertical stack
				sectionStack[sectionStack.length-1].push(slide);
			}

			lastIndex = separatorRegex.lastIndex;
			wasHorizontal = isHorizontal;
		}

		// add the remaining slide
		(wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1]).push(markdown.substring(lastIndex));

		// flatten the hierarchical stack, and insert
 tags
		for( var k = 0, klen = sectionStack.length; k < klen; k++ ) {
			// vertical
			if( sectionStack[k].propertyIsEnumerable( length ) && typeof sectionStack[k].splice === 'function' ) {
				markdownSections += '
' +
										'
' +  sectionStack[k].map( twrap ).join( '

' ) + '
' +
									'
';
			} else {
				markdownSections += '
' + twrap( sectionStack[k] ) + '
';
			}
		}

		return markdownSections;
	};

	var queryExternalMarkdown = function() {

		var sections = document.querySelectorAll( '[data-markdown]'),
			section;

		for( var j = 0, jlen = sections.length; j < jlen; j++ ) {

			section = sections[j];

			if( section.getAttribute( 'data-markdown' ).length ) {

				var xhr = new XMLHttpRequest(),
					url = section.getAttribute( 'data-markdown' );

				datacharset = section.getAttribute( 'data-charset' );

				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
				if( datacharset != null && datacharset != '' ) {
					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
				}

				xhr.onreadystatechange = function() {
					if( xhr.readyState === 4 ) {
						if ( xhr.status >= 200 && xhr.status < 300 ) {
							section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute( 'data-separator' ), section.getAttribute( 'data-vertical' ), section.getAttribute( 'data-notes' ), getForwardedAttributes( section ) );
						}
						else {
							section.outerHTML = '
ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status +
								'. Check your browser\'s JavaScript console for more details.' +
								'
Remember that you need to serve the presentation HTML from a HTTP server and the Markdown file must be there too.

';
						}
					}
				};

				xhr.open( 'GET', url, false );

				try {
					xhr.send();
				}
				catch ( e ) {
					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
				}

			} else if( section.getAttribute( 'data-separator' ) ) {

				var markdown = stripLeadingWhitespace( section );
				section.outerHTML = slidifyMarkdown( markdown, section.getAttribute( 'data-separator' ), section.getAttribute( 'data-vertical' ), section.getAttribute( 'data-notes' ), getForwardedAttributes( section ) );

			}
		}

	};

	var queryMarkdownSlides = function() {

		var sections = document.querySelectorAll( '[data-markdown]');

		for( var j = 0, jlen = sections.length; j < jlen; j++ ) {

			makeHtml( sections[j] );

		}

	};

	var makeHtml = function( section ) {

		var notes = section.querySelector( 'aside.notes' );

		var markdown = stripLeadingWhitespace( section );

		section.innerHTML = marked( markdown );

		if( notes ) {
			section.appendChild( notes );
		}

	};

	queryExternalMarkdown();
	queryMarkdownSlides();

})();
<|endoftext|>