Skip to content

Instantly share code, notes, and snippets.

@brandonregard
Created August 8, 2017 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonregard/32709a55e56a61bd9e9b6399db09f56b to your computer and use it in GitHub Desktop.
Save brandonregard/32709a55e56a61bd9e9b6399db09f56b to your computer and use it in GitHub Desktop.
wunderground using jQuery, backbone, and flot...
wui.Models = {};
wui.Collections = {};
wui.Views = {};
wui.backbone = {};
(function(b, c) {
var a = {
isValidMeasurement: function(d) {
if (d === null) {
return false
} else {
if (typeof (d) == "undefined") {
return false
} else {
if (d === "") {
return false
} else {
if (d == "-999") {
return false
} else {
if (d == "-9999") {
return false
} else {
if (parseFloat(d) <= -999) {
return false
} else {
return true
}
}
}
}
}
}
},
convertNumbersInString: function(j, i) {
if (_.isNull(j) || _.isUndefined(j) || _.isUndefined(i)) {
return j
}
var f = /\d+/g;
var k = 0;
var g = 0;
var e = "";
var h;
var d;
j = j.toString();
while ((d = f.exec(j)) !== null) {
e += j.substring(k, d.index);
h = i(d);
e += h;
k = d.index + d.toString().length
}
return e
},
filterObject: function(f, e) {
var d = {};
_.each(f, function(h, g) {
if (e(g, h)) {
d[g] = h
}
});
return d
},
fromDateObjectToTimestamp: function(e, d) {
var f = (d) ? d.tz_offset_hours : 0;
return Date.UTC(parseInt(e.year, 10), parseInt(e.mon, 10) - 1, parseInt(e.mday, 10), parseInt(e.hour, 10) + f, parseInt(e.min, 10))
},
fromPrefToBoolean: function(d, e) {
if (d === "1" || d === 1 || d === "true" || d === true) {
return true
} else {
if (d === "0" || d === 0 || d === "false" || d === false) {
return false
} else {
return e
}
}
},
getBeginningOfDay: function(f, h) {
var g = new Date(f);
var e = b.date.increment(g, h, "hour");
var i = b.date.floor(e, "day");
return i
},
getTimestamp: function(i, e) {
var h = (e) ? e.tz_offset_hours : 0;
if (c.type(i) === "date") {
var g = b.date.create(h, "hour", i);
var f = g.getTime();
return f
} else {
if (i.utcdate) {
return a.fromDateObjectToTimestamp(i.utcdate, e)
} else {
if (i.FCTTIME) {
return (parseFloat(i.FCTTIME.epoch) + h * 3600) * 1000
} else {
if (i.date && i.date.epoch) {
var f = (parseFloat(i.date.epoch) + h * 3600) * 1000;
return f
} else {
if (i.epoch) {
var f = (parseFloat(i.epoch) + h * 3600) * 1000;
return f
}
}
}
}
}
return null
},
getTimeAgo: function(j, g) {
g = c.extend({
now: null,
numFields: 0
}, g);
var m = [];
var e = g.now;
if (!e) {
e = new Date()
}
var l = e - j;
var k = Math.round(l / 1000);
var n = k % 60
, f = Math.floor(k / 60) % 60
, h = Math.floor(k / 3600);
if (h > 0) {
m.push({
period: "hour",
label: "hr",
value: h
})
}
if (f > 0) {
m.push({
period: "minute",
label: "min",
value: f
})
}
if (true) {
m.push({
period: "second",
label: "sec",
value: n
})
}
if (g.numFields) {
m = _.first(m, g.numFields)
}
var i = _.map(m, function(d) {
return d.value + " " + d.label
}).join(" ");
i += " ago";
return i
},
getTimezoneFromAPI: function(e) {
var f = null;
var d = e.get("response.date");
if (d) {
f = _.pick(d, ["tz_short", "tz_long", "tz_offset_text", "tz_offset_hours"])
}
return f
},
getAstronomyMarkings: function(s, e, m) {
var n = null
, f = null
, k = []
, e = e || {}
, o = null
, q = null
, g = (e.dayColor != "transparent")
, r = (e.nightColor != "transparent")
, m = m || null;
if (!s) {
return k
}
for (var j = 0, h = s.length; j < h; j++) {
var p = s[j];
if (p.sunrise.date.epoch) {
n = new Date(p.sunrise.date.epoch * 1000);
o = a.getTimestamp(n, m)
}
if (r) {
f = c.extend({
xaxis: {
from: q,
to: o
}
}, {
color: e.nightColor,
yaxis: e.yaxis
});
k.push(f)
}
if (p.sunset.date.epoch) {
n = new Date(p.sunset.date.epoch * 1000);
q = a.getTimestamp(n, m)
}
if (g) {
f = c.extend({
xaxis: {
from: o,
to: q
}
}, {
color: e.dayColor,
yaxis: e.yaxis
});
k.push(f)
}
}
if (r) {
f = c.extend({
xaxis: {
from: q,
to: null
}
}, {
color: e.nightColor,
yaxis: e.yaxis
});
k.push(f)
}
return k
},
getVariableUnits: function(e, g, d) {
var f = "";
if (c.isFunction(e.units)) {
f = e.units.call(null, g, e, d)
} else {
if (e.units) {
f = '<span class="units">' + e.units + "</span>"
}
}
return f
},
hourlyStripes: function(i) {
var l = i.xaxis;
if (l.options.mode != "time") {
return null
}
var g = [];
var f = b.date.floor(new Date(l.min), "day")
, n = new Date(l.max)
, m = (l.max - l.min)
, j = 86400 * 1000 * 1.02
, k = (m > j) ? 6 : 1
, h = b.date.roundDownTo(f, k, "hour")
, e = null;
while (h < n) {
e = b.date.create(k, "hour", h);
h = b.date.create(k, "hour", e);
g.push({
xaxis: {
from: e.getTime(),
to: h.getTime()
},
color: "#ffffff"
})
}
return g
},
rotate: function(e, i) {
var h = false;
if (Modernizr && Modernizr.csstransforms) {
h = true
}
if (!h) {
return
}
var g;
var f;
var d = (i % 1) ? i.toFixed(4) : i;
if (h) {
g = "transform";
f = "rotate(" + d + "deg)";
if (Modernizr && Modernizr.prefixed) {
g = Modernizr.prefixed(g)
}
}
if (g) {
e.css(g, f)
}
},
roundTimestamp: function(d, e) {
e = e || 1;
return Math.round(d / e) * e
},
setTransitionDuration: function(d, g) {
var h = false;
if (Modernizr && Modernizr.csstransitions) {
h = true
}
if (!h) {
return
}
var f = "TransitionDuration";
var e = "" + g + "ms";
if (Modernizr && Modernizr.prefixed) {
f = Modernizr.prefixed(f)
}
if (f) {
d.css(f, e)
}
},
symbols: {
arrow: function(g, f, j, e, i) {
var d = 2 * e;
var h = d * 2 / 3;
g.moveTo(f - h / 2, j - d / 2);
g.lineTo(f, j - d / 4);
g.lineTo(f + h / 2, j - d / 2);
if (!i) {
g.lineTo(f, j + d / 2);
g.lineTo(f - h / 2, j - d / 2)
}
}
},
tickPresets: {
"1day": {
tickSize: [1, "day"],
timeformat: "%a %m/%d"
},
"3hour": {
tickSize: [3, "hour"],
timeformat: "%l %p"
}
},
tickZoomPresets: {
"1day3hour": function(e) {
var d = a.tickPresets;
if (e) {
return d["3hour"]
} else {
return d["1day"]
}
}
},
translate: function(j, d) {
var m = d.x || 0;
var k = d.y || 0;
var i = d.z || 0;
var l = (m % 1) ? m.toFixed(4) : m;
var g = (k % 1) ? k.toFixed(4) : k;
var f = (i % 1) ? i.toFixed(4) : i;
var o;
var n;
var e = false;
var h = false;
if (Modernizr && Modernizr.csstransforms3d) {
h = true
}
if (Modernizr && Modernizr.csstransforms) {
e = true
}
if (h || e) {
o = "transform";
if (Modernizr && Modernizr.prefixed) {
o = Modernizr.prefixed(o)
}
if (h) {
n = "translate3d(" + l + "px, " + g + "px, " + f + "px)"
} else {
if (e) {
n = "translate(" + l + "px, " + g + "px)"
}
}
} else {
o = "left";
n = m
}
if (o) {
j.css(o, n)
}
},
updateVariable: function(g, d, f, e) {
e = c.extend(true, {
classNames: {
updated: "wx-updated",
windDirVariable: "wind-dir-vrb",
wxdata: "wx-data",
wxunit: "wx-unit",
wxvalue: "wx-value"
},
duration: 5000,
unit: null
}, e);
if (e.duration > 0) {
g.addClass(e.classNames.updated).delay(e.duration).queue(function() {
c(this).removeClass(e.classNames.updated).dequeue()
})
}
g.find("." + e.classNames.wxvalue).html(f);
if (e.unit !== null) {
g.find("." + e.classNames.wxunit).html(e.unit)
}
},
generateCityQuery: function(e) {
var d = "";
var f = e.country ? e.country.toLowerCase() : "us";
d += "/zmw:" + e.zip + "." + e.magic + "." + e.wmo;
return d
}
};
b.backbone.utils = a
})(wui, jQuery);
(function(b, c) {
var a = b.backbone.utils;
var d = {
createPlotGroupModel: function(e) {
e = e || {};
var g = e.weather;
var n = e.prefs;
if (!n && b.bootstrapped) {
n = b.bootstrapped.prefs
}
var j = g.get("forecast.days[0]");
var m = j.summary.date;
var k = a.fromPrefToBoolean(n.EXPFCT, true) || g.get("forecast.source") === "bestfct";
var h = k ? 10 : 7;
var l = a.getBeginningOfDay(m.epoch * 1000, m.tz_offset_hours);
var f = b.date.create(h, "day", l);
var i = new b.Models.PlotGroup({
astronomy: {
markings: {
show: true
}
},
bufferLeft: c(window).width(),
bufferRight: c(window).width(),
date_min: l,
date_max: f,
legends: true,
needleNow: true,
selectors: {
editDone: "#editDone",
editMode: "#editMode",
variablesMenu: "#plotVariablesMenu"
},
tickZoomPreset: "1day3hour",
zoomable: true,
flot: {
series: {
grow: {
active: false
}
},
},
plots: [{
variables: [],
astronomy: {
markings: {
show: false
}
},
flot: {
datelabel: {
show: true
},
yaxis: {
show: false
}
}
}, {
autoscale: true,
variables: [{
preset: "dewpoint",
show: a.fromPrefToBoolean(n.CP_VAR_dp, false)
}, {
preset: "feelslike",
show: a.fromPrefToBoolean(n.CP_VAR_fl, false)
}, {
preset: "temperature",
show: a.fromPrefToBoolean(n.CP_VAR_temp, true)
}],
flot: {
grid: {
borderWidth: {
top: 0,
right: 1,
bottom: 1,
left: 1
}
},
yaxis: {
tickUnitsPreset: "temperature"
}
},
freezeline: true,
reserveSpace: [10, 10]
}, {
variables: [{
preset: "cloudcover",
show: a.fromPrefToBoolean(n.CP_VAR_cc, false)
}, {
preset: "pop",
show: a.fromPrefToBoolean(n.CP_VAR_pop, true),
legend: false,
options: {
lines: {
fill: false
}
}
}, {
preset: "pop_type_notsnow",
show: a.fromPrefToBoolean(n.CP_VAR_pop, true)
}, {
preset: "pop_type_snow",
show: a.fromPrefToBoolean(n.CP_VAR_pop, true)
}, {
preset: "humidity",
show: a.fromPrefToBoolean(n.CP_VAR_h, false)
}, {
preset: "pressure",
show: a.fromPrefToBoolean(n.CP_VAR_p, true),
options: {
yaxis: 2
}
}],
flot: {
yaxes: [{
min: 0,
max: 100,
ticks: [0, 25, 50, 75, 100],
tickUnitsPreset: "humidity"
}, {
tickDecimalsPreset: "pressure"
}]
}
}, {
variables: [{
preset: "precip_today",
show: a.fromPrefToBoolean(n.CP_VAR_precip, false)
}, {
preset: "liquid_precip",
show: a.fromPrefToBoolean(n.CP_VAR_qpf, false)
}],
flot: {
yaxis: {
min: 0,
tickDecimalsPreset: "precip",
ticksPreset: "precip"
}
}
}, {
variables: [{
preset: "wind_speed_dir",
show: a.fromPrefToBoolean(n.CP_VAR_wspd, true)
}]
}]
});
return i
}
};
b.backbone.configs = d
})(wui, jQuery);
wui.global.colorscales = {
"-60": "#9f94a7",
"-59": "#9f94a7",
"-58": "#9f94a7",
"-57": "#9f94a7",
"-56": "#9f94a7",
"-55": "#896ea0",
"-54": "#896ea0",
"-53": "#896ea0",
"-52": "#896ea0",
"-51": "#896ea0",
"-50": "#754a9a",
"-49": "#754a9a",
"-48": "#754a9a",
"-47": "#754a9a",
"-46": "#754a9a",
"-45": "#7c409f",
"-44": "#7c409f",
"-43": "#7c409f",
"-42": "#7c409f",
"-41": "#7c409f",
"-40": "#883da5",
"-39": "#883da5",
"-38": "#883da5",
"-37": "#883da5",
"-36": "#883da5",
"-35": "#953aac",
"-34": "#953aac",
"-33": "#953aac",
"-32": "#953aac",
"-31": "#953aac",
"-30": "#8341b4",
"-29": "#8341b4",
"-28": "#8341b4",
"-27": "#8341b4",
"-26": "#8341b4",
"-25": "#6f47bc",
"-24": "#6f47bc",
"-23": "#6f47bc",
"-22": "#6f47bc",
"-21": "#6f47bc",
"-20": "#5b4ec4",
"-19": "#5b4ec4",
"-18": "#5b4ec4",
"-17": "#5b4ec4",
"-16": "#5b4ec4",
"-15": "#445bc7",
"-14": "#445bc7",
"-13": "#445bc7",
"-12": "#445bc7",
"-11": "#445bc7",
"-10": "#4655c9",
"-9": "#4655c9",
"-8": "#4655c9",
"-7": "#4655c9",
"-6": "#4655c9",
"-5": "#1767c3",
"-4": "#1767c3",
"-3": "#1767c3",
"-2": "#1767c3",
"-1": "#1767c3",
"0": "#1278c8",
"1": "#1278c8",
"2": "#1278c8",
"3": "#1278c8",
"4": "#1278c8",
"5": "#1f91d7",
"6": "#1f91d7",
"7": "#1f91d7",
"8": "#1f91d7",
"9": "#1f91d7",
"10": "#2aa8e5",
"11": "#2aa8e5",
"12": "#2aa8e5",
"13": "#2aa8e5",
"14": "#2aa8e5",
"15": "#36c1f3",
"16": "#36c1f3",
"17": "#36c1f3",
"18": "#36c1f3",
"19": "#36c1f3",
"20": "#30bfef",
"21": "#30bfef",
"22": "#30bfef",
"23": "#30bfef",
"24": "#30bfef",
"25": "#28b7e6",
"26": "#28b7e6",
"27": "#28b7e6",
"28": "#28b7e6",
"29": "#28b7e6",
"30": "#1fafdd",
"31": "#1fafdd",
"32": "#1fafdd",
"33": "#1fafdd",
"34": "#1fafdd",
"35": "#32afb1",
"36": "#32afb1",
"37": "#32afb1",
"38": "#32afb1",
"39": "#32afb1",
"40": "#52b673",
"41": "#52b673",
"42": "#52b673",
"43": "#52b673",
"44": "#52b673",
"45": "#71bc3c",
"46": "#71bc3c",
"47": "#71bc3c",
"48": "#71bc3c",
"49": "#71bc3c",
"50": "#93c124",
"51": "#93c124",
"52": "#93c124",
"53": "#93c124",
"54": "#93c124",
"55": "#b6c609",
"56": "#b6c609",
"57": "#b6c609",
"58": "#b6c609",
"59": "#b6c609",
"60": "#f4b701",
"61": "#f4b701",
"62": "#f4b701",
"63": "#f4b701",
"64": "#f4b701",
"65": "#feae3c",
"66": "#feae3c",
"67": "#feae3c",
"68": "#feae3c",
"69": "#feae3c",
"70": "#fe9a3b",
"71": "#fe9a3b",
"72": "#fe9a3b",
"73": "#fe9a3b",
"74": "#fe9a3b",
"75": "#fd843b",
"76": "#fd843b",
"77": "#fd843b",
"78": "#fd843b",
"79": "#fd843b",
"80": "#ec5a34",
"81": "#ec5a34",
"82": "#ec5a34",
"83": "#ec5a34",
"84": "#ec5a34",
"85": "#da2f2f",
"86": "#da2f2f",
"87": "#da2f2f",
"88": "#da2f2f",
"89": "#da2f2f",
"90": "#d72a36",
"91": "#d72a36",
"92": "#d72a36",
"93": "#d72a36",
"94": "#d72a36",
"95": "#da3a45",
"96": "#da3a45",
"97": "#da3a45",
"98": "#da3a45",
"99": "#da3a45",
"100": "#dc4953",
"101": "#dc4953",
"102": "#dc4953",
"103": "#dc4953",
"104": "#dc4953",
"105": "#df5961",
"106": "#df5961",
"107": "#df5961",
"108": "#df5961",
"109": "#df5961",
"110": "#e26870",
"111": "#e26870",
"112": "#e26870",
"113": "#e26870",
"114": "#e26870",
"115": "#e5787f",
"116": "#e5787f",
"117": "#e5787f",
"118": "#e5787f",
"119": "#e5787f",
"120": "#e8878d",
"121": "#e8878d",
"122": "#e8878d",
"123": "#e8878d",
"124": "#e8878d",
"125": "#e8878d",
"126": "#e8878d",
"127": "#e8878d",
"128": "#e8878d",
"129": "#e8878d",
"130": "#e8878d",
"131": "#e8878d",
"132": "#e8878d",
"133": "#e8878d",
"134": "#e8878d",
"135": "#e8878d",
"136": "#e8878d",
"137": "#e8878d",
"138": "#e8878d",
"139": "#e8878d",
"140": "#e8878d",
"141": "#e8878d",
"142": "#e8878d",
"143": "#e8878d",
"144": "#e8878d",
"145": "#e8878d",
"146": "#e8878d",
"147": "#e8878d",
"148": "#e8878d",
"149": "#e8878d",
"150": "#e8878d",
"151": "#e8878d",
"152": "#e8878d",
"153": "#e8878d",
"154": "#e8878d",
"155": "#e8878d"
};
(function(a) {
if (!window.Backbone) {
return
}
wui.Models.Page = Backbone.NestedModel.extend({
defaults: function() {
return {
classNames: {
hover: "hover",
loading: "loading",
open: "open",
selected: "selected",
updated: "wx-updated",
windDirVariable: "wind-dir-vrb",
wxdata: "wx-data",
wxunit: "wx-unit",
wxvalue: "wx-value"
},
iconset: "k",
favorites: {
bar: {
show: false
},
list: {
enabled: false,
show: false
}
},
timezone: {
"short": "UTC",
"long": "UTC",
offset: {
text: "+0000",
hours: 0
}
},
zmw: ""
}
},
initialize: function(b, d) {
var e = _.result(this, "defaults");
var c = a.extend(true, {}, e, b);
this.set(c, d);
this.changed = {}
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
wui.Views.Header = Backbone.View.extend({
events: {
"submit #wuForm": "onSearchSubmit",
"focus #wuSearch": "onSearchOpen",
"blur #wuSearch": "onSearchClose",
"click .geolocate-wrap": "onGeolocate",
"click .menu-geolocate": "onGeolocate"
},
initialize: function(c) {
this.options = c || {};
var d = b("#feature-menu-mobile");
if (wui.sidebar && wui.Menu && d[0]) {
b("<a>", {
id: "sidebar-gutter"
}).appendTo("#inner-wrap");
var e = {
classNames: {
selected: "sidebar-active"
},
eventName: "click.sidebar",
selectors: {
toggles: "#sidebarButton, #sidebar-gutter"
}
};
wui.sidebar.initialize(e);
new wui.Menu({
selectors: {
container: "#feature-menu-mobile .sidebar-wrapper"
}
})
}
a();
if (wui.HorizontalMenu) {
new wui.HorizontalMenu({
menu: b("#feature-menu"),
selectors: {
menu: "ul.menu-list.primary-menu",
menu_item: "li"
},
active_menu_class: "active",
hidden_menu_class: "hidden"
});
b(".subnav-contain").each(function() {
new wui.HorizontalMenu({
menu: b(this),
selectors: {
menu: "> .subnav.subnav-left",
right_matter: "> .subnav.subnav-right"
},
active_menu_class: "active"
})
});
b(".wui-tabs-more-dl").each(function() {
new wui.HorizontalMenu({
menu: b(this),
selectors: {
menu: "> dl",
menu_item: "dd"
},
tags: {
menu: "dl",
menu_item: "dd"
}
})
})
}
},
onSearchSubmit: function(c) {
var f = this.$el.find("#wuSearch");
var d = f.val();
if (!d) {
c.preventDefault();
f.focus()
}
},
onSearchOpen: function() {
this.$el.addClass("search-open")
},
onSearchClose: function() {
this.$el.removeClass("search-open")
},
onGeolocate: function() {
var e = this;
var d = {
searching: "Finding your location...",
success: "Loading forecast...",
successWundermap: "Loading location...",
error_permissions: "Can't find location. Check permissions.",
error_generic: "Couldn't find location. Try searching.",
};
var c = wui.bootstrapped && wui.bootstrapped.pageType === "WunderMap";
if (navigator.geolocation) {
this.$alertBar = b("#header-alert-bar").addClass("active").removeClass("not-found");
this.$alertBar.text(d.searching);
navigator.geolocation.getCurrentPosition(function(f) {
var j = false;
if (f && f.coords) {
var h = f.coords.latitude;
var i = f.coords.longitude;
if (typeof h !== "undefined" && typeof i !== "undefined") {
var g = h + "," + i;
j = true;
e.showGeolocateFinished(c ? d.successWundermap : d.success, true);
if (c) {
b("#wuSearch").val(g);
wundermap.search.useAutocomplete(g, {});
b("#wuSearch").val("")
} else {
window.location = "/cgi-bin/findweather/getForecast?query=" + g
}
}
}
if (!j) {
e.showGeolocateFinished(d.error_generic, false)
}
}, function(f) {
if (f.code == f.PERMISSION_DENIED) {
e.showGeolocateFinished(d.error_permissions, false)
} else {
e.showGeolocateFinished(d.error_generic, false)
}
})
} else {
this.showGeolocateFinished(d.error_generic, false)
}
return false
},
showGeolocateFinished: function(d, e) {
var g = this;
var c = e ? "found" : "not-found";
var f = e ? 1000 : 5000;
this.$alertBar.addClass(c).text(d);
setTimeout(function() {
g.$alertBar.removeClass("active")
}, f)
}
});
function a() {
var f = b("#feature-menu")
, c = f.children(".menu-list")
, d = b("<ul>", {
"class": "menu-list primary-menu"
})
, e = f.find("> ul > li");
e.each(function() {
var i = b(this);
if (i.is(":has(> ul.menu-list)")) {
var h = b("<li>").append(i.children("label"))
, g = b("<div>", {
"class": "menu-wrapper"
})
, j = i.children("ul.menu-list");
d.append(h);
h.data("menu", g.get(0));
g.append(j);
f.append(g)
} else {
i.addClass("more-menu-only");
d.append(i)
}
});
f.append(d);
c.remove();
f.addClass("visible")
}
})(jQuery);
$(function() {
var a = $("#global-header")[0];
if (a) {
new wui.Views.Header({
el: a
})
}
});
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Models.Weather = Backbone.NestedModel.extend({
defaults: function() {
return {}
},
fetchMore: function(d) {
var c = this.url(d);
return this.fetch({
url: c
})
},
getDays: function() {
var c = [];
var d;
d = this.get("history.days");
if (d && d.length) {
c = c.concat(d)
}
d = this.get("forecast.days");
if (d && d.length) {
c = c.concat(d)
}
return c
},
getStationId: function() {
var c = this.get("current_observation.station.id");
return c
},
getUpdatedTimeAgo: function() {
var e = "";
var f = this.get("current_observation.updated");
if (_.isUndefined(f)) {
f = this.get("current_observation.date.epoch")
}
if (_.isUndefined(f)) {
var c = this.get("labels.not_available.label") || "--";
e = c
} else {
var g = new Date(parseFloat(f) * 1000);
e = a.getTimeAgo(g, {
numFields: 1
})
}
return e
},
initialize: function(c, d) {
this.options = b.extend(true, {
autoFetch: false
}, d);
if (this.options.autoFetch) {
this.fetch()
}
this.on("change:current_observation", this.onChangeCurrentObservation, this)
},
isOffline: function() {
var f = this.get("current_observation.updated");
var e = (new Date()).getTime() / 1000;
var d = true;
var c = 10800;
if (_.isUndefined(f)) {
f = this.get("current_observation.date.epoch")
}
if (!_.isUndefined(f) && e - f <= c) {
d = false
}
return d
},
lookupWindString: function(c) {
if (c > 360) {
c = c % 360
}
if (c >= 0 && c < 11.25) {
return "N"
}
if (c >= 11.25 && c < 33.75) {
return "NNE"
}
if (c >= 33.75 && c < 67.5) {
return "NE"
}
if (c >= 67.5 && c < 78.75) {
return "ENE"
}
if (c >= 78.75 && c < 101.25) {
return "E"
}
if (c >= 101.25 && c < 123.75) {
return "ESE"
}
if (c >= 123.75 && c < 146.25) {
return "SE"
}
if (c >= 146.25 && c < 168.75) {
return "SSE"
}
if (c >= 168.75 && c < 191.25) {
return "S"
}
if (c >= 191.25 && c < 213.75) {
return "SSW"
}
if (c >= 213.75 && c < 236.25) {
return "SW"
}
if (c >= 236.25 && c < 258.75) {
return "WSW"
}
if (c >= 258.75 && c < 281.25) {
return "W"
}
if (c >= 281.25 && c < 303.75) {
return "WNW"
}
if (c >= 303.75 && c < 326.25) {
return "NW"
}
if (c >= 326.25 && c < 348.75) {
return "NNW"
}
if (c >= 348.75) {
return "N"
}
return "-"
},
mergeRapidfire: function(g) {
if (g) {
var e = this.get("current_observation");
var d = a.filterObject(g, function(h, i) {
return i !== null
});
if (_.has(d, "wind_dir_degrees")) {
var c = this.lookupWindString(d.wind_dir_degrees);
d.wind_dir = c
}
var f = b.extend(true, {}, e, d);
this.set({
current_observation: f
})
}
this.trigger("rapidfire", this, g)
},
onChangeCurrentObservation: function() {
var d = this.getStationId();
var c = this.previous("current_observation");
if (c) {
if (c.station.id !== d) {
this.trigger("currentStationChange", d, c.station.id)
}
}
},
sync: function(e, d, c) {
if (e == "read") {
c.cache = true
}
return Backbone.sync.call(this, e, d, c)
},
url: function(d) {
d = b.extend({}, this.options, d);
var c = "//api-ak-aws.wunderground.com/api/" + this.options.apikey;
if (d.features) {
c += "/" + d.features.join("/");
if ("history"in d.features) {
c.replace("/history/", "/history_" + wui.date.strftime("%Y%m%d") + "/")
}
}
if (d.lang) {
c += "/lang:" + d.lang
}
if (d.units) {
c += "/units:" + d.units
}
if (d.version) {
c += "/v:" + d.version
}
if (wui.arrayContains(d.bestfct, [0, false])) {
c += "/bestfct:0"
}
if (wui.arrayContains(d.bestfct, [1, true])) {
c += "/bestfct:1"
}
c += "/q/" + d.query + ".json";
c += "?ttl=300";
if (d.fodqa) {
c += "&qa=1&fod=1"
}
if (d.selected_pws) {
c += "&sp=" + d.selected_pws
}
return c
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Models.Location = Backbone.NestedModel.extend({
defaults: function() {
return {
lat: 0,
lon: 0,
name: "",
type: "",
zmw: ""
}
},
idAttribute: "zmw"
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Models.PlotGroup = Backbone.NestedModel.extend({
defaults: function() {
return {
astronomy: {
markings: {
show: false,
dayColor: "transparent",
nightColor: "#f4f4f4",
yaxis: {}
}
},
bufferLeft: 0,
bufferRight: 0,
classNames: {
editMode: "editMode",
hasHeader: "has-header",
hasPrecip: "has-precip",
header: "plot-header",
hidden: "hidden",
legend: "plot-legend",
needle: "plot-needle",
needleLabelBottom: "needle-label-bottom",
needleLabelTop: "needle-label-top",
needleLine: "plot-needle-line",
needleNow: "plot-needle-now",
numberedItem: "n",
lastPlot: "plot-last",
plot: "plot",
plots: "plots",
selected: "selected"
},
date_min: "auto",
date_max: "auto",
dayMaxWidth: 82,
editMode: false,
fitDuration: 250,
iconset: "v3",
legends: false,
mode: "forecast",
needleDateFormat: null,
needleDateLabels: false,
needleNow: false,
panDuration: 1000,
selectors: {
checkboxes: null,
editDone: null,
editMode: null,
variablesMenu: null
},
tickZoomPreset: "",
zoomable: false,
zoomDuration: 1000,
flot: {
grid: {
autoHighlight: false,
clickable: false,
hoverable: false,
labelMargin: 0,
minBorderMargin: 0,
mouseActiveRadius: 5
},
legend: {
show: false
},
needle: {
show: true
},
series: {
bars: {
barWidth: 60 * 60 * 1000
},
shadowSize: 0
},
touch: {
autoHeight: false,
autoWidth: false,
childrenSelector: "canvas, .flot-header",
pan: "x",
scale: "x"
},
xaxis: {
labelHeight: 0.1,
tickFormatter: function(c, b) {
return ""
}
},
yaxis: {
alignTicksWithAxis: 1,
labelHeight: 1,
labelWidth: 30,
tickDecimals: 0,
tickFormatter: function(c, b) {
return c.toFixed(b.tickDecimals) + (b.options.tickUnits || "")
}
}
},
plots: []
}
},
initialize: function(b, d) {
var e = _.result(this, "defaults");
var c = a.extend(true, {}, e, b);
this.set(c, d);
this.changed = {}
}
})
})(jQuery);
(function(c) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
var b = wui.bootstrapped.prefs;
wui.Models.Precip = Backbone.NestedModel.extend({
events: {},
defaults: function() {
return {}
},
fetch: function(d) {
var e = this;
return Backbone.Model.prototype.fetch.apply(this, d).fail(function() {
e.set("success", false);
e.set("graphMessage", wui.bootstrapped.precip.errors.graph);
e.set("tableMessage", wui.bootstrapped.precip.errors.table);
e.set("precipUpdated", new Date().getTime())
})
},
fetchStatement: function() {
this.updateURL();
var d = this.urlBase + "/forecast/wwir.json" + this.urlQueryString;
var e = this;
c.ajax(d).done(function(g) {
var f = g.forecast;
if (f) {
e.set("eventType", e.eventTypes[f.overall_type]);
e.set("statementTerse", f.terse_phrase);
e.set("statement", f.phrase);
e.set("lastUpdated", new Date());
e.set("statementSuccess", true)
}
}).fail(function() {
e.set("eventType", "noprecip");
e.set("statementSuccess", false);
e.set("statement", wui.bootstrapped.precip.errors.statement)
})
},
setEndTime: function() {
this.endTime = this.startTime + 3600 * 6
},
getTimezone: function(e) {
if (this.timezone) {
return this.timezone
}
var d = e.length;
return this.timezone = d ? e.substring(d - 5, d - 2) : ""
},
initialize: function(d, e) {
var f = this;
this.options = c.extend(true, {
autoFetch: false
}, e);
this.apiKey = this.options.apikey;
this.lang = this.options.lang || "en";
this.units = this.options.units === "metric" ? "m" : "e";
this.lat = this.options.lat;
this.lon = this.options.lon;
this.version = this.options.version || "v1";
if (this.lang && this.lang.indexOf("-") !== -1) {
this.lang = this.lang.split("-")[0]
}
if (this.lang && this.lang.indexOf("_") !== -1) {
this.lang = this.lang.split("_")[0]
}
this.eventTypes = ["noprecip", "rain", "snow", "mix", "thunder"];
this.intensityLabels = ["", "Light", "Moderate", "Heavy"];
this.typeLabels = ["No Precipitation", "Rain", "Snow", "Mix", "Rain"];
this.typeLabelMap = {
noprecip: "No Precipitation",
rain: "Rain",
snow: "Snow",
mix: "Mix",
thunder: "Rain"
};
this.intensityHeights = [0, 49, 99, 150];
this.yValues = ["", 101, 51, 0];
this.timezone = "";
this.updateURL();
if (this.options.autoFetch) {
this.fetch().done(function(g) {
f.set("precipUpdated", new Date().getTime())
})
}
if (this.options.fetchStatement) {
this.fetchStatement()
}
},
updateURL: function() {
var d = "//api.weather.com/" + this.version + "/geocode";
var e = new Date().getTime();
if (this.lat) {
d += "/" + this.lat + e
}
if (this.lon) {
d += "/" + this.lon + e
}
this.urlBase = d;
this.urlQueryString = "?apiKey=" + this.apiKey + "&units=" + this.units + "&language=" + this.lang
},
getIntensity: function(j, m, l) {
var g = 0;
if (m !== "noprecip") {
var j = l === "m" ? (m === "rain" ? j / 25.4 : j / 2.54) : j;
var d = [0, 0.1, 0.4];
var e = [0, 1, 2];
var f = m === "rain" ? d : e;
for (var h = 0, k = f.length; h < k; h++) {
if (j >= f[h]) {
g = h
}
}
g++
}
return g
},
parse: function(d) {
return wui.bootstrapped.precip && wui.bootstrapped.precip.chunky ? this.parsePrecip(d) : this.parseFifteen(d)
},
parseFifteen: function(j) {
if (typeof j.forecasts === "undefined" || !j.forecasts.length) {
return false
}
var m = this;
var h = 900;
var d = 3600 * 6;
var r = [];
var q = 0;
var f = 0;
var e = false;
var p = false;
var o = j.metadata.units;
var n = j.forecasts[0];
var l = m.getTimezone(n.fcst_valid_local);
var i = j.metadata.transaction_id;
var g = b.BrowserCode || b.LangCode;
var k = [];
this.startTime = n.fcst_valid;
this.setEndTime();
_.each(j.forecasts, function(x, B) {
var w = g.indexOf("en") >= 0 ? "%l:%M %P" : "%H:%M";
var s = x.fcst_valid;
var z = s + h;
var E = x.precip_type === "precip" ? "mix" : x.precip_type;
var C = E === "rain" || E == "mix" ? x.precip_rate : x.snow_rate;
if (x.pop < 30 && C === 0) {
E = "noprecip"
}
var y = C * 0.25;
var t = m.getIntensity(C, E, o);
var A = k.length;
var v = 15;
var u = {
epoch: s,
tz_offset_hours: l
};
var D = {
epoch: z,
tz_offset_hours: l
};
if (!A || k[A - 1].type !== E || k[A - 1].intensity !== t) {
k.push({
type: E,
intensity: t,
timeStart: wui.date.strftime(w, u),
timeEnd: wui.date.strftime(w, D),
amount: y,
duration: 15,
height: m.intensityHeights[t],
y: m.yValues[t],
intensityLabel: m.intensityLabels[t],
typeLabel: m.typeLabelMap[E],
hasThunder: false
})
} else {
var F = k[A - 1];
F.duration += 15;
F.timeEnd = wui.date.strftime(w, D);
F.amount += y
}
if (E === "rain" || E === "mix") {
e = true;
q += y
} else {
if (E === "snow") {
p = true;
f += y
}
}
});
return {
success: true,
totals: {
liquid: q,
snow: f
},
hasLiquid: e,
hasSnow: p,
events: k
}
},
parsePrecip: function(g) {
if (typeof g.forecasts === "undefined" || !g.forecasts.length) {
return false
}
var j = this;
var f = 900;
var h = 32;
var l = f / h;
var o = [];
var n = 0;
var e = 0;
var d = false;
var m = false;
var k = g.forecasts[0];
var i = j.getTimezone(k.event_start_local);
_.each(g.forecasts, function(u, x) {
if (x === 0) {
j.startTime = u.event_start;
j.setEndTime()
}
var q = {};
var z = u.event_start < j.startTime ? j.startTime : u.event_start;
var w = u.event_end > j.endTime ? j.endTime : u.event_end;
var p = u.event_type;
var r = u.intensity;
var v = p === 2 ? u.snow_qpf : u.qpf;
var t = {
epoch: z,
tz_offset_hours: i
};
var A = {
epoch: w,
tz_offset_hours: i
};
var s = "%l:%M %P";
var y = j.eventTypes[p];
if (z >= j.endTime) {
return false
}
if (p) {
q = {
width: (w - z) / l - 1,
x: (z - j.startTime) / l + 1 + h,
height: j.intensityHeights[r],
y: j.yValues[r]
}
}
if (y === "rain" || y === "mix" || y === "thunder") {
d = true;
n += v
} else {
if (y === "snow") {
m = true;
e += v
}
}
y = y === "thunder" ? "rain" : y;
c.extend(q, {
duration: (w - z) / 60,
type: y,
amount: v,
timeStart: wui.date.strftime(s, t),
timeEnd: wui.date.strftime(s, A),
intensityLabel: j.intensityLabels[r],
typeLabel: j.typeLabels[p],
hasThunder: p === 4
});
o.push(q)
});
return {
totals: {
liquid: n,
snow: e
},
hasLiquid: d,
hasSnow: m,
events: o
}
},
url: function(e) {
var f = wui.bootstrapped.precip && wui.bootstrapped.precip.chunky ? "precipitation" : "fifteenminute";
this.updateURL();
var d = this.urlBase + "/forecast/" + f + ".json" + this.urlQueryString;
return d
}
})
})(jQuery);
(function(c) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
var b = wui.bootstrapped.prefs;
wui.Models.Pollen = Backbone.NestedModel.extend({
events: {},
defaults: function() {
return {}
},
fetch: function(d) {
var e = this;
return Backbone.Model.prototype.fetch.apply(this, d)
},
parse: function(e) {
var g = {};
if (e && e.length) {
var d = e[0];
var j = 0;
var f = "";
g.grass = d.vt1pollenforecast.grass;
g.tree = d.vt1pollenforecast.tree;
g.weed = d.vt1pollenforecast.weed;
for (var i in g) {
if (g[i]) {
var h = g[i][0];
if (h !== null && h > j) {
j = h;
f = i
}
}
}
g.highestLevel = j;
g.pollenType = f
}
return g
},
initialize: function(d, e) {
var f = this;
this.lat = e.lat;
this.lon = e.lon;
this.apiKey = e.apiKey;
this.fetch().done(function(g) {
f.set("success", true)
})
},
url: function(e) {
var d = "//api.weather.com/v2/turbo/vt1pollenforecast?geocodes=" + this.lat + "," + this.lon + "&format=json&language=en&apiKey=" + this.apiKey;
return d
}
})
})(jQuery);
(function(c) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
var b = wui.bootstrapped.prefs;
wui.Models.WeatherFiveDay = Backbone.NestedModel.extend({
events: {},
defaults: function() {
return {}
},
fetch: function(d) {
var e = this;
return Backbone.Model.prototype.fetch.apply(this, d)
},
parse: function(d) {
return d
},
initialize: function(d, e) {
var f = this;
this.lat = e.lat;
this.lon = e.lon;
this.apiKey = e.apiKey;
this.fetch().done(function(g) {
f.set("success", true)
})
},
url: function(e) {
var d = "//api.weather.com/v1/geocode/" + this.lat + "/" + this.lon + "/forecast/daily/5day.json?language=en-US&units=e&apiKey=" + this.apiKey;
return d
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Models.Station = Backbone.NestedModel.extend({
defaults: function() {
return {
id: "",
lat: 0,
lon: 0,
name: "",
type: "",
}
}
})
})(jQuery);
(function(c) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
var b = {
1: "85x64",
2: "85x64",
3: "85x64",
4: "85x64",
5: "155x155",
6: "155x114",
7: "320x260",
8: "320x180",
9: "485x273",
10: "650x366",
11: "815x458",
12: "980x551",
15: "640x598"
};
wui.Models.Video = Backbone.NestedModel.extend({
defaults: function() {
return {
clipid: "",
title: "",
description: "",
thumb: "",
video_source: ""
}
},
idAttribute: "clipid",
getFormattedTime: function(g) {
var e;
var d;
var f;
var h;
g = g ? String(g) : "0";
if (g.indexOf(":") > -1) {
e = g.split(":")
} else {
return g
}
if (e.length === 2) {
d = 0;
f = parseInt(e[0]) || 0;
h = parseInt(e[1]) || 0
} else {
d = parseInt(e[0]) || 0;
f = parseInt(e[1]) || 0;
h = parseInt(e[2]) || 0
}
if (d && d !== 0) {
d = d * 3600
}
if (f && f !== 0) {
f = f * 60
}
h = Math.round(d + f + h);
return h
},
getMimeType: function(d) {
var f = (/[.]/.exec(d)) ? /[^.]+$/.exec(d) : [];
var e;
switch (f[0]) {
case "mp4":
case "mov":
e = "video/mp4";
break;
case "mpeg":
e = "video/mpeg";
break;
case "mp4a":
e = "audio/mp4";
break;
case "flv":
e = "video/x-flv";
break;
case "m3u8":
e = "application/x-mpegURL";
break;
case "ts":
e = "video/MP2T";
break;
case "3gp":
e = "video/3gpp";
break;
case "avi":
e = "video/x-msvideo";
break;
case "wmv":
e = "video/x-ms-wmv";
break;
default:
e = "";
break
}
return e
},
parse: function(f, g) {
var j = f;
var h = 9;
j.clipid = j.source_guid;
if (j.variants && j.variants.legacy) {
j.video_source = c.trim(j.variants.legacy)
} else {
j.video_source = j.mezzanine_url
}
if (!j.video_source && j.variants && j.variants.hds) {
j.video_source = j.variants.hds
}
var i = ("lastmodifieddate"in j) ? j.lastmodifieddate : "";
if (!("lastModDate"in j)) {
j.lastModDate = i
}
if (!j.lastModDate) {
console.log("WARNING: Clip does not have last lastModDate")
}
if (!("mimeType"in j)) {
j.mimeType = this.getMimeType(j.video_source)
}
j.duration = ("duration"in j) ? this.getFormattedTime(j.duration) : "";
var d = null;
if (j.variants) {
j.mediaURL = j.variants[h]
}
var e = j;
return e
},
setSelected: function(d) {
d = !!d;
if (d == this.selected) {
return
}
this.selected = d;
this.trigger("selected", this, d)
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Models.Wundermap = Backbone.Model.extend({
defaults: {
currentLatLng: {},
country: "",
enticement: null,
lat: 0,
lon: 0,
layers: [],
hasRadar: false,
gMapType: "",
gMapUnits: "",
zoom: 7,
mapTypeId: "",
mapTypeControl: false,
maxZoom: 16,
minZoom: 7
},
initialize: function(c) {
this.set("lat", c.lat);
this.set("lon", c.lon);
this.set("country", c.country);
this.set("gMapType", c.gMapType);
this.set("gMapUnits", c.gMapUnits);
this.set("mapTypeControl", false);
var b = {
zoom: this.get("zoom"),
minZoom: this.get("minZoom"),
maxZoom: this.get("maxZoom"),
mapTypeControl: false
};
a.extend(b, c);
this.set("mapOptions", b)
},
checkCountryHasRadar: function(c) {
var f = this.toTitleCase(c);
var b = ["Ireland", "United Kingdom", "France", "Spain", "Portugal", "Belgium", "Netherlands", "Germany", "Switzerland", "Italy", "Austria", "Czech Republic", "Poland", "Denmark"];
var d = ["Us", "Canada", "Australia"];
var e = d.concat(b);
return ( a.inArray(f, e) != -1)
},
toTitleCase: function(b) {
return b.replace(/\w\S*/g, function(c) {
return c.charAt(0).toUpperCase() + c.substr(1).toLowerCase()
})
}
})
})(jQuery);
(function(c) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
var b = wui.bootstrapped.prefs;
wui.Models.AlertsList = Backbone.NestedModel.extend({
events: {},
defaults: function() {
return {}
},
fetch: function(d) {
var e = this;
return Backbone.Model.prototype.fetch.apply(this, d)
},
parse: function(k) {
var o = {};
var u = [];
var r = [];
var p = false;
var t = false;
if (k && k.alerts) {
var q = k.alerts;
var m = wui.bootstrapped.citypage.city;
var e = wui.bootstrapped.citypage.state;
var g = wui.bootstrapped.citypage.country;
var f = wui.bootstrapped.citypage.zip;
if (q.length && m && e) {
var d = m + ", " + e;
if (f === "00000") {
d = m + ", " + g
}
for (var n = 0; n < q.length; n++) {
var s = q[n].city;
var l = s.cityname;
if (s.zip === "00000") {
l += ", " + s.country
}
if (s.altemail.alerts.periods.email === "1") {
u.push(l);
if (d === l) {
p = true
}
}
var j = false;
for (var h in s.altemail.alerts) {
if (h !== "periods" && s.altemail.alerts.hasOwnProperty(h)) {
if (s.altemail.alerts[h].email === "1") {
if (!j) {
r.push(l);
j = true
}
if (d === s.cityname) {
t = true
}
}
}
}
}
}
}
return {
forecast: {
activeCity: p,
cities: u
},
severe: {
activeCity: t,
cities: r
}
}
},
initialize: function() {
var d = this;
this.fetch().done(function(e) {
d.set("success", true)
})
},
url: function(e) {
var d = "/weather-alerts/list-cities";
return d
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Collections.Weather = Backbone.Collection.extend({
model: wui.Models.Weather,
getStationIds: function() {
var c = this.pluck("current_observation.station.id");
c = _.uniq(c);
return c
},
initialize: function() {
this._rapidfire = {
interval: 1000 * 60 * 15,
started: false,
timer: null
};
if (wui.bootstrapped && wui.bootstrapped.prefs) {
if (_.has(wui.bootstrapped.prefs, "rapidfire")) {
this._rapidfire.interval = parseInt(wui.bootstrapped.prefs.rapidfire, 0) * 1000
}
}
},
parseRapidfire: function(c, d) {
var e = c.stations;
this.each(function(h) {
var g = h.getStationId();
var f = e[g];
h.mergeRapidfire(f)
})
},
rapidfire: function(d) {
if (this.size() > 0) {
var e = b.extend(true, {}, this._rapidfire, d);
var c = this.urlRapidfire(e);
var f = b.ajax({
context: this,
dataType: "jsonp",
url: c,
success: function(g) {
this.parseRapidfire(g);
if (this._rapidfire.started) {
this.rapidfireDelay()
}
}
});
return f
} else {
if (this._rapidfire.started) {
this.rapidfireDelay()
}
return false
}
},
rapidfireDelay: function() {
if (this._rapidfire.interval) {
var c = _.bind(this.rapidfire, this);
this._rapidfire.timer = setTimeout(c, this._rapidfire.interval)
}
},
rapidfireSetOptions: function(c) {
this._rapidfire = b.extend(true, this._rapidfire, c)
},
rapidfireStart: function(c) {
this.rapidfireStop();
this.rapidfireSetOptions(c);
this._rapidfire.started = true;
this.rapidfire()
},
rapidfireStop: function() {
this._rapidfire.started = false;
if (this._rapidfire.timer) {
clearTimeout(this._rapidfire.timer)
}
this._rapidfire.timer = null
},
urlRapidfire: function(d) {
d = b.extend(true, {
format: "json",
maxage: 10,
stations: null,
units: "english",
v: "2.0"
}, d);
if (!d.stations) {
d.stations = this.getStationIds()
}
var c = "//stationdata.wunderground.com/cgi-bin/stationlookup?";
c += b.param({
format: d.format,
maxage: d.maxage,
station: d.stations.join(","),
units: d.units,
v: d.v
});
return c
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Collections.Location = Backbone.Collection.extend({
model: wui.Models.Location,
initialize: function() {},
getZMWs: function() {
var c = this.pluck("zmw");
c = _.uniq(c);
return c
},
hasZMW: function(d) {
var c = this.findWhere({
zmw: d
});
return !!c
},
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Collections.Favorites = wui.Collections.Location.extend({
initialize: function() {
var c = this;
this.listenTo(this, "sort", this.reorderFavorites)
},
addFavorite: function(e, d) {
var c = this;
var f = this._requestAdd(e);
f.done(function(i, k) {
var j = "Error";
var g = i.RESULTS || i;
if (g.indexOf(j.toLowerCase()) >= 0) {
c._requestError(g)
} else {
if (i.location) {
c.add(i.location)
} else {
var h = "Error: unknown favorite location";
c._requestError(h)
}
}
});
return f
},
delFavorite: function(e, d) {
var c = this;
var f = this._requestDel(e);
f.done(function(i, k) {
var j = "Error";
var h = i.RESULTS || i;
if (h.indexOf(j.toLowerCase()) >= 0) {
c._requestError(h)
} else {
var g = c.get(e);
if (g) {
c.remove(g)
}
if (!c.length) {
b("#favorites-edit-list").html("<h3>You do not have any favorite cities loaded.</h3><p>If you had previously set your favorite cities, this may be due to your cookie settings being deleted, that you are using a different computer or are not signed in.</p>");
b("#favorites-edit-list").removeClass()
}
}
});
return f
},
favoritesCallback: function(h) {
var k = h.current_observation;
var p = h.response["location"];
if (k == undefined) {
return
}
var n = k.temperature
, f = p.canonical
, c = k.forecast_url
, g = k.condition
, m = k.station["latitude"]
, e = k.station["longitude"]
, d = k.icon
, o = p.zip + "." + p.magic + "." + p.wmo
, j = this.zmwParse(o);
var l;
if (p.zip == "00000") {
l = p.city + ", " + p.country
} else {
l = p.city + ", " + p.state
}
var q = h.alerts.length !== 0;
var i = q ? h.alerts[0].defcon : 0;
this.favoriteObjects[j] = {
name: l,
type: "favorite",
url: f,
lat: m,
lon: e,
zmw: j,
has_alerts: q,
condition: {
temperature: n,
icon: d,
condition: g,
severe: q,
defcon: i
},
current_observation: k
}
},
reorderFavorites: function() {
var c = this._requestReorder();
return c
},
toggleFavorite: function(d) {
var c = this.hasZMW(d);
if (c) {
return this.delFavorite(d)
} else {
return this.addFavorite(d)
}
},
_request: function(h, d) {
var c = this;
h = b.extend({
action: ""
}, h);
d = b.extend({
dataType: "jsonp",
jsonp: "jsonp",
type: "get",
error: function(j) {
var i = "Error: favorites ajax request failed";
c._requestError(i)
}
}, d);
var f = "";
if (document.domain.indexOf(".wunderground.com") < 0 || 1) {
f = "https://www.wunderground.com"
}
var e = f + "/favorites/submit.html";
d.data = h;
d.url = e;
var g = b.ajax(d);
return g
},
_requestAdd: function(c) {
var d = {
action: "addfavorite",
conditions: true,
place: c
};
return this._request(d)
},
_requestDel: function(c) {
var d = {
action: "delfavorite",
conditions: true,
place: c
};
return this._request(d)
},
_requestReorder: function() {
var e = this.getZMWs();
var c = "," + e.join(",");
var f = {
action: "reorderfavorites",
order: c
};
var d = {
dataType: "html",
type: "post"
};
return this._request(f, d)
},
_requestError: function(c) {
wui.log(c)
},
checkSelectedPWS: function(h) {
h = h.replace(/\./g, "");
var e = wui.bootstrapped.prefs.raw_string;
var d = e.indexOf(h);
var f = "";
if (d != -1) {
var g = e.indexOf(":", d);
var c = e.indexOf("|", g);
var f = e.substring(g + 1, c)
}
return f
},
loadAsync: function(h) {
var e = decodeURIComponent(h);
var d = e.split(",");
var g = [];
var c = [];
this.favoriteObjects = {};
this.citylist = h;
var f = this;
b.each(d, function(r, v) {
if (v == "") {
return
}
var p = f.zmwParse(v);
var j = p.replace(/\./g, "");
var w = f.checkSelectedPWS(p);
if (isNaN(j) || b.inArray(j, c) >= 0) {
j = g.length
}
c.push(j);
var x = wui.bootstrapped.prefs;
var q = "eb7a37c339cfd624";
var m = x.LangCode;
var s = x.Units;
var i = "//api-ak-aws";
var n = i + ".wunderground.com/api/" + q + "/conditions/alerts/v:2.0";
if (m) {
n += "/lang:" + m
}
if (s) {
n += "/units:" + s
}
var o = "/q/zmw:";
var u = ".json?ttl=300";
var k = n + o + p + u;
var l = new Date().getTime() / 1000;
var t = 300;
f.favoriteObjects[p] = {};
g.push(b.ajax({
url: k,
dataType: "jsonp",
timeout: 10000,
cache: true,
jsonpCallback: "favoritesCallback" + j,
success: function(y) {
f.favoritesCallback(y)
}
}))
});
b.when.apply(b, g).then(function() {
if (b.isEmptyObject(f.favoriteObjects)) {
return
}
var i = [];
for (var j in f.favoriteObjects) {
i.push(f.favoriteObjects[j])
}
f.add(i);
wui.favorites.stars.initialize()
})
},
zmwParse: function(h) {
var c = h.split(".");
var e, g, d;
if (c.length == 3) {
e = c[0];
g = c[1];
d = c[2]
} else {
if (c[0] == "00000") {
e = "00000";
g = "1";
d = c[1]
} else {
e = c[0];
g = c[1];
d = "99999"
}
}
var f = e + "." + g + "." + d;
return f
}
})
})(jQuery);
(function(e) {
if (!window.Backbone) {
return
}
var c = wui.backbone.utils;
var b = "_distance";
var a = "_latLng";
var g = "_title";
var f = 35;
var d = 10;
wui.Collections.Station = Backbone.Collection.extend({
model: wui.Models.Station,
initialize: function(i, h) {
this.options = {
bounds: null,
minlat: null,
minlon: null,
maxlat: null,
maxlon: null,
maxstations: f,
minstations: d,
center: null,
centerLat: null,
centerLon: null,
requiredVariables: [],
units: "english"
};
this.setOptions(h);
this.numFetches = 0;
this.listenTo(this, "sync", this.incrementFetches)
},
checkCenter: function() {
var h = this.options;
if (h.center === null) {
if (h.centerLat !== null && h.centerLon !== null) {
h.center = {
lat: wui.bootstrapped.citypage.lat,
lon: wui.bootstrapped.citypage.lon
}
}
}
},
comparator: b,
defaultStations: [],
fetchDefaultStations: function(i) {
i = e.extend({
distance: 19.53125,
maxstations: f,
minstations: d,
initialStations: false,
selectedStation: null
}, i);
this.checkCenter();
var h = this.options.center;
var j = i.distance * 1000;
this.setOptions({
isFetchDefaultStations: true,
maxstations: f
});
this.fetch({
initialStations: i.initialStations,
fetchDefaultStations: true,
selectedStation: i.selectedStation
})
},
getDefaultStations: function(h) {
h = h || {};
var j = this.defaultStations;
var i = h.bounds;
if (i) {
j = _.filter(j, function(k) {
var l = k[a];
return i.contains(l)
})
}
return j
},
getTitle: function(h) {
var i = [];
if (h.neighborhood) {
i.push(h.neighborhood)
}
if (h.city) {
i.push(h.city)
} else {
if (h.adm1) {
i.push(h.adm1)
}
}
if (h.state) {
i.push(h.state)
} else {
if (h.adm2 && h.adm2 != h.adm1) {
i.push(h.adm2)
}
}
var j = i.join(", ");
return j
},
incrementFetches: function() {
this.numFetches++
},
parse: function(i, j) {
var h = this.options.center;
if (h) {}
var m = i.stations;
var k = this.options.requiredVariables;
if (k && k.length) {
m = _.reject(m, function(n) {
var o = _.some(k, function(p) {
if (_.has(n, p)) {
return n[p] === null
} else {
return true
}
});
return o
})
}
_.each(m, function(n) {
if (h) {
var o = parseFloat(n.latitude);
var p = parseFloat(n.longitude)
}
n[g] = this.getTitle(n)
}, this);
var l = j.selectedStation;
if (l) {}
this.setOptions({
zoom: this.options.zoom
});
this.defaultStations = _.sortBy(m, b);
return m
},
setOptions: function(h) {
e.extend(this.options, h)
},
sync: function(k, j, i) {
if (k == "read") {
i.dataType = "jsonp"
}
var h = e.extend(this.options, i, i.data, {
data: null
});
return Backbone.sync.call(this, k, j, h)
},
url: function() {
var k = this.options;
var m = k.maxstations;
if (!m) {
m = ""
}
var o = k.minstations;
if (!o) {
o = ""
}
var i = k.minlat;
var j = k.minlon;
var l = k.centerLat;
var n = k.centerLon;
var h = "";
if (true) {
h = "//stationdata.wunderground.com/cgi-bin/stationdata?" + e.param({
centerLat: l,
centerLon: n,
format: "json",
maxage: 1800,
maxstations: f,
minstations: o,
height: 400,
width: 400,
iconsize: 2,
type: "ICAO,PWS",
units: k.units,
v: "2.0"
})
} else {
this.options.maxstations = 300;
h = "//stationdata.wunderground.com/cgi-bin/stationdata?" + e.param({
minlat: i,
minlon: j,
maxlat: maxlat,
maxlon: maxlon,
format: "json",
maxage: 1800,
maxstations: 300,
minstations: o,
height: 400,
width: 400,
iconsize: 2,
type: "ICAO,PWS",
units: k.units,
v: "2.0"
})
}
return h
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Collections.Video = Backbone.Collection.extend({
model: wui.Models.Video,
initialize: function(d, c) {
this.options = {
id: "",
selectedId: null,
selectedIndex: null
};
this.setOptions(c);
this.selected = null;
if (this.length) {
this.setInitialSelected()
} else {
this.once("sync", this.setInitialSelected, this)
}
},
parse: function(e, f) {
var h = matchMedia(Foundation.media_queries.small).matches;
var k = [];
if (e && e.body && e.body.length) {
var j = b.isArray(e.body[0].doc) ? e.body[0].doc : [e.body[0].doc];
if (typeof (j[0]) == "undefined") {
j = b.isArray(e.body) ? e.body : [e.body]
}
if (typeof (j[0].id) != "undefined") {
for (var g = 0, c = j.length; g < c; g++) {
var d = j[g].flags;
if ((d["Big Web"] && !h) || (d["Little Web"] && h)) {
k.push(j[g])
}
}
}
}
return k
},
select: function(c) {
c = c || null;
var e = (c) ? true : false;
if (c) {
if (c === this.selected) {
return
}
this.select(null);
if (c.setSelected) {
c.setSelected(e)
}
} else {
var d = this.selected;
if (!d) {
return
}
if (d.setSelected) {
d.setSelected(e)
}
}
this.selected = c
},
setInitialSelected: function() {
var e = null;
var d = this.options.selectedId;
var c = this.options.selectedIndex;
if (!e && d) {
e = this.get(d)
}
if (!e && _.isNumber(c) && c >= 0) {
e = this.at(c)
}
if (e) {
this.select(e)
}
},
setOptions: function(c) {
b.extend(this.options, c)
},
sync: function(e, d, c) {
if (e == "read") {
c.dataType = "jsonp";
c.jsonp = "jsonp"
}
return Backbone.sync.call(this, e, d, c)
},
url: function() {
var d = this.options;
var c = "";
var e = "";
if (this.options.type == "playlist") {
c = "//dsx.weather.com/cms/orderedlist/video/" + this.options.collid
} else {
e = d.isSingleVideo ? "/" + d.collid + "?" : "?q=type:$in(%27video%27);pcollid:$in(%27" + (d.collid || "wunderground/news") + "%27)&sort=-publishdate&pg=0,50&";
c = "//dsx.weather.com/cms/(assets)" + e + "api=7bb1c920-7027-4289-9c96-ae5e263980bc"
}
return c
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.Favorites = Backbone.View.extend({
events: {
"click .favorites-list-toggle": "onClickList"
},
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
this.collections = this.options.collections || {};
this.listenTo(this.model, "change:favorites.list.enabled", this.onListEnabledChange);
this.listenTo(this.model, "change:favorites.list.show", this.onListShowChange);
this.createViews();
this.render();
this.checkListToggle()
},
checkListToggle: function() {
var b = this.model.get("favorites.list.enabled");
this.$el.find(".favorites-list-toggle").toggle(b)
},
createViews: function() {
this.views = {};
this.views.favoritesBarView = new wui.Views.FavoritesBar({
model: this.model,
collections: {
favorites: this.collections.favorites,
recents: this.collections.recents,
popular: this.collections.popular,
},
el: this.$el.find(".favorites-bar")[0]
})
},
createListView: function() {
if (!this.views.favoritesListView) {
this.views.favoritesListView = new wui.Views.FavoritesList({
model: this.model,
collections: {
favorites: this.collections.favorites,
recents: this.collections.recents,
popular: this.collections.popular,
},
el: this.$el.find(".favorites-list")[0],
sortable: true,
render: true
})
}
},
onClickList: function(c) {
var b = this.model.get("favorites.list.show");
this.model.set("favorites.list.show", !b)
},
onListEnabledChange: function(c, b) {
this.checkListToggle()
},
onListShowChange: function(c, b) {
var d = this.model.get("classNames");
this.$el.find(".favorites-list-toggle").toggleClass(d.selected, b);
this.createListView()
},
render: function() {
_.each(this.views, function(b) {
b.render()
});
return this
}
});
wui.Views.FavoritesBar = Backbone.View.extend({
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
this.collections = this.options.collections || {};
this.template = _.template(a("script#favorites-bar-template").html());
this.templateCity = _.template(a("script#favorites-city-template").html());
if (a("script#favorites-alt-template").length) {
this.altTemplate = _.template(a("script#favorites-alt-template").html())
}
this.listenTo(this.model, "change:favorites.bar.show", this.onShowChange);
this.listenTo(this.collections.favorites, "add", this.render);
this.listenTo(this.collections.favorites, "remove", this.render);
this.listenTo(this.collections.favorites, "sort", this.render);
this.listenTo(this.collections.recents, "add", this.render);
this.listenTo(this.collections.recents, "remove", this.render);
this.listenTo(this.collections.popular, "add", this.render);
this.listenTo(this.collections.popular, "remove", this.render);
var d = _.bind(this.onResize, this);
var c = _.debounce(d, 500);
a(window).resize(c);
if (this.options.render) {
this.render()
}
},
checkListEnabled: function() {
var b = this.$el.width();
var d = this.$el.children("ul").width();
var c = (d > b);
this.model.set("favorites.list.enabled", c)
},
onResize: function(b) {
this.checkListEnabled()
},
onShowChange: function(c, b) {
this.toggle(b)
},
render: function() {
var b = [];
var e = [];
var g = [];
if (this.collections.favorites) {
b = this.collections.favorites.toJSON()
}
if (this.collections.recents) {
e = this.collections.recents.toJSON()
}
if (this.collections.popular) {
g = this.collections.popular.toJSON()
}
var d = {
favorites: b,
favCityList: this.collections.favorites.citylist,
recents: e,
popular: g,
templateCity: this.altTemplate ? this.altTemplate : this.templateCity
};
var f = this.template(d);
this.$el.html(f);
this.checkListEnabled();
var c = (b.length || e.length || g.length);
this.model.set("favorites.bar.show", c);
return this
},
toggle: function(b) {
this.$el.toggle(!!b)
}
});
wui.Views.FavoritesList = Backbone.View.extend({
events: {
"click .city-star": "onClickStar",
"click .city-home": "onClickHome"
},
initialize: function(d) {
this.options = d || {};
this.models = this.options.models || {};
this.collections = this.options.collections || {};
this.template = _.template(a("script#favorites-list-template").html());
this.templateCity = _.template(a("script#favorites-city-template").html());
this.listenTo(this.model, "change:favorites.list.enabled", this.onListEnabledChange);
this.listenTo(this.model, "change:favorites.list.show", this.onShowChange);
var b = this.collections.favorites;
if (b) {
this.listenTo(b, "add", this.onFavoritesChange);
this.listenTo(b, "remove", this.onFavoritesChange)
}
var c = this.collections.recents;
if (c) {
this.listenTo(c, "add", this.render);
this.listenTo(c, "remove", this.render)
}
var e = this.collections.popular;
if (e) {
this.listenTo(e, "add", this.render);
this.listenTo(e, "remove", this.render)
}
this._isSortable = false;
if (this.options.render) {
this.render()
}
},
createSortComparator: function(b) {
var c = function(e) {
var f = e.get("zmw");
var d = _.indexOf(b, f);
if (d < 0) {
d = b.length
}
return d
};
return c
},
onClickStar: function(e) {
e.preventDefault();
var b = a(e.target);
var c = this.el;
var f = b.closest("li", c);
var d = f.attr("data-zmw");
if (!d) {
return
}
this.toggleFav(d)
},
onClickHome: function(f) {
f.preventDefault();
var b = a(f.target);
var d = this.el;
var g = b.closest("li", d);
var e = g.attr("data-zmw");
var c = g.attr("data-cityName");
if (!e) {
return
}
if (!c) {
c = ""
}
this.toggleHome(e, b, c)
},
onFavoritesChange: function() {
this.render();
this.$el.sortable("refresh")
},
onListEnabledChange: function(c, b) {
var d = this.model.get("classNames");
if (!b) {
this.model.set("favorites.list.show", false);
this.$el.removeClass(d.open);
this.$el.hide()
}
if (b) {
this.$el.show()
}
},
onShowChange: function(c, b) {
this.toggle(b)
},
onSortUpdate: function(e, f) {
var d = this.$el.sortable("toArray", {
attribute: "data-zmw"
});
var b = this.collections.favorites;
var c = b.comparator;
b.comparator = this.createSortComparator(d);
b.sort();
b.comparator = c
},
render: function() {
var b = [];
var d = [];
var f = [];
if (this.collections.favorites) {
b = this.collections.favorites.toJSON()
}
if (this.collections.recents) {
d = this.collections.recents.toJSON()
}
if (this.collections.popular) {
f = this.collections.popular.toJSON()
}
var c = {
favorites: b,
recents: d,
popular: f,
templateCity: this.templateCity
};
var e = this.template(c);
this.$el.html(e);
if (!this._isSortable && this.options.sortable) {
this.setupSortable();
this._isSortable = true
}
return this
},
setupSortable: function() {
var b = {
axis: "y",
cancel: ".city-star",
containment: "parent",
distance: 2,
items: "> ul.list-favorites > li.is-fav",
tolerance: "pointer",
update: a.proxy(this.onSortUpdate, this)
};
this.$el.sortable(b)
},
toggle: function(b) {},
toggleFav: function(b) {
this.collections.favorites.toggleFavorite(b)
},
toggleHome: function(d, c, b) {
if (c.hasClass("active") == false) {
a(".city-home.active").removeClass("active")
}
wui.favorites.home.toggle(d, c, "active", "", b)
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.Location = Backbone.View.extend({
events: {
"click #flagstationbutton": "flagStation"
},
initialize: function(c) {
var d = this;
this.options = c || {};
this.models = this.options.models || {};
this.template = _.template(b("script#station-label-template").html());
this.listenTo(this.models.weather, "change:current_observation", this.render);
if (this.options.render && this.models.weather.attributes.response) {
this.render()
}
b("#report_box").on("closed.fndtn.dropdown", function() {
d.resetReportStation()
})
},
render: function() {
var d = "";
var c = {
labels: this.models.weather.attributes.labels,
weather: this.models.weather.attributes
};
d = this.template(c);
this.$el.find("#station-label").html(d);
if (this.models.weather.get("current_observation").source === "PWS") {
this.$el.find("#report-link").removeClass("hide")
} else {
this.$el.find("#report-link").addClass("hide")
}
return this
},
resetReportStation: function() {
b("#report-active").removeClass("hide");
b("#report-inactive").addClass("hide");
this.$el.find(".report-checkbox").prop("checked", false);
b("#report-error").text("").addClass("hide")
},
flagStation: function(h) {
var j = b(h.target);
var d = this.models.weather;
var c = d.get("current_observation");
var f = d.get("response");
var k = c.station;
var l = f.location;
var i = f.units;
var g = {
type: "wxstation",
stationid: k.id,
zip: l.zip,
magic: l.magic,
wmo: l.wmo,
badtemp: b("#badtemp").is(":checked"),
badpress: b("#badpress").is(":checked"),
badwind: b("#badwind").is(":checked"),
badfct: b("#badfct").is(":checked"),
badoff: b("#badoff").is(":checked")
};
g.temp_e = c.temperature;
g.press = c.pressure;
if (i === "metric") {
g.temp_e = g.temp_e * 1.8 + 32;
g.press /= 33.86
}
b("#report-error").addClass("hide");
if (!this.$el.find(".report-checkbox").is(":checked")) {
b("#report-error").text("Please select a reason below.").removeClass("hide")
} else {
j.prop("disabled", true).addClass("disabled");
b.ajax({
url: "/wuflag/flag.html",
data: g
}).complete(function(e, m) {
j.prop("disabled", false).removeClass("disabled")
}).done(function(e, m) {
b("#report-inactive").removeClass("hide");
b("#report-active").addClass("hide")
}).fail(function() {
b("#report-error").text("Our reporting system is currently down. Please try again later.").removeClass("hide")
})
}
return false
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.Current = Backbone.View.extend({
events: {
"click .cc3-toggle-hide": "onClickHideCC3",
"click .cc3-toggle-show": "onClickShowCC3"
},
initialize: function(c) {
this.options = c || {};
this.models = this.options.models || {};
var d = b("script#today_summary_template");
if (d[0]) {
this.templateTodaySummary = _.template(d.html())
}
this.listenTo(this.models.weather, "change:current_observation", this.updateVariables);
this.listenTo(this.models.weather, "change:forecast", this.updateWeatherQuickie);
this.listenTo(this.models.weather, "change:forecast", this.updateTodaySummary);
this.updateWeatherQuickie();
this.updateTodaySummary()
},
getPreviousValue: function(d) {
var f = null;
var c = this.models.weather.previousAttributes();
var e = c.current_observation;
if (e) {
f = e[d]
}
return f
},
getVariableElement: function(c, d) {
var f = this.model.get("classNames");
var e = this.$el.find("." + f.wxdata + "[data-variable]");
if (c) {
e = e.filter('[data-variable="' + c + '"]')
}
if (d) {
e = e.filter('[data-station="' + d + '"]')
}
return e
},
onClickHideCC3: function(c) {
c.preventDefault();
this.toggleCC3(false)
},
onClickShowCC3: function(c) {
c.preventDefault();
this.toggleCC3(true)
},
toggleCC3: function(c) {
var d = this.model.get("classNames");
this.$el.toggleClass(d.open, !!c)
},
updateMetadata: function() {
var d = this.models.weather.getStationId();
var c = ["station.elevation", "station.latitude", "station.longitude"];
var e = this.models.weather.attributes.labels;
_.each(c, function(f) {
var h = this.models.weather.get("current_observation." + f);
var i = this.getVariableElement(f, d);
var g = {};
if (f == "station.latitude") {
g.unit = "&deg;" + (h < 0 ? e.south.abbrev : e.north.abbrev);
h = Math.abs(h).toFixed(2)
}
if (f == "station.longitude") {
g.unit = "&deg;" + (h < 0 ? e.west.abbrev : e.east.abbrev);
h = Math.abs(h).toFixed(2)
}
a.updateVariable(i, f, h, g)
}, this)
},
updateStation: function(c, d) {
var e = this.getVariableElement(null, c).attr("data-station", d);
this.updateMetadata()
},
updateTodaySummary: function() {
if (!this.templateTodaySummary) {
return
}
var f = this.models.weather.get("forecast.days[0].summary.date");
var k = new Date(f.epoch * 1000);
var j = wui.date.increment(k, f.tz_offset_hours, "hour");
var c = wui.date.increment(j, -1, "day");
var g = this.models.weather.get("response");
var i = "";
var e = {
labels: this.models.weather.attributes.labels,
weather: this.models.weather.attributes,
yesterday_date: c
};
var h = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : "";
if (h && g.location) {
h += a.generateCityQuery({
zip: g.location.zip,
magic: g.location.magic,
wmo: g.location.wmo,
country: g.location.country_iso3166
})
}
e.cityUrl = h;
i = this.templateTodaySummary(e);
this.$el.find("#todaySummary").html(i)
},
updateVariableEffect: function(f, c, e) {
var d = f.attr("data-update-effect");
if (d == "wind-compass") {
this.updateWindCompass(f, e)
}
if (c == "icon_url") {
this.updateIconImg(f, e)
}
if (c == "wind_dir") {
this.updateWindDir(f, e)
}
},
initVariables: function() {
var g = this.models.weather;
var d = g.get("current_observation.station.id");
var f = false;
var e = g.attributes.current_observation;
var c = this;
_.each(e, function(i, h) {
var j = c.getVariableElement(h, d);
var k = c.model.get("classNames");
var j = c.$el.find("." + k.wxdata + "[data-variable]");
j = j.filter('[data-variable="' + h + '"]');
j.data("station", d);
if (j[0]) {
a.updateVariable(j, h, i, {});
c.updateVariableEffect(j, h, i)
}
});
this.updateStation(null, d)
},
updateVariables: function(j, i) {
var c = j.previousAttributes();
var g = c.current_observation;
var d = null;
var f = j.get("current_observation.station.id");
var h = false;
if (g) {
d = g.station.id;
h = (f !== d)
}
if (h) {
this.updateStation(d, f)
}
var e = this;
_.each(i, function(m, l) {
var k = e.getPreviousValue(l);
if (m !== k) {
var n = e.getVariableElement(l, f);
if (n[0]) {
a.updateVariable(n, l, m, {});
e.updateVariableEffect(n, l, m)
}
}
})
},
updateIconImg: function(d, c) {
d.attr({
alt: this.models.weather.get("current_observation.condition"),
src: c
})
},
updateWeatherQuickie: function() {
var d = "weather_quickie";
var i = this.models.weather;
var c = i.previousAttributes();
var e = null;
var f = {};
if (c.forecast) {
e = c.forecast.days[0].summary[d]
} else {
f.duration = 0
}
var h = i.get("forecast.days[0].summary[" + d + "]");
if (h !== e) {
var g = this.getVariableElement(d);
a.updateVariable(g, d, h, f)
}
},
updateWindCompass: function(d, c) {
a.rotate(d, c)
},
updateWindDir: function(d, c) {
var e = this.model.get("classNames");
var f = this.models.weather.get("current_observation.wind_dir_variable");
d.toggleClass(e.windDirVariable, !!f)
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.Forecast = Backbone.View.extend({
events: {},
initialize: function(b) {
this.options = b || {};
this.weather = this.options.weather;
this.models = this.options.models || {};
this.tabindex = this.options.tabindex || null;
if (this.options.render) {
this.initializeLater()
}
},
initializeLater: function() {
this.checkThunderstorm();
var b = this.$tabs = this.$el.find(".forecast-tabs");
var d;
if (this.tabindex !== null) {
d = parseInt(this.tabindex, 10)
} else {
d = 2;
var c = Foundation.media_queries.medium;
var e = matchMedia(c).matches;
if (e) {
d = 0
}
}
b.show();
b.tabs({
active: d,
activate: a.proxy(this.onTabsActivate, this)
});
this.createViews();
this.setupMetrics()
},
createViews: function() {
this.views = {};
var b = this.$tabs.tabs("option", "active");
this.createViewsByTabIndex(b)
},
checkThunderstorm: function() {
var f = this.weather.attributes.forecast.days;
var b = false;
for (var d = 0; d < 3; d++) {
if ((f[d].summary.condition == "Thunderstorm") || (f[d].summary.condition == "Chance of a Thunderstorm")) {
var b = true
}
}
var c = this.$el.find("#forcast-lightning-tab");
if (b && (c.length == 0)) {
var e = a("script#forecast-lightning-tab-template");
if (e) {
this.$el.find(".ui-tabs-nav").append(e.html())
}
} else {
if (c.length && !b) {
c.remove()
}
}
},
createViewsByTabIndex: function(b) {
if (b === 0 && !this.views.plotGroupView) {
this.views.plotGroupView = new wui.Views.PlotGroup({
model: this.model,
models: {
plotGroup: this.models.plotGroup,
weather: this.weather
},
render: true,
el: this.$el.find(".weather-graph").eq(0)[0]
});
this.listenTo(this.views.plotGroupView.status, "change:zoomedIn", function(d, c, e) {
this.trigger("forecast_graph_zoom", {
date: e.d,
initiator: e.eventInitiator,
zoomedIn: c
})
})
}
if (b === 1 && !this.views.tableVerticalView) {
this.views.tableVerticalView = new wui.Views.TableVertical({
model: this.model,
precip: this.models.precip,
weather: this.weather,
render: true,
el: a("#hourly-vertical")[0]
})
}
if (b === 1 && !this.views.tableHorizontalView) {
this.views.tableHorizontalView = new wui.Views.TableHorizontal({
model: this.model,
weather: this.weather,
render: true,
el: a("#hourly-horizontal")[0]
})
}
if (b === 2 && !this.views.extendedView) {
this.views.extendedView = new wui.Views.Extended({
model: this.model,
weather: this.weather,
render: true,
el: a("#extended")[0]
})
}
if (b === 3 && !this.views.contextView) {
this.views.contextView = new wui.Views.Context({
model: this.model,
weather: this.weather,
render: true,
el: a("#context-slideshow")[0]
})
}
this.$el.addClass("loaded");
this.$el.find(".content").removeClass("hidden-tab");
this.$el.find(".loader-screen").remove()
},
onTabsActivate: function(c, d) {
if (!this.views) {
return
}
var b = this.$tabs.tabs("option", "active");
this.createViewsByTabIndex(b);
if (b !== 3) {
wui.storage.setLocal("cityForecastTab", b)
}
this.trigger("forecast_tabs_activate", {
tabIndex: b,
jQueryObjects: d
})
},
setupMetrics: function() {
this.listenTo(this.models.plotGroup, "change:editMode", function(b, c) {
if (c) {
this.trigger("forecast_variables_menu_open")
} else {
this.trigger("forecast_variables_menu_close")
}
})
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.TableVertical = Backbone.View.extend({
events: {
"click .accordion > dd": "fixPosition"
},
initialize: function(c) {
this.options = c || {};
this.weather = this.options.weather;
this.precip = this.options.precip;
this.template = _.template(b("script#table-vertical-template").html());
this.listenTo(this.weather, "change:forecast", this.renderReady);
this.listenTo(this.precip, "change:statement", this.renderReady);
if (this.options.render && this.weather.attributes.forecast && this.precip.attributes.statement) {
this.render()
}
},
renderReady: function() {
if (this.weather.get("forecast") && this.precip.get("statement")) {
this.render()
}
},
render: function(g, j) {
var d = {
labels: this.weather.attributes.labels,
weather: this.weather.attributes,
precip: this.precip.attributes
};
var e = this.weather.get("response");
d.showPrecipDay = false;
d.showPrecipNight = false;
if (e && e.date) {
var c = e.date.hour;
if (c >= 1 && c < 19) {
d.showPrecipDay = true
}
if (c >= 13) {
d.showPrecipNight = true
}
}
var f = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : "";
if (f && e.location) {
f += a.generateCityQuery({
zip: e.location.zip,
magic: e.location.magic,
wmo: e.location.wmo,
country: e.location.country_iso3166
})
}
d.cityUrl = f;
var i = this.template(d);
var h = this.$el.find(".accordion").eq(0);
h.append(i);
this.checkStorm();
b(document).trigger("responsive_tables.new_table");
return this
},
checkStorm: function() {
if (wui.bootstrapped && wui.bootstrapped.citypage) {
var e = wui.bootstrapped.citypage.storm;
for (var d in e) {
var c = "dd#fctDay-" + d;
var f = "has-alert";
if (e[d].type === "blizzard") {
f += " has-blizzard"
}
if (b(c).length) {
b(c).addClass(f)
}
}
}
},
fixPosition: function(c) {
setTimeout(function() {
var d = b(c.target).offset().top;
var e = b(window).scrollTop();
if (e > d) {
b(window).scrollTop(d - 35)
}
}, 0)
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.TableVerticalSimple = Backbone.View.extend({
events: {
"click .accordion > dd": "fixPosition"
},
initialize: function(c) {
this.options = c || {};
this.weather = this.options.weather;
this.template = _.template(b("script#table-vertical-simple-template").html());
this.listenTo(this.weather, "change:forecast", this.renderReady);
if (this.options.render && this.weather.attributes.forecast) {
this.render()
}
},
renderReady: function() {
if (this.weather.get("forecast")) {
this.render()
}
},
render: function(e, h) {
var c = {
labels: this.weather.attributes.labels,
weather: this.weather.attributes
};
var d = this.weather.get("response");
var g = this.template(c);
var f = this.$el.find(".accordion").eq(0);
f.append(g);
this.checkStorm();
return this
},
checkStorm: function() {
if (wui.bootstrapped && wui.bootstrapped.citypage) {
var e = wui.bootstrapped.citypage.storm;
for (var d in e) {
var c = "dd#fctDay-" + d;
var f = "has-alert";
if (e[d].type === "blizzard") {
f += " has-blizzard"
}
if (b(c).length) {
b(c).addClass(f)
}
}
}
},
fixPosition: function(c) {
setTimeout(function() {
var d = b(c.target).offset().top;
var e = b(window).scrollTop();
if (e > d) {
b(window).scrollTop(d - 35)
}
}, 0)
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.TableHorizontal = Backbone.View.extend({
events: {
"click #fctDayLeftArrow": "leftScroll",
"click #fctDayRightArrow": "rightScroll"
},
initialize: function(c) {
this.options = c || {};
this.weather = this.options.weather;
this.dayMaxWidth = 115;
this.templateDay = _.template(b("script#table-horizontal-day-template").html());
this.templateDetails = _.template(b("script#table-horizontal-details-template").html());
this.listenTo(this.weather, "change:forecast", this.render);
this._tabsCreated = false;
if (this.options.render && this.weather.attributes.forecast) {
this.render()
}
},
checkArrows: function() {
var c = b("#fctDaySelect");
var e = b("#fctDayScroll");
var d = e.scrollLeft();
var g = e.width();
var f = c.width();
var h = b("#fctDayLeftArrow");
var i = b("#fctDayRightArrow");
if (g < f) {
if (d == 0) {
h.hide()
} else {
h.show()
}
if ((d + g) >= f - 1) {
i.hide()
} else {
i.show()
}
} else {
h.hide();
i.hide()
}
},
leftScroll: function() {
var d = b("#fctDayScroll");
var c = {
position: d.scrollLeft(),
width: d.width(),
amount: (d.width() / 2)
};
d.animate({
scrollLeft: (c.position - c.amount)
}, {
duration: "fast",
complete: function() {}
})
},
rightScroll: function() {
var d = b("#fctDayScroll");
var c = {
position: d.scrollLeft(),
width: d.width(),
amount: (d.width() / 2)
};
d.animate({
scrollLeft: (c.position + c.amount)
}, {
duration: "fast",
complete: function() {}
})
},
fitDays: function() {
var k = b("#hourly-horizontal");
var d = b("#fctDayScroll");
var j = b("#fctDaySelect");
var i = j.children("li");
var c = i.length;
var h = k.width();
var f = Math.floor(h / this.dayMaxWidth);
var l = d.height();
if (f >= c) {
f = c
}
var g = h / f;
var e = g * c;
j.width(e);
i.width(g);
if (d.height() > l) {
j.width(e + 1)
}
this.checkArrows()
},
render: function(i, g) {
var h = "";
var j = {
labels: this.weather.attributes.labels,
weather: this.weather.attributes
};
var e = this.weather.get("response");
var c = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : "";
j.showPrecipDay = false;
j.showPrecipNight = false;
if (e && e.date) {
var f = e.date.hour;
if (f >= 1 && f < 19) {
j.showPrecipDay = true
}
if (f >= 13) {
j.showPrecipNight = true
}
}
var c = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : "";
if (c && e.location) {
c += a.generateCityQuery({
zip: e.location.zip,
magic: e.location.magic,
wmo: e.location.wmo,
country: e.location.country_iso3166
})
}
j.cityUrl = c;
if (this._tabsCreated === true) {
this.$el.tabs("destroy")
}
this.$el.empty();
h = this.templateDay(j);
this.$el.append(h);
if (this.options.mode !== "simple") {
h = this.templateDetails(j);
this.$el.append(h);
this.$el.tabs();
this._tabsCreated = true
}
this.fitDays();
var k = _.bind(this.fitDays, this);
var d = _.debounce(k, 500);
b(window).resize(d);
var l = this;
b("#fctDayScroll").scroll(function() {
l.checkArrows()
});
l.checkStorm();
return this
},
checkStorm: function() {
if (wui.bootstrapped && wui.bootstrapped.citypage) {
var e = wui.bootstrapped.citypage.storm;
for (var d in e) {
var c = "li#fctDay-" + d;
var f = "has-alert";
if (e[d].type === "blizzard") {
f += " has-blizzard"
}
if (b(c).length) {
b(c).addClass(f)
}
}
}
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.Context = Backbone.View.extend({
events: {},
initialize: function(b) {
this.options = b || {};
this.weather = this.options.weather;
this.template = _.template(a("script#context-slideshow-template").html());
this.listenTo(this.weather, "change:forecast", this.render);
if (this.options.render && this.weather.attributes.forecast) {
this.render()
}
},
render: function(c, e) {
var b = {
labels: this.weather.attributes.labels,
weather: this.weather.attributes
};
var d = this.template(b);
this.$el.html(d);
this.$el.foundation();
return this
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.PlotGroup = Backbone.View.extend({
events: {
"click .plot-pan-left": "onPanLeft",
"click .plot-pan-right": "onPanRight",
"click .plot-zoom-hourly": "onZoomIn",
"click .plot-zoom-daily": "onZoomOut",
"click .plots": "onClick",
"mousedown .plots": "onMousedown",
"mouseup .plots": "onMouseup",
"mousemove .plots": "onMousemove",
"mouseleave .plots": "onMouseleave",
"touchstart .plots": "onTouchstart",
"touchmove .plots": "onTouchmove",
"touchend .plots": "onTouchend",
"touchcancel .plots": "onTouchcancel"
},
initialize: function(d) {
this.options = d || {};
this.models = this.options.models || {};
if (!this.models.plotGroup) {
console.error("missing required model `plotGroup` in this.models");
return
}
if (!this.models.weather) {
console.error("missing required model `weather` in this.models");
return
}
var f = this.$el.is(":visible");
this._initialized = true;
this._now = null;
this._numRenders = 0;
this._touchstart = {};
this._animateZoom = true;
this._presets = null;
this._presetsUnits = null;
if (Modernizr && Modernizr.touch) {
this._animateZoom = false
} else {
if (b(window).width() < 400) {
this._animateZoom = false
}
}
var c = this.checkDayPartsOnly();
this.status = new Backbone.NestedModel({
condition: null,
day: null,
dayPartsOnly: c,
dragging: false,
mousedown: false,
needle: {
locked: false,
timer: null,
x: 0,
y: 0
},
range: {},
timestamp: null,
touching: false,
transition: {
duration: 0
},
translation: {
x: 0,
y: 0,
z: 0
},
zoomedIn: (this.options.zoomedIn) ? this.options.zoomedIn : false
});
var e = this.models.plotGroup.get("classNames");
this.plots = [];
this.variablesMenu = null;
this.$needle = null;
this.$needleLabels = null;
this.$plots = this.$el.find("." + e.plots);
this.listenTo(this.models.weather, "change", this.onWeatherChange);
this.listenTo(this.status, "change:timestamp", this.onTimestampChange);
this.listenTo(this.status, "change:dragging", this.onDraggingChange);
this.listenTo(this.status, "change:zoomedIn", this.onZoomedInChange);
this.listenTo(this.status, "change:range", this.onRangeChange);
this.listenTo(this.status, "change:translation", this.onTranslateChange);
this.listenTo(this, "plotpan", this.onPlotPan);
if (this.options.render && this.models.weather.attributes.forecast) {
this.render()
}
},
initializeAtFirstRender: function() {
this.checkFlotAxesPresets({
presetKey: "tickUnitsPreset",
valueKey: "tickUnits",
fnName: "getUnitPreset"
});
this.checkFlotAxesPresets({
presetKey: "tickDecimalsPreset",
valueKey: "tickDecimals",
fnName: "getTickDecimalsPreset"
});
this.checkFlotAxesPresets({
presetKey: "ticksPreset",
valueKey: "ticks",
fnName: "getTicksPreset"
});
this.checkVariablesPresets();
this.createViews();
var d = _.some(this.plots, function(h) {
return h.isHeader()
});
var f = this.models.plotGroup.get("classNames");
this.$plots.toggleClass(f.hasHeader, d);
if (this.models.plotGroup.get("needleNow")) {
this.createNeedleNow()
}
this.createNeedle();
if (this.models.plotGroup.get("needleDateLabels")) {
this.createNeedleLabels()
}
this.setZoomButtons();
var g = _.bind(this.onResize, this);
var e = _.debounce(g, 500);
b(window).resize(e);
var c = _.bind(this.fitRangeY, this);
this.fitRangeYDebounced = _.debounce(c, 500);
b("body").on("mouseup", _.bind(this.onMouseup, this));
this.listenTo(this.models.plotGroup, "change:plots", this.onVariablesChange);
this.checkPrecip()
},
addPlotEvents: function(d) {
var e = this.plots[d];
var c = this;
e.$el.bind("plotpan", function(g, f, h) {
c.trigger("plotpan", d, h)
})
},
animateRangeX: function(h, m, g, l, f) {
var o = this;
var c = null;
if (!l) {
l = this.getFirstPlot()
}
var n = l.flot.getAxes().xaxis
, d = n.min
, k = n.max
, j = (window.performance && window.performance.now) ? window.performance.now() : null;
var i = 0;
this.setStatusRange({});
function e(u) {
if (j === null) {
j = u
}
i++;
var r = u - j;
var t = r / g;
var q = false;
if (t > 1) {
t = 1;
q = true
}
var s = d + t * (h - d);
var p = k - t * (k - m);
o.setRangeX(s, p);
o.setStatusRange({
complete: q,
elapsed: r,
fraction: t,
frame: i,
min: s,
max: p
});
if (q) {
if (f) {
f()
}
} else {
c = requestAnimationFrame(e)
}
}
c = requestAnimationFrame(e);
return c
},
checkDayPartsOnly: function() {
var d = false;
var g = this.getDays();
var e = g[0];
var f = e.observations;
var c = e.hours;
if (f && f.length) {
d = false
} else {
if (c && c.length) {
d = false
} else {
d = true
}
}
return d
},
checkFlotAxesPresets: function(c) {
c = b.extend({
axis: "y",
presetKey: "",
valueKey: "",
fnName: ""
}, c);
var p = {};
var f = c.axis + "axis";
var d = c.axis + "axes";
var h = this[c.fnName];
var m = this.models.plotGroup.get("plots");
for (var k = 0; k < m.length; k++) {
var l = m[k].flot;
if (l && l[f]) {
var q = l[f][c.presetKey];
if (q) {
var n = h.call(this, q);
if (n) {
var o = "plots[" + k + "].flot." + f + "." + c.valueKey;
this.models.plotGroup.set(o, n)
}
}
}
if (l && l[d]) {
for (var g = l[d].length - 1; g >= 0; g--) {
var e = l[d][g];
var q = e[c.presetKey];
if (q) {
var n = h.call(this, q);
if (n) {
var o = "plots[" + k + "].flot." + d + "[" + g + "]." + c.valueKey;
this.models.plotGroup.set(o, n)
}
}
}
}
}
},
checkInitialized: function() {
if (this._initialized !== true) {
this.initialize(this.options);
this.render()
}
},
checkNeedleDirection: function(e) {
var d = e.pageX;
for (var c = 0; c < this.plots.length; c++) {
var f = this.plots[c];
var g = f.flot.getOptions().needle;
if (g && g.show) {
f.flot.needle.checkDirection(d)
}
}
},
checkNeedleLabels: function() {
var c = this.$needle.offset().left + this.$needle.width() / 2;
var f = 0;
var e = this.fromScreenToFlotPos(c, f);
this.checkPosition({
lockNeedle: true,
pos: e
});
var d = this;
_.defer(function() {
b("#forecastGraph").css("opacity", "1");
b("#forecastGraph").css("filter", "");
b("#forecastGraph").css("background-color", "");
b("#plots").css("visibility", "visible");
d.delegateEvents();
d.checkStorm()
})
},
checkPanRange: function(c) {
var e = c;
var f = this._touchstart.x_min
, d = this._touchstart.x_max;
if (c > 0) {
if (f !== null && -c < f) {
e = -f
}
} else {
if (d !== null && -c > d) {
e = -d
}
}
return e
},
checkPosition: function(c) {
c = b.extend({
date: null,
event: null,
item: null,
lockNeedle: false,
plot: null,
pos: null
}, c);
var e = null
, f = null
, k = null;
var h = c.plot || this.getFirstPlot();
if (c.date) {
b.extend(true, c, {
pos: {
x: c.date.getTime()
}
})
}
if (h && c.pos) {
var g = this.getTimezone();
var i = h.flot.getAxes()
, j = i.xaxis
, l = Math.min(Math.max(c.pos.x, j.min), j.max);
e = this.getClosestConditionByTimestamp(l);
if (e) {
k = a.getTimestamp(e, g);
var d = this.checkTimestampInViewport(k);
if (d) {
f = this.getDayByCondition(e)
} else {
e = null;
k = null
}
}
}
this.status.set({
condition: e,
day: f,
"needle.locked": c.lockNeedle,
timestamp: k
})
},
checkPrecip: function() {
var f = this.models.plotGroup.get("classNames");
var e = this.models.plotGroup.get("plots");
var g = _.pluck(e, "variables");
g = [].concat.apply([], g);
var c = _.some(g, function(h) {
return ( h.show === true && h.hasPrecip === true)
});
var d = _.find(this.plots, function(h) {
return h.isHeader()
});
if (d) {
d.$el.toggleClass(f.hasPrecip, c)
}
return c
},
checkRangeOptions: function() {
var g = this.models.plotGroup.attributes;
var j = this.getTimezone();
var q, f;
var o = _.filter(this.getDays(), function(d) {
return d.hasOwnProperty("observations") || d.hasOwnProperty("hours")
})
, c = _.first(o)
, m = _.last(o);
if (g.date_min === "auto") {
var n = this.getHours(c);
var e = _.first(n) || c.summary;
var p = a.getTimestamp(e, j);
var l = new Date(p);
if (p && l) {
q = wui.date.roundDownTo(l, 1, "day")
}
} else {
if (g.date_min) {
q = g.date_min
}
}
if (g.date_max === "auto") {
var n = this.getHours(m);
var e = _.last(n) || m.summary;
var p = a.getTimestamp(e, j);
var l = new Date(p);
if (p && l) {
f = wui.date.roundUpTo(l, 1, "day")
}
} else {
if (g.date_max) {
f = g.date_max
}
}
for (var h = 0; h < this.plots.length; h++) {
var k = this.plots[h];
k.setPanRange(q, f)
}
if (q) {
this.models.plotGroup.set("date_min", q)
}
if (f) {
this.models.plotGroup.set("date_max", f)
}
},
checkTimestampInViewport: function(d) {
var c = this.getViewportDates();
if (d >= c.begin.getTime() && d <= c.end.getTime()) {
return true
} else {
return false
}
},
checkTouchmove: function(c) {
var f = false;
var e = this.models.plotGroup.get("bufferLeft");
var d = this.models.plotGroup.get("bufferRight");
if (e || d) {
if (e && c > 0 && c > e) {
f = true
}
if (d && c < 0 && -c > d) {
f = true
}
}
return f
},
checkVariablesPresets: function() {
var k = this.models.plotGroup.get("plots");
for (var g = 0; g < k.length; g++) {
var m = k[g].variables;
for (var e = 0; e < m.length; e++) {
var d = m[e];
if (_.has(d, "preset")) {
var l = "plots[" + g + "].variables[" + e + "]";
var f = this.getVariablePreset(d.preset);
if (f) {
var h = b.extend(true, {}, f, d);
this.models.plotGroup.set(l, h)
} else {
var c = "unknown preset `" + d.preset + "` in " + l;
console.error(c)
}
}
}
}
},
createNeedle: function() {
var d = this.models.plotGroup.get("classNames");
var c = b("<div />").addClass(d.needle).html('<div class="' + d.needleLine + '" />');
this.$plots.append(c);
this.$needle = c
},
createNeedleLabels: function() {
var h = this.models.plotGroup.get("classNames");
var c = this.$needle;
var g = this.getFirstPlot();
var e = g.createNeedleLabel();
var f = e.clone();
e.addClass(h.needleLabelTop).appendTo(c);
f.addClass(h.needleLabelBottom).appendTo(c);
var d = b().add(e).add(f);
this.$needleLabels = d
},
createNeedleNow: function() {
var g = this.models.plotGroup.get("classNames");
var c = b("<div />").addClass(g.needleNow);
var d = b("script#plotgroup-needle-now-template");
if (d[0]) {
var f = _.template(d.html());
var e = f({});
c.html(e)
}
this.$plots.append(c);
this.$needleNow = c
},
createViews: function() {
var k = this.models.plotGroup.get("classNames");
var h = this.$plots;
var g = this.models.plotGroup.get("selectors");
var c = this.models.plotGroup.get("plots");
for (var f = 0; f < c.length; f++) {
var d = "" + k.numberedItem + f;
var e = b("<div />").addClass(k.plot).addClass(d).appendTo(h);
if (f === c.length - 1) {
e.addClass(k.lastPlot)
}
var j = new wui.Views.Plot({
model: this.model,
models: {
plotGroup: this.models.plotGroup,
weather: this.models.weather
},
el: e[0],
status: this.status,
plotIndex: f
});
this.plots.push(j);
this.addPlotEvents(f)
}
this.variablesMenu = new wui.Views.PlotVariablesMenu({
model: this.model,
models: {
plotGroup: this.models.plotGroup,
weather: this.models.weather
},
el: b(g.variablesMenu)[0],
})
},
dragstart: function(k) {
k = b.extend(true, {
event: null,
currentTouch: null
}, k);
this.status.set("dragging", false);
var d = (k.currentTouch) ? k.currentTouch.pageX : k.event.pageX;
var c = (k.currentTouch) ? k.currentTouch.pageY : k.event.pageY;
var p = this.getFirstPlot()
, q = p.flot.getAxes()
, f = q.xaxis;
var n = p.getWidth();
var s = null
, t = null;
var r = this.models.plotGroup.get("bufferLeft")
, j = this.models.plotGroup.get("bufferRight");
var l = this.models.plotGroup.get("date_min")
, o = this.models.plotGroup.get("date_max");
var h = this.getViewportDates();
if (l) {
s = f.p2c(l.getTime()) - f.p2c(h.begin.getTime())
}
if (o) {
t = f.p2c(o.getTime()) - f.p2c(h.begin.getTime()) - n
}
var i = this.status.get("translation");
if (i.x) {
s -= i.x;
t -= i.x
}
var g = false;
if (k.currentTouch) {
var e = b(k.currentTouch.target);
var m = e.closest(this.$needle);
g = !!(m[0])
}
this._touchstart = {
needle: g,
pageX: d,
pageY: c,
translation: {
x: i.x,
y: i.y
},
x_min: s,
x_max: t
};
this._lasttouch = {
pageX: d,
pageY: c
}
},
dragmove: function(g) {
g = b.extend(true, {
event: null,
currentTouch: null
}, g);
this.status.set("dragging", true);
var f = (g.currentTouch) ? g.currentTouch.pageX : g.event.pageX;
var d = f - this._touchstart.pageX;
if (this._touchstart.translation) {
d += this._touchstart.translation.x
}
if (this._touchstart.needle) {
var h = this.fromEventToFlotPos(g.event);
this.checkPosition({
event: g.event,
pos: h
})
} else {
d = this.checkPanRange(d);
var e = this.checkTouchmove(d);
if (e) {
this.recenter(d)
} else {
this.status.set("translation.x", d)
}
var c = this.status.get("touching");
if (c) {
this.checkNeedleLabels()
}
}
},
dragend: function(f) {
f = b.extend(true, {
event: null,
eventInitiator: "dragend",
currentTouch: null
}, f);
var h = this.status.get("dragging");
if (h) {
this.status.set("dragging", false);
return
}
var e = this._animateZoom;
var j = this.fromEventToFlotPos(f.event);
var i = this.fromEventToPlot(f.event);
var g = (i && i.isHeader());
var d = this.models.plotGroup.get("zoomable");
if (d && g) {
var c = this.status.get("zoomedIn");
if (c) {
this.zoomOut({
animate: e,
eventInitiator: f.eventInitiator
})
} else {
if (this._scrollDirection != "y") {
this.zoomIn({
animate: e,
d: new Date(j.x),
eventInitiator: f.eventInitiator
})
}
}
} else {
this.checkPosition({
event: event,
pos: j
})
}
this.status.set("dragging", false)
},
drawNeedleLabels: function(c) {
c = b.extend({
condition: null,
day: null,
selectedVariable: "",
timestamp: null
}, c);
var e = c.condition
, o = c.day
, n = n
, l = c.timestamp;
var j = this.getTimezone()
, m = new Date(l)
, f = this.getNeedleDateLabel(m, j);
var h = this.models.plotGroup.get("mode");
for (var g = 0; g < this.plots.length; g++) {
var k = this.plots[g];
if (k.isHeader()) {
k.updateNeedleLabels({
mode: h,
selectedVariable: n,
timestamp: l,
top: 0,
value: f
})
} else {
k.updateNeedleLabels({
condition: e,
day: o,
mode: h,
selectedVariable: n,
timestamp: l
})
}
}
if (this.$needleLabels) {
this.$needleLabels.html(f)
}
},
drawPlots: function(d) {
var e = b.extend(true, {
setupGrid: true,
xaxisOptions: this.getXAxisOptions()
}, d);
for (var c = 0; c < this.plots.length; c++) {
this.plots[c].draw(e)
}
},
getLabels: function() {
var c = null;
if (!c && this.models.labels) {
c = this.models.labels.attributes
}
if (!c) {
c = this.models.weather.get("labels")
}
return c
},
getNeedleDateFormat: function(g) {
var e = 86400 * 1000
, h = e * 30;
var f = g.date.getUTCMinutes();
var c = [];
if (g.zoomedIn || g.timespan > 10 * e) {
c.push("%a")
}
if (g.timespan > 10 * e) {
c.push("%b %d")
}
if (g.timespan > 365 * e) {
c.push(", %Y")
}
if (!g.dayPartsOnly) {
if (f > 0) {
c.push("%l:%M %P")
} else {
c.push("%l %P")
}
}
var d = c.join(" ");
return d
},
getNeedleDateString: function(d) {
var c = wui.date.strftime(d.format, d.date, true);
return c
},
getNeedleDateLabel: function(j, i) {
var h = this.getViewportDates();
var l = (h.end - h.begin);
var c = {
date: j,
dayPartsOnly: this.status.get("dayPartsOnly"),
timespan: l,
timezone: i,
zoomable: this.models.plotGroup.get("zoomable"),
zoomedIn: this.status.get("zoomedIn")
};
var e = "";
var k = this.models.plotGroup.get("needleDateFormat");
if (b.isFunction(k)) {
e = k(c)
} else {
if (k) {
e = "" + k
} else {
e = this.getNeedleDateFormat(c)
}
}
b.extend(c, {
format: e
});
var f = "";
var g = this.models.plotGroup.get("needleDateString");
if (b.isFunction(g)) {
f = g(c)
} else {
f = this.getNeedleDateString(c)
}
return f
},
getTickDecimalsPreset: function(e) {
if (!this._presetsTickDecimals) {
var c = this.models.weather.get("response.units");
var d = (c === "metric");
this._presetsTickDecimals = {
precip: (d) ? 0 : 1,
pressure: (d) ? 0 : 2
}
}
if (_.has(this._presetsTickDecimals, e)) {
return this._presetsTickDecimals[e]
} else {
return null
}
},
getTicksPreset: function(e) {
if (!this._presetsTicks) {
var c = this.models.weather.get("response.units");
var d = (c === "metric");
this._presetsTicks = {
precip: function(h) {
var f = (d ? 10 : 0.4);
var j = [];
if (h.datamax !== null && h.datamax <= f) {
var g = f;
var i = (d ? 2 : 0.1);
if (h.max > g) {
g = h.max;
var k = 6;
i = g / (k - 1)
}
j = _.range(0, g, i);
j.push(g)
} else {
j = h.tickGenerator(h)
}
return j
}
}
}
if (_.has(this._presetsTicks, e)) {
return this._presetsTicks[e]
} else {
return null
}
},
getUnitPreset: function(c) {
if (!this._presetsUnits) {
var d = this.getLabels();
this._presetsUnits = {
humidity: d.humidity.units,
pressure: " " + d.pressure.units,
temperature: "&nbsp;" + d.temperature.units,
wind: "&nbsp;" + d.wind_speed.units,
wind_direction: "&deg;",
rainfall: "&nbsp;" + d.rainfall.units
}
}
if (_.has(this._presetsUnits, c)) {
return this._presetsUnits[c]
} else {
return null
}
},
getVariablePreset: function(c) {
if (!this._presets) {
var d = this.getLabels();
this._presets = {
cloudcover: {
id: "cloudcover",
abbrev: "cc",
legendFillColor: "rgba(142, 143, 145, 0.3)",
options: {
label: d.cloudcover.label,
color: "#8e8f91",
lines: {
show: true,
fill: 0.3,
lineWidth: 1
}
},
show: true,
textColor: "#696969",
units: d.cloudcover.units
},
dewpoint: {
id: "dewpoint",
abbrev: "dp",
filter: function(e) {
return ( e.dewpoint !== -99)
},
show: true,
textColor: "#22730b",
units: " " + d.dewpoint.units,
options: {
label: d.dewpoint.label,
color: "#5b9f4a"
}
},
feelslike: {
id: "feelslike",
abbrev: "fl",
show: true,
units: " " + d.feelslike.units,
missingFromNWS: true,
options: {
label: d.feelslike.label,
color: "#ad55a1"
}
},
humidity: {
id: "humidity",
abbrev: "h",
options: {
label: d.humidity.label,
color: "#87c404"
},
show: true,
textColor: "#5b9f49",
units: d.humidity.units,
},
liquid_precip: {
id: "liquid_precip",
abbrev: "qpf",
hasPrecip: true,
legendUnits: d.rainfall.units,
missingFromNWS: true,
options: {
label: "Hourly Liquid Precip.",
color: "#22730b",
lines: {
show: true,
steps: true,
fill: 0.3,
lineWidth: 1
}
},
show: true,
units: function(h, f, e) {
var j = _.clone(h.date);
j.epoch += (3600);
var i = '<span class="units"> ' + d.rainfall.units + "</span>";
var g = i + " (" + wui.date.strftime("%l%P-", h.date, true) + wui.date.strftime("%l%P", j, true) + ")";
if (e) {
g += "<br />" + e.summary.liquid_precip + i + " total (" + wui.date.strftime("%a", e.summary.date, true) + ")"
}
return g
}
},
max_temperature: {
id: "max_temperature",
abbrev: "tmax",
enabled: true,
enableWhen: function(e) {
return ( e.dayPartsOnly)
},
options: {
label: "Max Temperature",
color: "#d6212a"
},
show: true,
units: " " + d.temperature.units
},
min_temperature: {
id: "min_temperature",
abbrev: "tmin",
enabled: true,
enableWhen: function(e) {
return ( e.dayPartsOnly)
},
options: {
label: "Min Temperature",
color: "#0053ae"
},
show: true,
units: " " + d.temperature.units
},
pop: {
id: "pop",
abbrev: "pop",
show: true,
textColor: "#008fbf",
units: d.pop.units,
options: {
label: d.pop.abbrev,
color: "#16aadc",
lines: {
show: true,
steps: true,
fill: 0.3,
lineWidth: 1
}
}
},
pop_type_notsnow: {
id: "pop",
abbrev: "pop",
checkbox: false,
filter: function(e) {
return ( e.precip_type !== "snow")
},
legendFillColor: "rgba(22, 170, 220, 0.5)",
needle: false,
options: {
label: d.pop.abbrev,
color: "#16aadc",
bars: {
show: true,
fill: 0.3,
lineWidth: 0
},
lines: {
show: false
}
},
show: true,
textColor: "#008fbf",
units: d.pop.units
},
pop_type_snow: {
id: "pop",
abbrev: "pop",
checkbox: false,
filter: function(e) {
return ( e.precip_type === "snow")
},
legendFillColor: "rgba(128, 38, 116, 0.5)",
missingFromNWS: true,
needle: false,
options: {
label: d.chancesnow.label,
color: "#16aadc",
bars: {
show: true,
fillColor: "rgba(128, 38, 116, 0.3)",
lineWidth: 0
},
lines: {
show: false
}
},
show: true,
textColor: "#008fbf",
units: d.pop.units
},
precip_1hr: {
id: "precip_1hr",
abbrev: "precip_1hr",
show: true,
units: " " + d.rainfall.units,
options: {
label: d.precipitation.label,
color: "#87c404"
}
},
precip_rate: {
id: "precip_rate",
abbrev: "precip_rate",
show: true,
units: " " + d.rainfall.units,
options: {
label: "Precip. Rate",
color: "#87c404"
}
},
precip_today: {
id: "precip_today",
abbrev: "precip",
filter: function(e) {
return ( e.precip_today >= 0)
},
hasPrecip: true,
missingFromNWS: true,
options: {
label: "Precip. Accum. Total",
color: "#0074a2",
},
show: true,
units: " " + d.rainfall.units
},
pressure: {
id: "pressure",
abbrev: "p",
missingFromNWS: true,
options: {
label: d.pressure.label,
color: "#1e2023"
},
show: true,
units: " " + d.pressure.units
},
temperature: {
id: "temperature",
abbrev: "temp",
enabled: true,
enableWhen: function(e) {
return ( !e.dayPartsOnly)
},
options: {
label: d.temperature.label,
color: "#d6212a"
},
show: true,
units: " " + d.temperature.units
},
wind_speed: {
id: "wind_speed",
abbrev: "wspd",
show: true,
units: " " + d.wind_speed.units,
options: {
label: d.wind_speed.label,
color: "#002f80"
}
},
wind_dir_degrees: {
id: "wind_dir_degrees",
abbrev: "wdir",
show: true,
legendUnits: false,
units: function(f, e) {
return '<span class="units"> deg</span> (from ' + f.wind_dir + ")"
},
options: {
label: d.wind_direction.label,
color: "#002f80",
lines: {
show: false
},
points: {
fill: false,
radius: 1,
show: true
}
}
},
wind_gust: {
id: "wind_gust_speed",
abbrev: "gust",
show: true,
units: " " + d.wind_gust.units,
options: {
label: d.wind_gust.label,
color: "#EF9856",
lines: {
show: false
},
points: {
fill: false,
radius: 1,
show: true
}
}
},
wind_speed_dir: {
id: "wind_speed",
abbrev: "wspd",
legendUnits: false,
show: true,
units: function(f, e) {
return '<span class="units"> ' + d.wind_speed.units + "</span> from " + f.wind_dir
},
color: "#002f80",
options: {
label: d.wind_speed.label,
color: "rgba(0,47,128,0.5)",
lines: {
show: true,
lineWidth: 1
},
rotatedmarker: {
id: "wind_dir_degrees",
show: true,
fill: true,
fillColor: "#002f80",
preventOverlap: true,
preventOverlapMargin: 2,
radius: 5,
symbol: wui.backbone.utils.symbols.arrow
}
}
},
solarradiation: {
id: "solarradiation",
abbrev: "s",
enableWhen: function(e) {
return ( !e.dayPartsOnly)
},
options: {
label: "Solar Radiation",
color: "#FFB92F"
},
show: true,
units: " watts/m&sup2;"
},
uv_index: {
id: "uv_index",
abbrev: "uv",
enableWhen: function(e) {
return ( !e.dayPartsOnly)
},
options: {
label: d.uv_index.label,
color: "#802674"
},
show: true,
units: ""
},
aqpm10: {
id: "aqpm10",
abbrev: "pm10",
options: {
label: "PM 10",
color: "#CC5500"
},
show: true,
units: " μg/m3"
},
aqozone: {
id: "aqozone",
abbrev: "ozone",
options: {
label: "Ozone",
color: "#FFB580"
},
show: true,
units: " ppb"
},
aqpm25: {
id: "aqpm25",
abbrev: "pm2.5",
options: {
label: "PM 2.5",
color: "#990008"
},
show: true,
units: " μg/m3"
},
aqso2: {
id: "aqso2",
abbrev: "so2",
options: {
label: "SO2",
color: "#8ED1E9"
},
show: true,
units: " ppb"
},
aqno2: {
id: "aqno2",
abbrev: "no2",
options: {
label: "NO2",
color: "#AC54A0"
},
show: true,
units: " ppb"
},
aqco: {
id: "aqco",
abbrev: "co",
options: {
label: "CO",
color: "#6697CC"
},
show: true,
units: " ppm"
}
}
}
if (_.has(this._presets, c)) {
return this._presets[c]
} else {
return null
}
},
getViewportDates: function() {
var j = this.getFirstPlot()
, e = j.flot;
var k = e.getAxes()
, l = k.xaxis;
var g = new Date(l.min)
, m = new Date(l.max);
var i = this.fromBufferedToViewportDates(g, m);
var f = i.begin.getTime()
, h = i.end.getTime();
var c = this.status.get("translation");
if (c.x) {
var d = l.c2p(c.x) - l.c2p(0);
f -= d;
h -= d
}
return {
begin: new Date(f),
end: new Date(h)
}
},
fitDays: function(d, c, g) {
var f = this.getFittedDates(c);
if (f) {
var e = this.fromViewportToBufferedDates(f.begin, f.end);
this.synchronizeZoom(null, e.begin, e.end, !!d, g)
} else {
this.drawPlots()
}
},
fitRangeY: function() {
for (var c = 0; c < this.plots.length; c++) {
var d = this.plots[c];
d.fitRangeY()
}
},
fitRangeYDebounced: function() {},
fromBufferedToViewportDates: function(h, n) {
var e = h.getTime()
, j = n.getTime();
var i = this.models.plotGroup.get("bufferLeft");
var l = this.models.plotGroup.get("bufferRight");
if (i || l) {
var k = this.getFirstPlot()
, f = k.flot
, g = f.getPlotOffset()
, o = f.width()
, c = n - h;
var m = i / o
, d = l / o;
e = (e + m * c);
j = (j - d * c);
e = a.roundTimestamp(e, 1000);
j = a.roundTimestamp(j, 1000)
}
return {
begin: new Date(e),
end: new Date(j)
}
},
fromElementToPlot: function(d) {
var f = this.models.plotGroup.get("classNames");
var c = d.closest("." + f.plot);
var e = _.find(this.plots, function(g) {
return g.$el.is(c)
});
return e
},
fromEventToFlotPos: function(e) {
var d = e.pageX
, c = e.pageY;
var g = e.originalEvent;
if (g && g.changedTouches) {
var f = g.changedTouches[0];
d = f.pageX;
c = f.pageY
}
return this.fromScreenToFlotPos(d, c)
},
fromEventToPlot: function(d) {
var c = b(d.target);
return this.fromElementToPlot(c)
},
fromScreenToFlotPos: function(h, g) {
var d = this.models.plotGroup.get("classNames");
var i = this.models.plotGroup.get("bufferLeft");
var j = this.getFirstPlot()
, k = j.flot.getAxes()
, m = k.xaxis;
var e = j.flot.getPlotOffset();
var c = this.status.get("translation");
var f = h - this.$plots.offset().left + i - e.left - c.x;
var l = {
x: m.c2p(f),
y: 0,
pageX: h,
pageY: g
};
return l
},
fromViewportToBufferedDates: function(g, q) {
var d = g.getTime()
, j = q.getTime();
var k = this.getFirstPlot()
, e = k.flot;
var m = e.getAxes()
, o = m.xaxis;
var h = this.models.plotGroup.get("bufferLeft");
var l = this.models.plotGroup.get("bufferRight");
if (h || l) {
var f = e.getPlotOffset()
, n = k.getWidth()
, i = q - g;
var p = h / n
, c = l / n;
d = (d - p * i);
j = (j + c * i);
d = a.roundTimestamp(d, 1000);
j = a.roundTimestamp(j, 1000)
}
return {
begin: new Date(d),
end: new Date(j)
}
},
getClosestConditionByTimestamp: function(g) {
var o = this.getDays();
var c = 0;
var p = null;
var d = null;
var f = this.getTimezone();
var l = [];
for (var e = 0; e < o.length; e++) {
var j = o[e];
var k = this.getHours(j);
if (k) {
l = l.concat(k)
} else {
l.push(j.summary)
}
}
var n = (f) ? f.tz_offset_hours : 0;
var m = {
date: {
epoch: g / 1000 - n * 3600
}
};
var h = _.sortedIndex(l, m, function(i) {
return ((i || {}).date || {}).epoch
});
p = l[h];
return p
},
getDayByCondition: function(g) {
var d = "%Y%m%d";
var c = wui.date.strftime(d, g.date, true);
var f = this.getDays();
var e = _.find(f, function(h) {
if (h.summary && h.summary.date) {
var i = wui.date.strftime(d, h.summary.date, true);
return ( c === i)
} else {
return false
}
});
return e
},
getDays: function() {
var c = this.models.weather.getDays();
return c
},
getFirstPlot: function() {
var c = this.getVisiblePlots();
return c[0] || null
},
getFittedDates: function(l) {
var d = this.status.get("zoomedIn");
if (d) {
return null
}
var i = this.models.plotGroup.get("dayMaxWidth");
if (!i) {
return null
}
var k = this.getFirstPlot();
if (!k) {
return null
}
var c = k.getWidth()
, j = Math.floor(c / i)
, e = k.flot
, m = e.getAxes().xaxis;
var h = null;
if (l) {
var f = new Date((m.min + m.max) / 2);
h = wui.date.floor(f, "day");
var g = Math.floor(j / 2);
wui.date.increment(h, -g, "day")
} else {
h = new Date(m.min)
}
var n = wui.date.create(j, "day", h);
this.validateDateRange(h, n);
return {
begin: h,
end: n
}
},
getHours: function(d) {
var e = d.observations;
var c = d.hours;
if (e && e.length) {
return e
} else {
if (c && c.length) {
return c
} else {
return null
}
}
},
getTimezone: function() {
return a.getTimezoneFromAPI(this.models.weather)
},
getVisiblePlots: function() {
var c = [];
c = _.filter(this.plots, function(d) {
return d._visible
});
return c
},
getXAxisOptions: function() {
var g = {};
var c = this.models.plotGroup.get("tickZoomPreset");
var e = this.models.plotGroup.get("zoomable");
var d = this.status.get("zoomedIn");
if (e && c) {
var h = a.tickZoomPresets[c];
var f = h.call(null, d);
b.extend(true, g, f)
}
return g
},
onClick: function(c) {
this.dragend({
event: c,
eventInitiator: "onClick"
})
},
onDraggingChange: function(d, e) {
if (e) {
var c = this.status.get("touching");
if (!c) {
this.checkPosition({
pos: null
})
}
} else {}
},
onMousedown: function(d) {
if (d.which === 1) {
this.status.set("mousedown", true);
var c = this.status.get("touching");
if (!c) {
this.dragstart({
event: d
})
}
}
},
onMouseleave: function(c) {
this.status.set("mousedown", false);
this.checkPosition({
event: c,
pos: null
})
},
onMousemove: function(e) {
var d = this.status.get("mousedown");
var c = this.status.get("touching");
if (d) {
if (!c) {
this.dragmove({
event: e
})
}
} else {
var f = this.fromEventToFlotPos(e);
this.checkPosition({
event: e,
pos: f
});
this.checkNeedleDirection(e)
}
},
onMouseup: function(c) {
this.status.set("mousedown", false)
},
onPanLeft: function(c) {
c.stopPropagation();
this.panLeft()
},
onPanRight: function(c) {
c.stopPropagation();
this.panRight()
},
onPlotPan: function(c, d) {
this.synchronizePan(c, d)
},
onRangeChange: function(c, d) {
if (d.complete) {
var e = (d.frame / d.elapsed * 1000).toFixed(1)
}
this.setNeedleNow()
},
onResize: function(d) {
var c = this.models.plotGroup.get("dayMaxWidth");
this.resize();
if (c) {
this.fitDays()
} else {
this.drawPlots({
setupGrid: false
})
}
},
onTimestampChange: function(h, l) {
var j = this.models.plotGroup.get("bufferLeft");
var k = this.getFirstPlot()
, m = k.flot.getAxes()
, p = m.xaxis;
var e = k.flot.getPlotOffset();
var c = this.status.get("translation");
var i = this.status.get("needle.locked");
if (this.$needle[0]) {
if (l === null) {
this.$needle.hide()
} else {
if (i) {
this.$needle.show()
} else {
this.$needle.show();
var g = p.p2c(l) - j + e.left - this.$needle.width() / 2 + c.x;
this.status.set("needle.x", g);
a.translate(this.$needle, {
x: g
})
}
}
}
if (!i) {
this.positionNeedleLabels(l)
}
var n = null;
var f = this.status.get("condition");
var o = this.status.get("day");
var d = this.status.get("needle.timer");
if (!d) {
var q = this;
d = window.requestAnimationFrame(function() {
q.drawNeedleLabels({
condition: f,
day: o,
selectedVariable: n,
timestamp: l
});
q.status.set("needle.timer", null)
});
this.status.set("needle.timer", d)
}
},
onTouchstart: function(c) {
var e = c.originalEvent;
var d = e.changedTouches[0];
this._scrollDirection = null;
this.status.set("touching", true);
this.dragstart({
event: c,
currentTouch: d
})
},
onTouchmove: function(h) {
var j = h.originalEvent;
var i = j.changedTouches[0];
var g = i.pageX;
var f = i.pageY;
var d = Math.abs(g - this._lasttouch.pageX);
var c = Math.abs(f - this._lasttouch.pageY);
var e = 3;
if (!this._scrollDirection) {
if (d > e || c > e) {
if (d > c) {
this._scrollDirection = "x"
} else {
this._scrollDirection = "y"
}
}
}
if (this._scrollDirection == "x") {
h.preventDefault();
this.dragmove({
event: h,
currentTouch: i
})
}
this._lasttouch.pageX = g;
this._lasttouch.pageY = f
},
onTouchend: function(c) {
this.status.set("touching", false);
this.checkNeedleLabels()
},
onTouchcancel: function(c) {
this.status.set("touching", false);
this.dragend({
event: c
});
this.checkNeedleLabels()
},
onTranslateChange: function(c, d) {
this.setNeedleNow()
},
onVariablesChange: function() {
this.checkPrecip()
},
onWeatherChange: function(c) {
if (_.has(c.changed, "forecast") || _.has(c.changed, "history")) {
this.render()
}
},
onZoomedInChange: function(c, d) {
this.setZoomButtons(d);
this.drawPlots()
},
onZoomIn: function(c) {
this.zoomIn({
animate: this._animateZoom,
eventInitiator: "onZoomIn"
})
},
onZoomOut: function(c) {
this.zoomOut({
animate: this._animateZoom,
eventInitiator: "onZoomOut"
})
},
pan: function(c) {
c = b.extend({
amount: 1,
animate: false,
plot: null,
smooth: false
}, c);
var f = c.plot;
if (!f) {
f = this.getFirstPlot();
if (!f) {
return null
}
}
var e = this.getViewportDates();
var j = (e.end - e.begin) * c.amount
, d = new Date(e.begin.getTime() + j)
, l = new Date(e.end.getTime() + j);
this.validateDateRange(d, l);
if (c.smooth && c.animate) {
var g = f.flot.getAxes()
, i = g.xaxis;
var m = i.p2c(d.getTime()) - i.p2c(e.begin.getTime());
this.recenter();
var k = this;
_.defer(function() {
var n = k.models.plotGroup.get("panDuration");
k.status.set("transition.duration", n);
k.status.set("translation.x", -m);
if (n) {
window.setTimeout(function() {
k.status.set("transition.duration", 0);
k.checkNeedleLabels()
}, n)
}
})
} else {
var h = this.fromViewportToBufferedDates(d, l);
this.synchronizeZoom(f, h.begin, h.end, c.animate)
}
},
panLeft: function() {
this.pan({
animate: true,
amount: -1,
smooth: true
})
},
panRight: function() {
this.pan({
animate: true,
amount: 1,
smooth: true
})
},
positionNeedleLabels: function(d) {
for (var c = 0; c < this.plots.length; c++) {
var e = this.plots[c];
e.positionNeedleLabels({
timestamp: d
})
}
},
recenter: function(d) {
if (!d && d !== 0) {
d = this.status.get("translation.x")
}
var g = this.getFirstPlot()
, f = g.flot.getAxes()
, h = f.xaxis;
var e = h.c2p(h.p2c(h.min) - d)
, c = h.c2p(h.p2c(h.max) - d);
this.setRangeX(e, c);
if (this._touchstart.translation) {
this._touchstart.translation.x = 0
}
this.status.set("translation.x", 0);
this.setNeedleNow()
},
render: function() {
if (this._numRenders < 1) {
this.initializeAtFirstRender();
this.resize()
}
this.checkRangeOptions();
var c = this.checkDayPartsOnly();
this.status.set("dayPartsOnly", c);
this.drawPlots({
astronomy: true,
fitRangeY: true
});
this._numRenders++;
var f = this.models.plotGroup.get("dayMaxWidth");
if (f && this._numRenders <= 1) {
this.fitDays()
}
if (this._numRenders <= 1) {
this._now = new Date();
var g = this.getTimezone()
, e = a.getTimestamp(this._now, g)
, h = new Date(e);
this.checkPosition({
date: h
});
this.setNeedleNow()
}
this.checkStorm();
this.$el.addClass("loaded");
return this
},
resize: function() {
var d = this.$el.is(":visible");
if (!d) {
return
}
var c = this.getVisiblePlots();
_.each(c, function(e) {
e.resize()
})
},
checkStorm: function() {
if (wui.bootstrapped.citypage) {
var d = this.status.get("zoomedIn");
var f = wui.bootstrapped.citypage.storm;
for (var e in f) {
var c = ".flot-header .col-" + e + "T000000";
var g = "has-alert";
if (f[e].type === "blizzard") {
g += " has-blizzard"
}
if (b(c).length) {
if (d) {
b(c).removeClass(g)
} else {
b(c).addClass(g)
}
}
}
}
},
setNeedleNow: function() {
if (!this.$needleNow || !this.$needleNow[0]) {
return
}
var h = this.getTimezone()
, m = a.getTimestamp(this._now, h)
, j = new Date(m);
var g = this.models.plotGroup.get("bufferLeft");
var i = this.getFirstPlot()
, k = i.flot.getAxes()
, l = k.xaxis;
var e = i.flot.getPlotOffset();
var c = this.status.get("translation");
var f = l.p2c(m) - g + e.left - this.$needleNow.width() / 2 + c.x;
a.translate(this.$needleNow, {
x: f
})
},
setRangeX: function(e, c) {
for (var d = 0; d < this.plots.length; d++) {
var f = this.plots[d];
f.setRangeX(e, c)
}
},
setStatusRange: function(c) {
c = b.extend({
complete: false,
elapsed: 0,
fraction: 0,
frame: 0,
min: 0,
max: 0
}, c);
this.status.set({
range: c
})
},
setZoomButtons: function(d) {
if (typeof d == "undefined") {
d = this.status.get("zoomedIn")
}
var c = this.$el.find(".plot-zoom-daily");
var e = this.$el.find(".plot-zoom-hourly");
var f = this.models.plotGroup.get("classNames");
c.toggleClass(f.selected, !d);
e.toggleClass(f.selected, !!d)
},
synchronizePan: function(c, g) {
for (var d = 0; d < this.plots.length; d++) {
if (c === d) {
continue
}
var f = this.plots[d];
if (f) {
var e = b.extend({}, g, {
preventEvent: true
});
f.flot.pan(e)
}
}
this.checkStorm()
},
synchronizeZoom: function(i, e, d, c, h) {
var j = e.getTime()
, g = d.getTime();
if (c) {
var f = this.models.plotGroup.get("zoomDuration");
this.animateRangeX(j, g, f, i, h)
} else {
this.setRangeX(j, g);
if (h) {
h()
}
}
this.checkStorm()
},
translate: function(c) {
for (var d = 0; d < this.plots.length; d++) {
var e = this.plots[d];
e.translate(c)
}
},
updateDates: function(c, e) {
for (var d in e) {
this.plots.setAdded(d)
}
},
validateDateRange: function(e, d) {
var f = this.models.plotGroup.get("date_min"), c = this.models.plotGroup.get("date_max"), g;
if (f && e < f) {
g = f - e;
e.setTime(f.getTime());
d.setTime(d.getTime() + g)
}
if (c && d > c) {
g = d - c;
e.setTime(e.getTime() - g);
d.setTime(c.getTime())
}
if (f && e < f) {
e.setTime(f.getTime())
}
if (c && d > c) {
d.setTime(c.getTime())
}
},
zoomCheck: function() {
this.undelegateEvents()
},
zoomIn: function(c) {
this.zoomCheck();
c = b.extend({
animate: false,
d: null,
eventInitiator: "zoomIn",
plot: null
}, c);
var l = this
, h = c.plot
, i = c.d;
if (!h) {
var h = this.getFirstPlot();
if (!h) {
return null
}
}
if (!i) {
var g = this.getViewportDates();
i = g.begin
}
this.setZoomButtons(true);
var e = function() {
var d = {
d: i,
eventInitiator: c.eventInitiator
};
l.status.set("zoomedIn", true, d);
l.recenter();
l.checkNeedleLabels();
l.checkStorm()
};
var f = wui.date.roundDownTo(i, 1, "day")
, k = wui.date.roundUpTo(i, 1, "day");
var j = this.fromViewportToBufferedDates(f, k);
this.synchronizeZoom(h, j.begin, j.end, c.animate, e);
this.checkStorm()
},
zoomOut: function(c) {
this.zoomCheck();
c = b.extend({
animate: false,
eventInitiator: "zoomOut",
plot: null
}, c);
var k = this;
var h = c.plot;
if (!h) {
var h = this.getFirstPlot();
if (!h) {
return null
}
}
this.setZoomButtons(false);
var f = {
eventInitiator: c.eventInitiator
};
this.status.set("zoomedIn", false, f);
this.recenter();
var d = function() {
k.checkNeedleLabels();
k.checkStorm()
};
var g = this.models.plotGroup.get("dayMaxWidth");
if (g) {
var i = true;
this.fitDays(c.animate, i, d)
} else {
var l = this.models.plotGroup.get("date_min")
, e = this.models.plotGroup.get("date_max");
var j = this.fromViewportToBufferedDates(l, e);
this.synchronizeZoom(h, j.begin, j.end, c.animate, d)
}
this.checkStorm()
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.Plot = Backbone.View.extend({
initialize: function(d) {
this.options = d || {};
this.status = this.options.status;
this.models = this.options.models || {};
this.setOptions(d);
this.flot = null;
this.flotOptions = null;
this.legend = null;
this._needleLabels = [];
this._visible = true;
this.templateHeaderDaily = _.template(b("script#plotgroup-header-daily-template").html());
this.templateHeaderHourly = _.template(b("script#plotgroup-header-hourly-template").html());
this.checkVariablesEnabled();
var c = this.getPlotOptions();
var j = c.variables;
var f = "plots[" + this.options.plotIndex + "]";
for (var e = 0; e < j.length; e++) {
this.listenTo(this.models.plotGroup, "change:" + f + ".variables[" + e + "]", this.onVariableChange)
}
this.listenTo(this.status, "change:dayPartsOnly", this.onDayPartsOnlyChange);
this.listenTo(this.status, "change:transition", this.onTransitionChange);
this.listenTo(this.status, "change:translation", this.onTranslateChange);
this.listenTo(this.status, "change:zoomedIn", this.onZoomedInChange);
this.createFlot();
this.createNeedleLabels();
if (c.legends === true) {
this.createLegend()
} else {
if (c.legends === false) {} else {
if (this.models.plotGroup.get("legends") === false) {} else {
this.createLegend()
}
}
}
var g = this.isHeader();
if (g) {
var h = this.models.plotGroup.get("classNames");
this.$el.addClass(h.header)
}
this.translate({
x: 0,
y: 0,
z: 0
})
},
animateRangeY: function(h, m, g, f) {
var n = this;
var c = null;
var l = this.flot.getAxes().yaxis
, d = l.min
, k = l.max
, j = (window.performance && window.performance.now) ? window.performance.now() : null;
var i = 0;
function e(t) {
if (j === null) {
j = t
}
i++;
var q = t - j;
var s = q / g;
var p = false;
if (s > 1) {
s = 1;
p = true
}
var r = d + s * (h - d);
var o = k - s * (k - m);
n.setRangeY(r, o);
if (p) {
if (f) {
f()
}
} else {
c = requestAnimationFrame(e)
}
}
c = requestAnimationFrame(e);
return c
},
checkVariablesEnabled: function() {
var d = this.status.get("dayPartsOnly");
var c = this.getPlotOptions();
var k = c.variables;
var h = "plots[" + this.options.plotIndex + "]";
var j = {
dayPartsOnly: d
};
for (var g = 0; g < k.length; g++) {
var f = k[g];
if (b.isFunction(f.enableWhen)) {
var e = f.enableWhen(j);
this.models.plotGroup.set(h + ".variables[" + g + "].enabled", e)
}
}
},
createFlot: function() {
var f = [];
var e = this.models.plotGroup.attributes;
var k = this.getPlotOptions();
var g = b.extend(true, {}, this.options.flot, e.flot, k.flot);
this.flotOptions = g;
var l = {
draw: []
};
var d = this.isHeader();
if (d) {
l.draw.push(b.proxy(this.drawHeader, this))
}
b.extend(true, g, {
hooks: l
});
var h = this.models.plotGroup.get("bufferLeft");
var j = this.models.plotGroup.get("bufferRight");
if (h || j) {
this.$el.css({
"margin-left": -h,
"margin-right": -j
})
}
this.flot = b.plot(this.$el, f, g);
if (h || j) {
this.$el.children(".flot-text").css({
left: h,
right: j
})
}
if (k.freezeline) {
var i = this.getFreezelineMarkings();
var c = this.flot.getOptions().grid;
if (c.markings && b.isArray(c.markings)) {
c.markings = i.concat(c.markings)
} else {
c.markings = i
}
}
},
createLegend: function() {
if (!wui.Views.PlotLegend) {
return
}
var c = b("<div />");
this.legend = new wui.Views.PlotLegend({
model: this.model,
models: {
plotGroup: this.models.plotGroup,
weather: this.models.weather
},
el: c[0],
plotIndex: this.options.plotIndex
});
c.insertAfter(this.$el)
},
createNeedleLabel: function(d) {
var e = this.flot.getOptions().needle;
var c = b("<div />").addClass(e.classNames.label);
if (d) {
c.css({
color: d.textColor || d.color || d.options.color,
})
}
return c
},
createNeedleLabels: function(g) {
g = b.extend({}, g);
if (!this.flot.needle) {
return
}
var d = this.getPlotOptions();
var k = d.variables;
var j = this._needleLabels;
var h = this.isHeader();
if (h) {
var c = this.createNeedleLabel();
j.push({
top: 0,
node: c
});
this.flot.needle.addLabel(c)
}
for (var f = 0; f < k.length; f++) {
var e = k[f];
var c = this.createNeedleLabel(e);
j.push({
top: 0,
node: c,
variableIndex: f
});
this.flot.needle.addLabel(c)
}
},
draw: function(e) {
var g = this.getFlotData();
var c = (g.length > 0);
var f = this.isHeader();
if (!c && f) {
var d = [];
this.setFlotData([d]);
this.drawFlot(e);
c = true
} else {
this.setFlotData(g);
this.drawFlot(e)
}
this._visible = c;
this.$el.toggle(c)
},
drawFlot: function(d) {
d = b.extend(true, {
astronomy: false,
date: null,
fitRangeY: false,
setupGrid: false,
xaxisOptions: null
}, d);
var f = this.models.plotGroup.attributes;
var r = this.getPlotOptions();
var j = this.getTimezone();
var p = b.extend(true, {}, f, r);
if (d.setupGrid) {
var o = this.flot.getAxes().xaxis;
if (d.date) {
var s = wui.date.roundDownTo(d.date, 1, "day");
var e = wui.date.roundUpTo(d.date, 1, "day");
o.options.min = s.getTime();
o.options.max = e.getTime()
}
if (p.flot && p.flot.xaxis) {
b.extend(o.options, p.flot.xaxis)
}
if (d.xaxisOptions) {
b.extend(o.options, d.xaxisOptions)
}
if (d.fitRangeY && r.autoscale) {
var l = this.flot.getAxes().yaxis;
var i = {
min: null,
max: null
};
var g = this.models.plotGroup.get("bufferLeft");
var k = this.models.plotGroup.get("bufferRight");
if (g || k) {
i = this.getVisibleDataminDatamax()
}
if (i.min === null) {
i.min = l.datamin
}
if (i.max === null) {
i.max = l.datamax
}
this.padRangeY(i, l);
b.extend(l.options, i)
}
if (d.astronomy) {
var n = b.extend(true, {}, f.astronomy, r.astronomy);
if (n) {
var m = n.markings;
if (m && m.show) {
var q = this.models.weather.get("astronomy.days");
var h = a.getAstronomyMarkings(q, m, j);
var c = this.flot.getOptions().grid;
if (c.markings && b.isArray(c.markings)) {
c.markings = h.concat(c.markings)
} else {
c.markings = h
}
}
}
}
this.flot.setupGrid()
}
this.flot.draw()
},
drawHeader: function(e, c) {
var f = this.models.weather.get("forecast.days");
if (!f) {
return
}
var d = this.status.get("zoomedIn");
if (d) {
this.drawHeaderHourly()
} else {
this.drawHeaderDaily()
}
this.drawHeaderAstronomy(e)
},
drawHeaderDaily: function() {
var j = this.getTimezone();
var n = this.templateHeaderDaily;
var o = this.models.weather.get("forecast.days");
var h = this.models.weather.get("labels");
var k = this.models.weather.get("response.units");
var c = this.models.weather.get("forecast.source");
var d = {
iconset: this.model.get("iconset"),
labels: h,
source: c,
units: k,
zoomedIn: this.status.get("zoomedIn")
};
for (var g = 0, f = o.length; g < f; g++) {
var m = o[g];
var e = m.summary;
this.drawHeaderCondition(e, j, n, d)
}
},
drawHeaderHourly: function() {
var k = this.getTimezone();
var o = this.templateHeaderHourly;
var p = this.models.weather.get("forecast.days");
var h = this.models.weather.get("labels");
var c = {
iconset: this.model.get("iconset"),
labels: h,
zoomedIn: this.status.get("zoomedIn")
};
for (var g = 0, e = p.length; g < e; g++) {
var m = p[g];
var n = m.hours;
for (var f = 0; f < n.length; f++) {
var d = n[f];
this.drawHeaderCondition(d, k, o, c)
}
}
},
drawHeaderCondition: function(e, h, m, c) {
var i = a.getTimestamp(e, h);
var j = new Date(i);
if (!c.zoomedIn) {
j = wui.date.floor(j, "day")
}
var k = "col-" + wui.date.strftime("%Y%m%dT%H0000", j, true);
var l = this.$el.find("." + k).find(".col-body");
if (l[0]) {
var g = {
condition: e,
labels: c.labels,
opts: c
};
var f = m(g);
l.html(f)
}
},
drawHeaderAstronomy: function(f) {
var f = f || this.flot;
var s = f.getAxes()
, e = s.xaxis;
var q = this.$el.find(".flot-header");
var g = this.models.weather.get("astronomy.days");
if (!g) {
return
}
var o = this.getTimezone();
var y = this.status.get("zoomedIn");
var v = true
, x = true
, j = true
, n = (y);
for (var u = 0, p = g.length; u < p; u++) {
var r = g[u];
var c = null
, k = ""
, h = ""
, w = null
, m = 0;
if (v) {
w = new Date(r.sunrise.date.epoch * 1000);
m = a.getTimestamp(w, o);
w.setTime(m);
if (m > e.min && m < e.max) {
k = "";
if (j) {
k += '<div class="icon-sunrise"></div>'
}
if (n) {
h = wui.date.strftime("%l:%M%P", w, true);
k += '<div class="icon-label">' + h + "</div>"
}
c = b("<div>" + k + "</div>").addClass("astronomy-marker sunrise").css({
left: e.p2c(m)
}).appendTo(q)
}
}
if (x) {
w = new Date(r.sunset.date.epoch * 1000);
m = a.getTimestamp(w, o);
w.setTime(m);
if (m > e.min && m < e.max) {
k = "";
if (j) {
k += '<div class="icon-sunset"></div>'
}
if (n) {
h = wui.date.strftime("%l:%M%P", w, true);
k += '<div class="icon-label">' + h + "</div>"
}
c = b("<div>" + k + "</div>").addClass("astronomy-marker sunset").css({
left: e.p2c(m)
}).appendTo(q)
}
}
}
},
fitRangeY: function(i) {
var d = this.getPlotOptions();
if (!d.autoscale) {
if (i) {
i()
}
return
}
var h = this.models.plotGroup.get("fitDuration");
var f = this.flot.getAxes().yaxis;
var g = this.getVisibleDataminDatamax();
if (g.min === null) {
g.min = f.datamin
}
if (g.max === null) {
g.max = f.datamax
}
this.padRangeY(g, f);
var e = g.min
, c = g.max;
this.animateRangeY(e, c, h, i)
},
fromConditionsToFlot: function(e, p, k, r) {
var f = [];
var m = (p.options.text && p.options.text.show);
var z = (p.options.rotatedmarker && p.options.rotatedmarker.show);
var u = b.isFunction(k);
var w = b.isFunction(p.filter);
var j = this.status.get("dayPartsOnly");
var c = (m) ? p.options.text.y : 0;
var A = (z) ? p.options.rotatedmarker.id : null;
var n = this.getTimezone();
for (var s = 0, o = e.length; s < o; s++) {
var t = e[s];
var h = a.getTimestamp(t, n);
var g = 0;
var B = "";
if (u) {
B = k.call(null, t)
} else {
B = t[k]
}
if (w) {
var d = p.filter.call(null, t, {
dayPartsOnly: j
});
if (!d) {
B = null
}
}
if (m) {
g = c;
f.push([h, g, B])
} else {
if (z) {
g = a.isValidMeasurement(B) ? parseFloat(B) : null;
var v = null;
if (_.isNumber(t[A])) {
var q = parseFloat(t[A]);
v = q / 180 * Math.PI
}
f.push([h, g, v])
} else {
g = a.isValidMeasurement(B) ? parseFloat(B) : null;
f.push([h, g])
}
}
}
return f
},
getFlotData: function() {
var c = this.getPlotOptions();
var j = [];
var k = _.reject(c.variables, function(i) {
return ( i.show === false || i.enabled === false)
});
var h = this.models.weather.get("forecast.source");
if (h == "nws") {
k = _.reject(k, function(i) {
return i.missingFromNWS
})
}
for (var g = 0; g < k.length; g++) {
var d = k[g];
var f = this.getFlotSeriesData(d);
var e = b.extend(true, {}, d.options, {
data: f
});
j.push(e)
}
return j
},
getFlotSeriesData: function(f) {
var e = this.models.weather;
var c = [];
var d = null;
var h = false;
var k = [];
d = f.id;
var m = e.get("history.days");
if (m) {
for (var g = 0; g < m.length; g++) {
var j = m[g];
k = this.getHours(j);
if (k && k.length && d) {
var l = [];
l = this.fromConditionsToFlot(k, f, d, j);
c = c.concat(l)
}
}
}
var m = e.get("forecast.days");
if (m) {
for (var g = 0; g < m.length; g++) {
var j = m[g];
k = this.getHours(j);
if (k && k.length && d && !h) {
var l = [];
l = this.fromConditionsToFlot(k, f, d, j);
c = c.concat(l)
}
}
}
return c
},
getFreezelineMarkings: function() {
var d = this.models.weather.get("response.units");
var e = (d == "metric") ? 0 : 32;
var c = [{
yaxis: {
from: e,
to: e
},
color: "#6697cc",
lineWidth: 1
}];
return c
},
getHours: function(d) {
var e = d.observations;
var c = d.hours;
if (e && e.length) {
return e
} else {
if (c && c.length) {
return c
} else {
if (d.summary) {
return [d.summary]
} else {
return null
}
}
}
},
getPlotOptions: function() {
var d = "plots[" + this.options.plotIndex + "]";
var c = this.models.plotGroup.get(d);
return c
},
getTimezone: function() {
return a.getTimezoneFromAPI(this.models.weather)
},
getVariableValue: function(g, h, j, l) {
var d = false;
var f = "";
var i = false;
var m = ["aqozone", "aqpm25", "aqpm10", "aqso2", "aqco", "aqno2"];
i = (j && j.id == h.id);
if (g.hasOwnProperty(h.id)) {
d = true;
f = g[h.id]
}
if (f && (b.inArray(h.id, m) > -1)) {
f = Number.parseFloat(f).toFixed(1)
}
if (d) {
var c = b.isFunction(h.filter);
if (c) {
var k = this.status.get("dayPartsOnly");
var e = h.filter.call(null, g, {
dayPartsOnly: k
});
if (!e) {
d = false
}
}
}
if (d) {
return {
selected: i,
valid: d,
value: f
}
} else {
return null
}
},
getVisibleDataminDatamax: function() {
var E = Number.POSITIVE_INFINITY
, w = Number.NEGATIVE_INFINITY
, g = Number.MAX_VALUE;
var v = this.flot.getData();
var J, G, D;
var O, d, M;
var p = E
, r = w;
var o = this.flot
, I = o.getAxes()
, l = I.xaxis;
var e = l.min
, h = l.max;
var N = this.models.plotGroup.get("bufferLeft");
var u = this.models.plotGroup.get("bufferRight");
if (N || u) {
var c = o.width()
, x = h - e;
var P = N / c
, n = u / c;
e = (e + P * x);
h = (h - n * x)
}
var t = this.status.get("translation");
if (t.x) {
var A = l.c2p(t.x) - l.c2p(0);
e -= A;
h -= A
}
for (J = 0; J < v.length; ++J) {
var y = v[J]
, H = y.datapoints.points
, C = y.datapoints.pointsize
, L = y.datapoints.format;
var z = E
, F = E
, B = w
, K = w;
var k = 0
, q = 0;
for (G = 0; G < L.length; ++G) {
M = L[G];
if (!M) {
continue
}
if (M.x) {
k = G
}
if (M.y) {
q = G
}
}
for (G = 0; G < H.length; G += C) {
if (H[G] == null) {
continue
}
O = H[G + k];
d = H[G + q];
if (d == g || d == -g) {
continue
}
if (O < e || O > h) {
continue
}
if (d < F) {
F = d
}
if (d > K) {
K = d
}
}
if (F < p && F != -g) {
p = F
}
if (K > r && K != g) {
r = K
}
}
if (p == E) {
p = null
}
if (r == w) {
r = null
}
return {
min: p,
max: r
}
},
getWidth: function() {
var d = this.models.plotGroup.get("bufferLeft");
var c = this.models.plotGroup.get("bufferRight");
return this.flot.width() - d - c
},
hideNeedleLabels: function() {
var f = this._needleLabels;
for (var e = 0; e < f.length; e++) {
var d = f[e];
var c = d.node;
c.css("opacity", 0)
}
},
isHeader: function() {
var c = this.flotOptions.datelabel;
return !!(c && c.show)
},
onDayPartsOnlyChange: function(d, c) {
this.checkVariablesEnabled()
},
onTranslateChange: function(c, d) {
this.translate(d)
},
onTransitionChange: function(c, d) {
this.setTransitionDuration(d.duration)
},
onVariableChange: function(c, g) {
var f = {
setupGrid: true
};
this.draw(f);
var e = function() {
this.updateNeedleLabels({
condition: this.status.get("condition"),
day: this.status.get("day"),
mode: this.models.plotGroup.get("mode"),
selectedVariable: null,
timestamp: this.status.get("timestamp")
})
};
var d = _.bind(e, this);
this.fitRangeY(d);
this.setVariablePref(g)
},
onZoomedInChange: function(c, d) {
var e = this.flot.getOptions().datelabel;
if (e) {
e.hourly = !!d
}
},
padRangeY: function(g, d) {
var l = this.getPlotOptions();
var f = g.min
, h = g.max;
var c = d.options
, j = h - f;
var e = 0;
var k = d.box.height;
var i = l.reserveSpace;
if (i && b.isArray(i) && i.length >= 2) {
if (i[0]) {
e = i[0] / k;
f -= j * e;
if (f < 0 && d.datamin != null && d.datamin >= 0) {
f = 0
}
}
if (i[1]) {
e = i[1] / k;
h += j * e;
if (h > 0 && d.datamax != null && d.datamax <= 0) {
h = 0
}
}
}
g.min = f;
g.max = h
},
positionNeedleLabels: function(c) {
c = b.extend({
timestamp: null
}, c);
var d = this.status.get("translation");
this.flot.needle.position({
translation: d,
x: c.timestamp,
y: 0
})
},
render: function() {
return this
},
resize: function() {
this.flot.resize();
this.flot.setupGrid()
},
setFlotData: function(c) {
this.flot.setData(c)
},
setOptions: function(c) {
var d = {
astronomy: {
markings: {
show: false,
dayColor: "transparent",
nightColor: "#f4f4f4"
}
},
flot: {
crosshair: {
mode: "x"
},
grid: {
autoHighlight: false,
borderColor: "#e8e8e9",
borderWidth: 1,
color: "#8e8f91",
hoverable: true
},
series: {
bars: {
show: false
},
lines: {
show: true
},
points: {
show: false
},
images: {
show: false
}
},
xaxis: {
mode: "time"
},
yaxis: {
labelWidth: 30,
panRange: false,
reserveSpace: true,
zoomRange: false
},
yaxes: [{}, {
tickLength: "full",
position: "right"
}]
}
};
this.options = b.extend(true, d, this.options, c);
if (c.date_begin) {
this.options.flot.xaxis.min = c.date_begin.getTime()
}
if (c.date_end) {
this.options.flot.xaxis.max = c.date_end.getTime()
}
},
setPanRange: function(o, e) {
if (!this.flot) {
return
}
if (o || e) {
var c = o;
var i = e;
var m = this.flot.getAxes().xaxis;
var g = this.models.plotGroup.get("bufferLeft");
var k = this.models.plotGroup.get("bufferRight");
if (g || k) {
if (o) {
var j = o.getTime();
var f = m.p2c(j) - g;
j = m.c2p(f);
c = new Date(j)
}
if (e) {
var n = e.getTime();
var l = m.p2c(n) + k;
n = m.c2p(l);
i = new Date(n)
}
}
var d = m.options.panRange;
var h;
if (b.isArray(d) && d.length == 2) {
h = [d[0], d[1]]
} else {
h = [null, null]
}
if (c && b.type(c) == "date" && wui.date.isValid(c)) {
h[0] = c.getTime()
}
if (i && b.type(i) == "date" && wui.date.isValid(i)) {
h[1] = i.getTime()
}
m.options.panRange = h
}
},
setRangeX: function(f, c) {
var d = this.getPlotOptions();
var g = this.flot.getAxes().xaxis;
g.options.min = f;
g.options.max = c;
var e = "plot::setRangeX::draw index:" + this.options.plotIndex;
this.flot.setupGrid();
this.flot.draw()
},
setRangeY: function(d, c) {
var e = this.flot.getAxes().yaxis;
var f = {
min: d,
max: c
};
e.options.min = f.min;
e.options.max = f.max;
this.flot.setupGrid();
this.flot.draw()
},
setTransitionDuration: function(d) {
var c = this.$el.find(".flot-base, .flot-header");
a.setTransitionDuration(c, d)
},
setVariablePref: function(e) {
var d = e.abbrev || e.id;
var c = (e.show !== false);
var f = "CP_VAR_" + d;
var g = c ? 1 : 0;
wui.prefs.set(f, g)
},
translate: function(d) {
var c = this.$el.find(".flot-base, .flot-header");
a.translate(c, d)
},
updateNeedleLabels: function(m) {
m = b.extend({
condition: null,
day: null,
mode: "forecast",
selectedVariable: null,
timestamp: null,
top: null,
value: ""
}, m);
if (!this.flot.needle) {
return
}
if (m.timestamp === null) {
return
}
var q = this.getPlotOptions();
var f = q.variables;
var w = this.models.plotGroup.get("classNames");
var v = this._needleLabels;
var u = [];
var c = 17;
var y = (m.mode == "forecast");
var e = this.flot.getPlotOffset();
var j = this.flot.getYAxes()
, t = null;
for (var s = 0; s < v.length; s++) {
var h = v[s];
var r = null;
var l = h.variableIndex;
if (l || l === 0) {
r = f[l]
}
var z = h.node;
if (r && (r.show === false || r.enabled === false || r.needle === false)) {
z.css("opacity", 0);
continue
}
var p = "";
var d = "";
var k = "";
var o = false;
if (m.value) {
p = m.value
} else {
if (!r) {
p = m.value
} else {
var x = this.getVariableValue(m.condition, r, m.selectedVariable, y);
if (!x || !x.valid) {
z.css("opacity", 0);
continue
}
p = x.value;
d = "";
k = a.getVariableUnits(r, m.condition, m.day);
o = x.selected
}
}
if (p === null) {
z.css("opacity", 0);
continue
}
z.css("opacity", 1);
u.push(h);
var n = 0;
if (m.top || m.top === 0 || !r) {
n = m.top
} else {
if (r.options && r.options.yaxis > 0) {
t = j[r.options.yaxis - 1]
} else {
t = j[0]
}
n = t.p2c(p) + e.top - c;
if (n < 0) {
n = 0
}
}
h.top = n;
d = p + k;
z.html(d)
}
u.sort(function(A, i) {
return A.top - i.top
});
var g = [];
for (var s = 0; s < u.length; s++) {
var h = u[s];
var n = h.top;
if (g.length && n < g[g.length - 1] + c) {
n = g[g.length - 1] + c;
h.top = n;
g = [];
g.push(n)
} else {
g = [];
g.push(n)
}
}
for (var s = 0; s < u.length; s++) {
var h = u[s];
var z = h.node;
a.translate(z, {
y: h.top
})
}
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.PlotLegend = Backbone.View.extend({
initialize: function(d) {
this.options = d || {};
this.models = this.options.models || {};
var c = b("script#plotgroup-legend-template");
if (!c[0]) {
console.error("missing required PlotLegend template");
return
}
this.template = _.template(c.html());
var e = "plots[" + this.options.plotIndex + "]";
this.listenTo(this.models.plotGroup, "change:" + e + ".variables", this.onVariablesChange);
var f = this.models.plotGroup.get("classNames");
this.$el.addClass(f.legend);
this.render()
},
onVariablesChange: function(c, d) {
this.render({
variables: d
})
},
render: function(f) {
var i;
var e = "";
if (f && f.variables) {
i = f.variables
} else {
var d = "plots[" + this.options.plotIndex + "]";
i = this.models.plotGroup.get(d + ".variables")
}
var h = !!(i && i.length);
if (h && this.models.weather) {
var g = this.models.weather.get("forecast.source");
if (g == "nws") {
i = _.reject(i, function(j) {
return j.missingFromNWS
})
}
}
h = !!(i && i.length);
if (h) {
var c = {
variables: i
};
e = this.template(c)
}
this.$el.html(e);
this.$el.toggle(h);
return this
},
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.PlotVariablesMenu = Backbone.View.extend({
events: {
click: "onClick",
opened: "onDropdownOpened",
closed: "onDropdownClosed"
},
initialize: function(c) {
this.options = c || {};
this.models = this.options.models || {};
this.template = _.template(b("script#plotgroup-variables-menu-template").html());
this.listenTo(this.models.plotGroup, "change:plots", this.onVariablesChange);
this.listenTo(this.models.plotGroup, "change:editMode", this.onEditMode);
this.render()
},
onClick: function(e) {
var c = b(e.target);
var f = this.models.plotGroup.get("editMode");
if (c.is(this.$editDone)) {
this.models.plotGroup.set("editMode", false)
} else {
if (c.is("input[type=checkbox]")) {
var d = c[0].checked;
var g = c.attr("data-variable-id");
if (f) {
this.toggleVariable(g, d)
}
}
}
if (!f) {
e.preventDefault()
}
},
onDropdownOpened: function(c) {
this.models.plotGroup.set("editMode", true)
},
onDropdownClosed: function(c) {
this.models.plotGroup.set("editMode", false)
},
onEditMode: function(c, d) {},
render: function(e) {
var c = {
forecastSource: this.models.weather.get("forecast.source"),
plots: this.models.plotGroup.get("plots")
};
var d = this.template(c);
this.$el.html(d);
var f = this.models.plotGroup.get("editMode");
return this
},
toggleVariable: function(k, c) {
var g = this.models.plotGroup.get("plots");
for (var f = 0; f < g.length; f++) {
var h = g[f].variables;
for (var d = 0; d < h.length; d++) {
if (h[d].id == k) {
var e = "plots[" + f + "].variables[" + d + "]";
this.models.plotGroup.set(e + ".show", c)
}
}
}
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.Extended = Backbone.View.extend({
events: {
"click .fct3-toggle-hide": "onClickHideFct3",
"click .fct3-toggle-show": "onClickShowFct3"
},
initialize: function(c) {
this.options = c || {};
this.weather = this.options.weather;
if (b("#extended-template").length > 0) {
this.template = _.template(b("script#extended-template").html());
this.listenTo(this.weather, "change:forecast", this.render);
if (this.options.render && this.weather.attributes.forecast) {
this.render()
}
}
},
onClickHideFct3: function(c) {
c.preventDefault();
this.toggleFct3(false)
},
onClickShowFct3: function(c) {
c.preventDefault();
this.toggleFct3(true)
},
render: function(g, i) {
var d = {
labels: this.weather.attributes.labels,
weather: this.weather.attributes
};
var e = this.weather.get("response");
d.showPrecipDay = false;
d.showPrecipNight = false;
if (e && e.date) {
var c = e.date.hour;
if (c >= 1 && c < 19) {
d.showPrecipDay = true
}
if (c >= 13) {
d.showPrecipNight = true
}
}
var f = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : "";
if (f && e.location) {
f += a.generateCityQuery({
zip: e.location.zip,
magic: e.location.magic,
wmo: e.location.wmo,
country: e.location.country_iso3166
})
}
d.cityUrl = f;
var h = this.template(d);
this.$el.html(h);
this.checkStorm();
return this
},
toggleFct3: function(c) {
var d = this.model.get("classNames");
this.$el.toggleClass(d.open, !!c)
},
checkStorm: function() {
if (wui.bootstrapped.citypage) {
var e = wui.bootstrapped.citypage.storm;
for (var d in e) {
var c = "div#fctDay-" + d;
var f = "has-alert";
if (e[d].type === "blizzard") {
f += " has-blizzard"
}
if (b(c).length) {
b(c).addClass(f)
}
}
}
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.PhotoSlideshow = Backbone.View.extend({
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
if (this.options.render) {
this.initializeLater()
}
},
initializeLater: function() {
this.template = _.template(a("script#photo-slideshow-template").html());
this.render()
},
getPhotos: function() {
var b = this.options.photos || [];
return b
},
render: function() {
var c = {
photos: this.getPhotos()
};
var b = this.template(c);
this.$el.find(".slideshow").html(b);
a(document).ready(function() {
a(".bxslider").bxSlider({
captions: true
})
});
return this
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.Share = Backbone.View.extend({
events: {
"click #shareButton": "onClickButton",
"click .share-icons #socialTwitter": "onClickTwitter",
"click .share-icons #socialFacebook": "onClickFacebook",
"click .share-icons #socialGoogle": "onClickGoogle",
"click .share-icons #socialReddit": "onClickReddit",
"click .share-icons #socialMail": "onClickMail",
"click #radioForm #fullLinkRadio": "onClickFullLink",
"click #radioForm #shortLinkRadio": "onClickShortLink"
},
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
this._opened = false;
this.urls = new Backbone.Model({
full: null,
mini: null
});
this.templateButtons = _.template(a("script#share-buttons-template").html());
this.templatePanel = _.template(a("script#share-panel-template").html());
if (this.options.render) {
this.render()
}
},
initializeAtFirstOpen: function() {
this.listenTo(this.urls, "change", this.renderURL)
},
getURL: function() {
var b = "";
var c = this.$el.find("#shortLinkRadio");
if (c.is(":checked")) {
b = this.urls.get("mini")
}
if (!b) {
b = this.urls.get("full")
}
return b
},
getFullURL: function() {
var b = "";
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
if (wui.bootstrapped.share.url) {
b = wui.bootstrapped.share.url
}
}
if (!b) {
b = a('meta[property="og:url"]').attr("content")
}
if (!b) {
b = a("link[rel=canonical]").attr("href")
}
if (!b) {
b = window.location.toString()
}
b = b.trim();
return b
},
getTitle: function() {
var b = "";
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
if (wui.bootstrapped.share.title) {
b = wui.bootstrapped.share.title
}
}
if (!b) {
b = a('meta[property="og:title"]').attr("content")
}
if (!b) {
b = document.title
}
b = b.trim();
return b
},
getDescription: function() {
var b = "";
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
if (wui.bootstrapped.share.description) {
b = wui.bootstrapped.share.description
}
}
if (!b) {
b = a('meta[property="og:description"]').attr("content")
}
if (!b) {
b = a('meta[name="description"]').attr("content")
}
b = b.trim();
return b
},
getImage: function() {
var b = "";
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
if (wui.bootstrapped.share.image) {
b = wui.bootstrapped.share.image
}
}
if (!b) {
b = a('meta[property="og:image"]').attr("content")
}
if (!b) {
b = "//icons.wxug.com/i/o/logo-footer.png"
}
b = b.trim();
return b
},
loadScripts: function() {
window.___gcfg = {
lang: "en-US"
};
(function() {
var b = document.createElement("script");
b.type = "text/javascript";
b.async = true;
b.src = "https://apis.google.com/js/plusone.js";
var c = document.getElementsByTagName("script")[0];
c.parentNode.insertBefore(b, c)
})();
window.fbAsyncInit = function() {
FB.init({
appId: wui.facebook.app_id,
channelUrl: wui.facebook.channel_url,
status: true,
cookie: true,
xfbml: true,
version: "v2.0"
});
wui.facebook.on_load_trigger()
}
;
(function(e) {
var c, f = "facebook-jssdk", b = e.getElementsByTagName("script")[0];
if (e.getElementById(f)) {
return
}
c = e.createElement("script");
c.id = f;
c.async = true;
c.src = "//connect.facebook.net/en_US/sdk.js";
b.parentNode.insertBefore(c, b)
}(document))
},
onClickButton: function(b) {
if (!this._opened) {
this.initializeAtFirstOpen();
this.renderPanel()
}
this._opened = true;
this.renderURL();
this.updateMiniURL()
},
onClickFullLink: function(b) {
this.updateFullURL();
this.renderURL()
},
onClickShortLink: function(b) {
this.updateMiniURL();
this.renderURL()
},
onClickFacebook: function(d) {
d.preventDefault();
var b = this.getFullURL();
var c = null;
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
c = wui.bootstrapped.share
}
if (wui && wui.bootstrapped && (wui.bootstrapped.pageType == "CityPage")) {
facebook_share_forecast(b, c.image, c.now, c.temp_now, c.high_now, c.low_now, c.tonight, c.high_tonight, c.low_tonight, c.tomorrow, c.high_tomorrow, c.low_tomorrow, c.loc)
} else {
c = {
title: this.getTitle(),
description: this.getDescription(),
image: this.getImage()
};
facebook_share_page(c.title, b, c.description, c.image)
}
},
onClickGoogle: function(c) {
c.preventDefault();
var b = this.getURL();
window.open("https://plus.google.com/share?url=" + encodeURIComponent(b), "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600")
},
onClickMail: function(c) {
c.preventDefault();
var b = this.getURL();
var d = this.getTitle();
window.open("mailto:?subject=Check this out on Weather Underground&body=" + encodeURIComponent(d) + "%20%20%0d" + b, "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600")
},
onClickTwitter: function(f) {
f.preventDefault();
var d = "";
var e = null;
var c = this.getURL();
if (wui && wui.bootstrapped && wui.bootstrapped.share) {
e = wui.bootstrapped.share
}
if (e && e.content) {
d = e.content
} else {
if (e && e.content_template) {
var b = {};
if (this.models.weather) {
b.weather = this.models.weather.attributes;
b.labels = b.weather.labels
}
d = _.template(e.content_template, b)
} else {
d = this.getTitle()
}
}
var g = {
related: "wunderground",
text: d,
url: c,
via: "wunderground"
};
if (e && e.via) {
g.via = e.via
}
window.open("http://twitter.com/share?" + a.param(g), "twitterwindow", "menubar=1,resizable=0,width=550,height=368")
},
onClickReddit: function(c) {
c.preventDefault();
var b = this.getURL();
window.open("http://www.reddit.com/submit?url=" + encodeURIComponent(b), "redditwindow", "menubar=1,resizable=0,width=750,height=500")
},
render: function() {
this.loadScripts();
var b = this.templateButtons();
this.$el.find("#shareButtons").html(b);
return this
},
renderPanel: function() {
var b = this.templatePanel();
this.$el.find("#sharePanel").html(b);
return this
},
renderURL: function() {
var b = this.getURL();
this.$el.find("#urlInput").val(b)
},
requestMiniURL: function() {
var b = this.updateFullURL({
silent: true
});
var c = a.ajax({
url: "/miniurl/api.php?url=" + encodeURIComponent(b)
});
return c
},
updateFullURL: function(c) {
var b = this.getFullURL();
this.urls.set("full", b, c);
return b
},
updateMiniURL: function() {
var b = this;
var c = this.requestMiniURL();
c.done(function(d, e) {
b.urls.set("mini", d)
}).fail(function() {
b.urls.set("mini", "")
});
return c
}
})
})(jQuery);
(function(a) {
var b = "https://www.wunderground.com";
if (window.location.host && window.location.host.indexOf("www") === -1) {
b = ""
}
if (!window.Backbone) {
return
}
wui.Views.MembershipForm = Backbone.View.extend({
events: {
"change #show-password": "showPassword",
"change #gift-code": "showGiftField",
"keydown #sign-up-form input": "debouncedChangeStatus",
"blur #sign-up-form input": "immediateChangeStatus",
"click .submit-button": "setMembershipType",
"change #terms": "setCheckedStatus",
"submit #sign-up-form": "submitSignUpForm",
"submit #sign-in-form": "submitSignInForm",
"click .gift-label-wrap": "disableLabelClick",
"submit #user-delete-form": "submitDeleteForm",
"click .cancel-delete-btn": "closeDeleteForm"
},
initialize: function() {
this.validators = this.validatorFunctions();
this.usedGiftCode = false;
this.views = {};
this.$premiumBtn = a("#noads-submit");
this.$basicBtn = a("#basic-submit");
var c = wui.getParameterByName("giftcode");
if (c) {
setTimeout(function() {
a("#gift-code").trigger("click");
a("#register-gift").val(c).trigger("blur")
}, 0)
}
this.debouncedChangeStatus = _.debounce(this.changeStatus, 250)
},
changeStatus: function(k, d) {
var l = k.target;
var c = a(l);
var m = c.val();
var h = c.parent();
var f = c.data("previousValue");
var i = this;
var g = 2500;
if (c.attr("name") === "giftcode") {
g = 1000
}
if (c.attr("type") === "checkbox" || c.attr("type") === "submit") {
return false
}
if (this.wait && !d) {
clearTimeout(this.wait)
}
if (!d) {
this.wait = setTimeout(j, g)
} else {
j()
}
function j() {
if (!d) {
if (!i.wait) {
return
}
i.wait = null
}
if (f !== m) {
c.data("previousValue", m);
if (c.val()) {
c.data("used", true)
}
if (c.data("used")) {
i.runValidator(c.attr("name"), m, h)
}
}
}
},
immediateChangeStatus: function(c) {
this.changeStatus(c, true)
},
checkIfExists: function(d, f, c) {
var h = this;
var c = typeof c !== "undefined" ? c : a("#sign-up-form").find('input[name="' + d + '"]');
var e = {};
var g = c.parent();
e[d] = f;
this.checkIfExistsDone = function(i) {
if (i && i.member) {
var k;
var j = i.status === "success" && _.isNull(i.member.members);
if (!_.isNull(i.member.members)) {
k = "Already in use."
}
if (i.errors && i.errors.length) {
k = i.errors[0].error_string
}
h.setStatus(g, j, k)
}
}
;
g.find(".input-status").addClass("loading");
return a.ajax(b + "/member/info/", {
data: e,
dataType: "json"
}).done(h.checkIfExistsDone)
},
checkIfGiftCodeExists: function(d) {
var f = this;
var c = a("#register-gift");
var e = c.parent();
if (!d) {
return a.Deferred()
}
e.find(".input-status").addClass("loading");
return a.ajax(b + "/member/validgiftcode", {
data: {
giftcode: d
},
dataType: "json"
}).done(function(g) {
if (!a("#gift-code").is(":checked")) {
f.resetStatus(a("#register-gift").parent());
return false
}
if (g && g.status === "success" && g.giftcode) {
if (g.giftcode.status === "success") {
f.setStatus(e, true);
f.giftCodeSuccess(g.giftcode)
} else {
if (!a("#gift-success").is(":visible")) {
f.checkErrors(g.giftcode.errors, e)
} else {
e.find(".input-status").removeClass("loading")
}
}
}
})
},
disableLabelClick: function(d) {
var c = a(d.currentTarget);
if ((c.find("input").is(":visible") || a("#gift-success").is(":visible")) && d.target !== d.currentTarget) {
return false
}
},
activateButton: function(c) {
c.parent().removeClass("disabled");
c.removeClass("disabled")
},
deactivateButton: function(c) {
c.parent().addClass("disabled");
c.addClass("disabled")
},
giftCodeSuccess: function(d) {
if (d) {
var g = d.expire_epoch * 1000 - new Date();
var c = Math.round(wui.date.millisecondsToUnit(g, "month"));
var e = "month" + (c !== 1 ? "s" : "");
var f = d.mobile_gift_code ? "gift-code-mobile" : "gift-code-premium";
this.giftCodeDuration = c + " " + e;
this.isMobileGiftCode = d.mobile_gift_code;
this.$el.find(".gift-code-duration").show().find(".duration").text(this.giftCodeDuration).end().find("." + f).removeClass("hide");
a("#register-gift").addClass("hide");
a(".gift-input-status").html("");
if (!d.mobile_gift_code) {
a("#noads-submit").val("Premium - Free");
this.deactivateButton(this.$basicBtn)
}
}
},
resetGiftCode: function() {
a("#noads-submit").val("Premium - $10/yr");
this.$el.find(".gift-code-duration").hide();
this.$el.find(".gift-code-mobile").addClass("hide");
this.$el.find(".gift-code-premium").addClass("hide");
a("#register-gift").data("previousValue", "");
this.activateButton(this.$basicBtn)
},
setCheckedStatus: function(d) {
var c = a(d.target);
c.data("valid", c.is(":checked"))
},
setInputStatus: function(e, g, f) {
var d = e.find(".input-status");
var c = "status-icon fi-" + (g ? "check" : "x");
d.removeClass("loading");
if (!f) {
d.html('<i class="' + c + '" />')
} else {
d.html("")
}
},
setMembershipType: function(d) {
var c = a(d.target).attr("name");
a("#membership-type").val(c)
},
setStatus: function(c, e, d) {
d = !e ? d : "";
c.find("input").data("valid", e);
this.setInputStatus(c, e);
this.setStatusMessage(c, d)
},
resetStatus: function(c) {
c.find("input").removeData("valid");
this.setInputStatus(c, true, true);
this.setStatusMessage(c, "")
},
setStatusMessage: function(c, d) {
c.find(".status-message").text(d)
},
showPassword: function(i) {
var c = a("#register-password");
var l = a("#register-password-text");
var j = i.target;
var d = a(j);
var h = a(".password-state");
var f = j.checked ? c : l;
var k = j.checked ? l : c;
var m = f.val();
var g = f.data();
h.text(j.checked ? "Hide" : "Show");
f.hide();
k.val(m).show()
},
showGiftField: function(f) {
var d = f.target;
var c = a(d);
if (!d.checked) {
this.resetStatus(c.parent());
this.resetGiftCode()
}
},
submitSignInForm: function(f) {
var d = {
email: a("#sign-in-email").val(),
password: a("#sign-in-password").val()
};
var g = this;
var c = a(f.target);
this.updateSignInSubmitButton();
a.ajax({
url: b + c.attr("action"),
data: d,
dataType: "json",
type: c.attr("method"),
xhrFields: {
withCredentials: true
}
}).done(function(h) {
var e = h.status;
var i = h.errors;
if (e === "success") {
g.resetStatus(c);
if (a("#wu-registration").length) {
if (a("#sign-in-form #redirect_url").val().length) {
location.href = a("#sign-in-form #redirect_url").val();
window.location.reload()
} else {
window.location.reload()
}
} else {
window.location.href = document.referrer || "/"
}
} else {
if (i) {
g.checkErrors(i, a("#sign-in-form"));
g.updateSignInSubmitButton()
} else {}
}
});
return false
},
closeDeleteForm: function(c) {
a("#user-delete").foundation("reveal", "close")
},
submitDeleteForm: function(f) {
var d = {
password: a("#delete-password").val()
};
var g = this;
var c = a(f.target);
this.updateDeleteSubmitButton();
a.ajax({
url: b + c.attr("action"),
data: d,
dataType: "json",
type: c.attr("method"),
xhrFields: {
withCredentials: true
}
}).done(function(h) {
var e = h.status;
var i = h.errors;
if (e === "success") {
g.resetStatus(c);
if (a("#user-delete").length) {
if (a("#user-delete-form #redirect_url").val().length) {
location.href = a("#user-delete-form #redirect_url").val();
window.location.reload()
} else {
window.location.reload()
}
} else {
window.location.href = document.referrer || "/"
}
} else {
if (i) {
g.checkErrors(i, a("#user-delete-form"));
g.updateDeleteSubmitButton()
} else {}
}
});
return false
},
checkErrors: function(g, f) {
if (g && g.length) {
for (var e = 0; e < g.length; e++) {
var c = g[e];
var d = f.find('input[name="' + c.field_name + '"]').parent();
this.setStatus(d, false, c.error_string)
}
}
},
submitSignUpForm: function(h) {
var f = a("#membership-type").val() === "noads" ? this.$premiumBtn : this.$basicBtn;
if (f.hasClass("disabled")) {
return false
}
var g = {
email: a("#register-email").val(),
handle: a("#register-handle").val(),
password: a("#register-password").val() || a("#register-password-text").val(),
tos: a("#terms").is(":checked"),
optin: a("#optin").is(":checked"),
signupmode: "web_signup",
signup_ref: document.referrer
};
var d = a(h.target);
var i = this;
var c = a("#register-gift").val();
if (c.length) {
g.giftcode = c
}
if (!c.length || this.isMobileGiftCode) {
g.noads = a("#membership-type").val() === "noads"
}
this.updateSignUpSubmitButton(f, true);
this.submitDone = function(j) {
var e = j.status;
var l = j.errors || [];
var k = j.giftcode && j.giftcode.errors ? j.giftcode.errors : [];
if (e) {
if (e === "error" || k.length) {
l = l.concat(k);
i.checkErrors(l, a("#sign-up-form"));
i.updateSignUpSubmitButton(f)
} else {
if (e === "success") {
if ((g.noads && _.isNull(j.giftcode)) || this.isMobileGiftCode) {
i.directToPayment(g.email)
} else {
i.renderAlmostView(g)
}
}
}
}
}
;
a.ajax({
url: b + d.attr("action"),
data: g,
dataType: "json",
type: d.attr("method"),
xhrFields: {
withCredentials: true
}
}).done(i.submitDone).fail(function(e) {
i.updateSignUpSubmitButton(f)
});
return false
},
renderAlmostView: function(e) {
var c = a("#wu-registration").length ? window.location.href : document.referrer || "/";
if (c.indexOf("wunderground") < 0) {
c = "//www.wunderground.com"
}
var d = "newmember=";
if (c.indexOf(d) === -1) {
c += (c.indexOf("?") === -1 ? "?" : "&") + d + "1"
}
if (a("#sign-up-form #redirect_url").val().length) {
window.location.href = a("#sign-up-form #redirect_url").val();
window.location.reload()
} else {
window.location.href = c
}
},
render: function() {
return this
},
runValidator: function(d, g, f) {
var e = this.validators[d];
if (typeof e !== "undefined") {
var c = e.check(g);
if (!a.isFunction(c.done)) {
this.setStatus(f, c.valid, c.message);
return c.valid
} else {
return c
}
}
},
updateDeleteSubmitButton: function() {
var d = a("#delete-btn");
var c = d.val();
d.val(d.data("alt-action"));
d.data("alt-action", c);
d.toggleClass("disabled")
},
updateSignInSubmitButton: function() {
var d = a("#sign-in-btn");
var c = d.val();
d.val(d.data("alt-action"));
d.data("alt-action", c);
d.toggleClass("disabled")
},
updateSignUpSubmitButton: function(d, e) {
var c = d.val();
d.val(d.data("alt-action"));
d.data("alt-action", c);
d.siblings(".submit-status").toggleClass("loading");
if (e) {
this.$premiumBtn.addClass("disabled");
this.$basicBtn.addClass("disabled")
} else {
this.$premiumBtn.toggleClass("disabled");
this.$basicBtn.toggleClass("disabled")
}
},
directToPayment: function(c) {
a(".payment-form").find('input[name="os0"]').val(c);
a(".payment-form").submit()
},
validatorFunctions: function() {
var c = this;
return {
email: {
check: function(f) {
var d = /^[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])?)*$/;
var e = d.test(f);
if (!e) {
return {
valid: e,
message: !e ? "Email is invalid." : ""
}
} else {
this.done = function() {}
;
return c.checkIfExists("email", f)
}
}
},
handle: {
check: function(f) {
var d = /^[a-zA-Z0-9]{1,20}$/;
var e = d.test(f);
if (!e) {
return {
valid: e,
message: !e ? "Letters and numbers only, please." : ""
}
} else {
this.done = function() {}
;
return c.checkIfExists("handle", f)
}
}
},
giftcode: {
check: function(d) {
return c.checkIfGiftCodeExists(d)
}
},
password: {
check: function(e) {
var d = (e.length >= 5 && e.length <= 30);
return {
valid: d,
message: !d ? "Must be 5 to 30 characters." : ""
}
}
},
tos: {
check: function(e) {
var d = e === "on" ? true : false;
return {
valid: d,
message: !d ? "Required." : ""
}
}
}
}
}
})
})(jQuery);
(function(a) {
var b = "https://www.wunderground.com";
if (!window.Backbone) {
return
}
wui.Views.MembershipAlmost = Backbone.View.extend({
events: {},
initialize: function(c) {
this.options = c
},
addParam: function(c, d) {
if (location.search.length) {
return c + "&" + d
}
return c + "?" + d
},
checkValidation: function() {
var g = this;
if (!this.options.email) {
return false
}
var d = 2500;
var f = 300000;
var c = 0;
var e = setInterval(function() {
a.ajax(b + "/member/info/", {
data: {
email: g.options.email
},
dataType: "json",
cache: false
}).done(function(h) {
var j = h.member;
if (h && h.status === "success" && j.members && j.members.length) {
var i = j.members[0].account_valid === "valid";
if (i) {
window.location.href = g.addParam(window.location.href, "membervalidated=1");
clearTimeout(e)
}
}
c++;
if (c >= f / d) {
clearTimeout(e)
}
})
}, d);
a(document).on("closed.fndtn.reveal", "[data-reveal]", function() {
clearTimeout(e)
})
},
render: function() {
return this
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.Videos = Backbone.View.extend({
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
if (this.options.render) {
this.initializeLater()
}
},
initializeLater: function() {
var b = this.options.videos;
var c = this.$el.find("#videoImage");
a.ajax({
url: "//dsx.weather.com/cms/orderedlist/video/pl-wunderground-top-stories",
dataType: "jsonp",
jsonp: "jsonp",
success: function(i, k, h) {
var e = i.body;
if (e && e.length) {
var g = e[0];
var d = g.variants[9];
var j = g.title;
var f = '<div><a href="/video?video=' + g.source_guid + "\" onclick=\"_gaq.push(['_trackEvent', 'Meat TDU', 'Click'," + b.title + ']);" id="video-tdu-link"><img src="' + d + '" alt="' + g.title + '" /><span><img src="' + b.play_icon + '" alt="Play"></span><div class="content"><h4 class="video-caption">' + j + "</h4></div></a></div>";
c.append(f)
}
}
})
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.HPTileVideos = Backbone.View.extend({
initialize: function(b) {
this.options = b || {};
this.render()
},
render: function() {
var b = this.$el;
a.ajax({
url: "//dsx.weather.com/cms/orderedlist/video/pl-wunderground-top-stories",
dataType: "jsonp",
jsonp: "jsonp",
success: function(g, h, f) {
if (g && g.body && g.body.length) {
var e = g.body[0];
var c = e.variants[8];
var d = '<a href="/video/top-stories/?cm_ven=topstories_hptile&video=' + e.source_guid + '"><div class="row collapse has-playbtn"><div class="columns small-5 medium-12 large-12 cta-news"><div class="cta-image"><img src="' + c + '" title="' + e.title + '" /><span><img src="//icons.wxug.com/graphics/playBtn.png" alt="Play"></span></div></div><div class="columns small-7 medium-12 large-12"><h3>' + e.title + "</h3></div></div></a>";
b.append(d)
}
}
})
}
})
})(jQuery);
(function(b) {
if (!window.Backbone) {
return
}
var a = wui.backbone.utils;
wui.Views.Wundermap = Backbone.View.extend({
events: {},
initialize: function(c) {
this.options = c || {};
this.models = this.options.models || {};
if (!this.models.wundermap) {
console.error("missing required model `wundermap` in this.models");
return
}
if (this.options.render) {
this.initializeLater()
}
},
initializeLater: function() {
this.viewLoaded = b.Deferred();
var c = this;
var d = wui.usher.loadScript("googlemaps");
d.done(function() {
c.continueInit()
})
},
continueInit: function() {
var e = {
zoom: this.models.wundermap.get("zoom"),
minZoom: this.models.wundermap.get("minZoom"),
maxZoom: this.models.wundermap.get("maxZoom"),
center: this.models.wundermap.get("center"),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: this.models.wundermap.get("mapTypeControl")
};
var h = ["RADAR", "SAT", "WEBCAM"];
var d = this.options.layer;
this.tabindex = _.indexOf(h, d[0]);
if (this.tabindex < 0) {
this.tabindex = 0
}
e.layer = h[this.tabindex];
this.template = _.template(b("script#wundermap_template").html(), null, {
variable: "data"
});
this.templateWebcam = _.template(b("script#webcam_modal_template").html());
var c = this.template(e);
this.$el.find(".map-ui").html(c);
this.initGoogleMap();
var f = this;
var g = wui.usher.loadScript("wundermap");
g.done(function() {
f.finishInit()
})
},
finishInit: function() {
this.render();
wundermap.layers.Webcams.onClick = b.proxy(this.openWebcamModal, this);
wundermap.getLinkToThisPage = function(e) {
var d = "/wundermap/?" + this.toQueryString(e);
return d
}
;
var c = this.$tabs = this.$el.find("#wundermap_module_header");
c.tabs({
active: this.tabindex
});
google.maps.event.addListener(wundermap, "layertoggled", b.proxy(this.onLayerToggled, this));
this.viewLoaded.resolve()
},
openWebcamModal: function(g, f) {
var c = g.ICONS[0];
var e = {
city: c.city,
state: c.state,
country: c.country,
neighborhood: c.neighborhood,
image_url: "//icons.wxug.com/" + c.image,
handle: c.handle,
camindex: c.camindex,
link: "/webcams/" + c.handle + "/" + c.camindex + "/show.html"
};
var d = this.templateWebcam({
webcam: e
});
b("#webcamModal").html(d);
b("#webcamModal").foundation("reveal", "open")
},
checkEnticements: function() {
var c = this.activeTab();
if (this.last_tab_with_enticement == c) {
return
}
var f = this.models.wundermap.get("enticement");
var e = this.$el.find(".enticements");
var d = this.$enticements.filter(".enticement-" + f);
if (d[0]) {
this.$enticements.hide();
d.show();
e.slideDown();
this.last_tab_with_enticement = c
} else {
e.hide()
}
},
initEnticements: function() {
var g = this;
var f = this.models.wundermap.get("gmap");
this.$enticements = this.$el.find(".enticements .enticement");
this.checkEnticements();
this.$enticements.find("a").attr("target", "_blank");
this.listenTo(this.models.wundermap, "change:enticement", this.onChangeEnticement);
var e = 0;
google.maps.event.addListener(f, "idle", function() {
e++;
if (e <= 1) {
return
}
g.showEnticement("panzoom")
});
google.maps.event.addListener(wundermap, "layertoggled", function(k, j) {
g.showEnticement("layers")
});
var c = wundermap.layers.Radar;
var d = wundermap.layers.Satellite;
var i = c.getPrefs().num;
var h = d.getPrefs().num;
google.maps.event.addListener(c, "settings_changed", function() {
var j = c.getPrefs().num;
if (i !== j) {
i = j;
g.showEnticement("animation")
}
});
google.maps.event.addListener(d, "settings_changed", function() {
var j = d.getPrefs().num;
if (h !== j) {
h = j;
g.showEnticement("animation")
}
})
},
initGoogleMap: function() {
var f = this.models.wundermap.get("lat");
var h = this.models.wundermap.get("lon");
var g = this.models.wundermap.get("gMapType");
var e = this.models.wundermap.get("gMapUnits");
var c = true;
if (b(window).width() <= 640) {
c = false
}
var d = new google.maps.Map(this.$(".map")[0],{
center: new google.maps.LatLng(f,h),
zoom: this.models.wundermap.get("zoom"),
mapTypeId: "lightmap",
mapTypeControl: false,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
disableDefaultUI: true,
draggable: c,
scrollwheel: false,
streetViewControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
}
});
this.models.wundermap.set("gmap", d)
},
onChangeEnticement: function(c, d) {
this.checkEnticements()
},
onLayerToggled: function(g, e) {
var c = wundermap.layers.Radar;
var f = wundermap.layers.Satellite;
b("#radar_animate_button").toggle(c.active_);
b("#sat_animate_button").toggle(f.active_);
var h = "";
var d = {
Radar: "RADAR",
Satellite: "SAT",
Webcams: "WEBCAM"
};
h = d[g];
if (e) {
if (h === "WEBCAM") {
wui.prefs.set("RADARBOX_WEBCAM", h)
} else {
wui.prefs.set("RADARBOX", h)
}
} else {
if (h === "WEBCAM") {
wui.prefs.set("RADARBOX_WEBCAM", "")
}
}
},
recenter: function() {
var c = this.models.wundermap.get("gmap");
if (!google) {
console.log("nooo google");
return
}
google.maps.event.addDomListener(window, "resize", function() {
var d = c.getCenter();
google.maps.event.trigger(c, "resize");
c.setCenter(d)
})
},
render: function() {
this.setLayers();
wundermap.initialize();
this.recenter();
return this
},
setLayers: function() {
var g = this.models.wundermap.get("gMapUnits");
var c = this.models.wundermap.get("gmap");
var e = this.options.layer || "RADAR";
var d = null;
var f;
if (wui.bootstrapped.citypage) {
d = wui.bootstrapped.citypage.storm ? 1 : 0;
f = wui.bootstrapped.citypage.tzname
}
if (c && wundermap) {
wundermap.date = new Date();
wundermap.setOptions({
map: c,
refreshPeriod: 60000,
customMapTypes: true,
units: g,
layers: [{
layer: "Radar",
active: (e[0] === "RADAR"),
timelabel: 1,
timelabelX_offset: 163,
timelabelY_offset: 22,
tzname: f,
defaultUI: 0,
opacity: 75,
useTiles: false,
type: "00Q",
type2: "",
smooth: 1,
animation: {
num: 10,
delay: 50
}
}, {
layer: "Satellite",
active: (e[0] === "SAT"),
timelabel: 1,
timelabelX_offset: 176,
timelabelY_offset: 22,
tzname: f,
opacity: 60,
animation: {
num: 4,
delay: 50
}
}, {
layer: "Webcams",
active: (e[1] === "WEBCAM")
}, {
layer: "Hurricane",
active: d
}],
linkToThisPage: {
rawlink: this.$el.find("A.wundermap-link")
}
})
}
},
activeTab: function() {
return wundermap.layers.Radar.active_ ? "radar" : (wundermap.layers.Satellite.active_ ? "satellite" : "webcams")
},
showEnticement: function(c) {
this.models.wundermap.set("enticement", c + "-" + this.activeTab())
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Models.Survey = Backbone.Model.extend({
initialize: function(b, c) {
this.cookie_name = "wu-survey-campaign-" + b.campaign + "-is-available";
this.cookie_promise = wui.usher.loadScript("jquery-cookie")
},
close: function() {
var b = this;
this.cookie_promise.done(function() {
a.cookie(b.cookie_name, "false", {
expires: 7,
path: "/"
})
});
return this
},
when_available: function(d) {
var b = this
, c = function() {
return a.cookie(b.cookie_name) != "false"
};
this.cookie_promise.done(function() {
if (c()) {
d.apply()
}
});
return this
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.SurveyPrompt = Backbone.View.extend({
events: {
"click .alert-box-close": "onSurveyPromptClose"
},
initialize: function(b) {
this.survey = b.survey;
this.template = _.template('<p class="alert-box-prompt"><%= prompt %></p><a class="alert-box-close-button modal-close alert-box-close">&#215;</a>');
this.constructTemplate()
},
constructTemplate: function() {
var b = this.template({
prompt: this.survey.get("prompt")
});
this.$el.html(b)
},
render: function() {
this.constructTemplate();
return this
},
onSurveyPromptClose: function(b) {
this.survey.close()
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.AlertBar = Backbone.View.extend({
events: {
"click .alert-box-close": "onClose"
},
id: "header-alert",
initialize: function(b) {
this.alert_view = b.alert;
this.$el.append(this.alert_view.el);
a("body").prepend(this.$el).addClass("header-alert-visible")
},
onClose: function(b) {
a(this.alert_view.el).remove();
this.alert_view = null;
a("body").removeClass("header-alert-visible");
this.$el.detach()
}
})
})(jQuery);
(function(a) {
var b = "https://www.wunderground.com";
if (window.location.host && window.location.host.indexOf("www") === -1) {
b = ""
}
if (!window.Backbone) {
return
}
wui.Views.UpgradeMembershipView = Backbone.View.extend({
events: {
"submit .upgrade-wrap": "upgradeMembership",
"submit #send-gift": "sendGiftCode"
},
initialize: function() {},
render: function() {
return this
},
sendGiftCode: function(f) {
var c = a(f.target);
var d = b + c.attr("action") + "?" + c.serialize();
a("#send-loading").addClass("loading");
a("#send-status").removeClass("error");
a.ajax(d, {
type: "post",
dataType: "json"
}).done(function(e) {
if (e.status === "success") {
if (e.giftcode && e.giftcode.errors && e.giftcode.errors.length) {
a("#send-status").text(e.giftcode.errors[0].error_string).addClass("error")
} else {
a("#send-status").html("You sent <strong>" + c.find('input[name="toemail"]').val() + "</strong> a message with details on how to get three months of Premium Membership!")
}
} else {
if (e.errors && e.errors.length) {
a("#send-status").text(e.errors[0].error_string).addClass("error")
}
}
}).fail(function() {
a("#send-status").text("Something went wrong...Please try again later.")
}).complete(function() {
a("#send-loading").removeClass("loading")
});
return false
},
redeemGiftCode: function(c, d) {
var e = this;
a.ajax(b + "/member/redeemcode", {
data: {
giftcode: c,
toemail: d
},
dataType: "json"
}).done(function(f) {
if (f.status === "success") {
if (f.giftcode && f.giftcode.errors && f.giftcode.errors.length) {
e.$el.find(".upgrade-status").removeClass("hide").text(f.giftcode.errors[0].error_string)
} else {
e.$el.find(".upgrade-status").text("Your giftcode has been applied successfully!").removeClass("error hide")
}
}
}).fail(function() {
e.$el.find(".upgrade-status").removeClass("hide").text("Something went wrong...Please try again later.")
}).complete(function() {
e.$el.find(".upgrade-loading").removeClass("loading")
})
},
upgradeMembership: function() {
var d = this.$el.find(".upgrade-code");
var e = d.val();
var c = this.$el.find('input[name="gift-only"]').val() == 1 || false;
if (e || c) {
this.$el.find(".upgrade-loading").addClass("loading");
this.redeemGiftCode(e, d.data("email"))
} else {
a(".payment-form").submit()
}
return false
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.CondsCard = Backbone.View.extend({
initialize: function(b) {
this.options = b || {};
this.models = this.options.models || {};
this.models.weather = this.createWeatherModel();
this.models.weather.fetch();
this.listenToOnce(this.models.weather, "sync", this.render)
},
createWeatherModel: function() {
var c = wui.bootstrapped.prefs;
var d = this.options.geoip_lat + "," + this.options.geoip_lon;
if (this.options.geoip_lat == "0.00" && this.options.geoip_lon == "0.00") {
d = "94101.1.99999"
}
if (this.options.home_zmw.length > 0 && this.options.home_zmw != "") {
d = this.options.home_zmw
}
var b = new wui.Models.Weather({},{
apikey: "8dee7a0127c63e7f",
lang: c.LangCode,
query: d,
features: ["forecast10day", "conditions"],
units: c.Units,
version: "2.0"
});
return b
},
render: function() {
this.template = _.template(a("script#conditions-card-template").html());
var c = {
weather: this.models.weather.attributes
};
var b = this.template(c);
this.$el.removeClass("placeholder");
this.$el.find(".react-wrapper").html(b);
return this
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.UstreamTDUView = Backbone.View.extend({
events: {
"click .close": "onClose"
},
initialize: function() {
if (typeof (UstreamEmbed) != "undefined") {
this.viewer = UstreamEmbed(this.$el.find("iframe").attr("id"));
this.islive = false;
var b = this;
this.viewer.addListener("live", function() {
b.itsAlive()
});
this.viewer.addListener("playing", function() {
b.itsAlive()
});
this.viewer.addListener("offline", function() {
b.hesDeadJim()
})
}
},
itsAlive: function() {
if (!this.islive) {
this.islive = true;
this.viewer.removeListener("live");
this.viewer.removeListener("playing");
this.viewer.removeListener("offline");
this.$el.remove();
wui.page.headerTDU = a("#header-alert-bar").addClass("downpour-tdu").removeClass("not-found");
var b = '<div class="tdu-wrap"><a href="/live-forecasts" target="_blank" class="white-text non-bold">' + wui.bootstrapped.dailyDownpourText + '</a><span class="close">x</span></div>';
wui.page.headerTDU.html(b);
wui.page.headerTDU.on("click", ".close", this.onClose);
a(".new-badge-text-only.twiw").show();
a(window).trigger("resize")
}
},
hesDeadJim: function() {},
onClose: function(b) {
if (this.viewer) {
this.viewer.removeListener("live");
this.viewer.removeListener("playing");
this.viewer.removeListener("offline")
}
wui.page.headerTDU.removeClass("active downpour-tdu")
}
})
})(jQuery);
(function(a) {
if (!window.Backbone) {
return
}
wui.Views.AlertModule = Backbone.View.extend({
events: {
"submit #alert-form": "onSubscribe"
},
initialize: function(c) {
this.options = c || {};
this.model = c.model;
this.type = c.type;
this.typeData = {};
this.$alerts = a("#alerts-location");
if (this.$alerts[0]) {
var b = new wui.autocomplete({
autosubmit: false,
autoFocus: true,
data: {
ski: 1,
features: 0
},
includeFavorites: false,
includePWS: false,
includeHeaderGeoLocate: false,
includeRecents: true,
includePopular: true,
includeOnlyCities: true,
includeOnlyUS: false,
input: "#alerts-location",
maxResults: 10,
minLength: 0,
showConditions: false,
showFavoriteStars: false,
appendTo: "#autocomplete-wrap"
})
}
if (this.model) {
this.listenTo(this.model, "change:success", this.checkReady);
this.checkReady()
}
},
checkReady: function() {
if (typeof this.model.get("forecast") !== "undefined") {
this.typeData = this.model.get(this.type);
this.render()
}
},
render: function() {
var b = this.typeData.activeCity;
if (!b) {
a("#alerts-hook").show()
}
},
onSubscribe: function(h) {
h.preventDefault();
var f = this;
var g = this.$alerts.val();
var c = "//api.wunderground.com/api/260773b24515a709/geolookup/alerts/q/" + g + ".json";
var j = a(".alert-error");
var d = a(".alert-email-error");
var l = a("#alerts-location");
var k = a("#alerts-email");
var i = k.val();
j.html("").hide();
d.html("").hide();
l.removeClass("has-error");
k.removeClass("has-error");
var m = /^[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])?)*$/;
var b = m.test(i);
if (!b) {
d.html("Please enter a valid email address.").show();
k.addClass("has-error");
return false
}
a.ajax({
url: c,
dataType: "json",
complete: function(q) {
var o = JSON.parse(q.responseText);
if (o.response.error) {
j.html("Location not found");
j.show();
l.addClass("has-error")
} else {
if (o.response.results) {
if (o.response.results.length > 1) {
j.html("Location not found");
j.show();
l.addClass("has-error")
}
} else {
if (o.location) {
var s = o.location;
var r = {};
var n = a("#alerts-hook").hasClass("alert-severe");
if (a.inArray(p, f.model.get("cities")) > -1) {
j.html("You've already signed up for this city.");
l.addClass("has-error");
return
}
var p = s.city;
var t = s.state;
var e = s.country_name;
var u = t + o.query_zone;
var v = "periods=ALL&SVR=0";
if (s.type !== "INTLCITY") {
if (s.state) {
p += ", " + s.state
} else {
if (s.country) {
p += ", " + s.country
}
}
}
if (s.country_name === "USA") {
e = "United States"
}
if (n) {
v = "periods=NON&SVR=1"
}
a.ajax({
url: "/member/sendemailvalidationcode?altemail=" + i + "&zip=" + s.zip + "&magic=" + s.magic + "&zone=" + u + "&country=" + e + "&cityname=" + p + "&" + v + "&lat=" + s.lat + "&lon=" + s.lon,
dataType: "json",
complete: function(A) {
var z = JSON.parse(A.responseText);
var y = false;
var w = z.status === "error" && z.errors;
if (w) {
for (var x = 0; x < z.errors.length; x++) {
if (z.errors[x].error_code === "already_valid") {
y = true
}
}
}
if (y) {
a("#default-message").hide()
} else {
a("#alt-message").hide()
}
a("#alert-form").hide();
a("#alert-thank-you").addClass("email-validated").show()
}
})
}
}
}
}
});
return false
}
})
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment