Comparison of Stamen Design's previous Toner style with new Toner data as of 2014.
Borrowed from Andrew Harvey's gist here and his live demo.
Extended with Leaflet-hash by Michael Evans
Adapted to function on bl.ocks.org by Alan McConchie
Comparison of Stamen Design's previous Toner style with new Toner data as of 2014.
Borrowed from Andrew Harvey's gist here and his live demo.
Extended with Leaflet-hash by Michael Evans
Adapted to function on bl.ocks.org by Alan McConchie
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<!-- | |
This file is licenced CC0 http://creativecommons.org/publicdomain/zero/1.0/ | |
--> | |
<head> | |
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> | |
<title>Leaflet Maps Side by Side</title> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" type="text/css" /> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; | |
} | |
/* set the two maps side by side */ | |
#mapA { | |
width: 50%; | |
height: 100%; | |
} | |
#mapB { | |
width: 50%; | |
height: 100%; | |
left: 50%; | |
top: 0; | |
position: absolute; | |
} | |
/* the cursor */ | |
#cursor { | |
position: absolute; | |
z-index: 100; | |
} | |
/* map title bar along the top */ | |
.title { | |
position: absolute; | |
z-index: 2; | |
opacity: 0.75; | |
top: 0px; | |
text-align: center; | |
font-weight: bold; | |
background-color: white; | |
} | |
/* position the individual title bars */ | |
#mapATitle { | |
width: 50%; | |
} | |
#mapBTitle { | |
width: 50%; | |
left: 50%; | |
} | |
</style> | |
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script> | |
<script src="https://cdn.rawgit.com/turban/Leaflet.Sync/master/L.Map.Sync.js" type="text/javascript"></script> | |
<script src="zepto.min.js" type="text/javascript"></script> | |
<script src="prototype.js" type="text/javascript"></script> | |
<script src="leaflet-hash.js" type="text/javascript"></script> | |
<script src="l.control.geosearch.js" type="text/javascript"></script> | |
<script src="l.geosearch.provider.nominatim.js" type="text/javascript"></script> | |
<link rel="stylesheet" href="l.geosearch.toner.css" type="text/css" /> | |
<script type="text/javascript"> | |
var mapA; | |
var mapB; | |
window.onload = function init(){ | |
// predefined map layers | |
var provider = "http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png"; | |
var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\ | |
(min--moz-device-pixel-ratio: 1.5),\ | |
(-o-min-device-pixel-ratio: 3/2),\ | |
(min-resolution: 1.5dppx)"; | |
if (window.devicePixelRatio > 1 || | |
(window.matchMedia && window.matchMedia(mediaQuery).matches)) { | |
// replace the last "." with "@2x." | |
provider = provider.replace(/\.(?!.*\.)/, "@2x.") | |
} | |
var tonernew = new L.TileLayer(provider, | |
{ | |
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://opendatacommons.org/licenses/odbl/">ODbL</a>.', | |
maxZoom: 18 | |
}); | |
var tonerold = new L.TileLayer("http://tile.stamen.com/toner-lite/{z}/{x}/{y}.png", | |
{ | |
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.', | |
maxZoom: 18 | |
}); | |
// give these layers names so users can reference them in the URI | |
var mapLayers = new Array(); | |
mapLayers['tonernew'] = tonernew; | |
mapLayers['tonerold'] = tonerold; | |
var mapADefaultLayer = tonerold; | |
var mapBDefaultLayer = tonernew; | |
// make the map objects | |
var startLocation = new L.LatLng(0,0); | |
var startZoom = 2; | |
mapA = new L.Map('mapA', | |
{ | |
center: startLocation, | |
zoom: startZoom, | |
layers: [mapADefaultLayer] | |
}); | |
mapB = new L.Map('mapB', | |
{ | |
center: startLocation, | |
zoom: startZoom, | |
layers: [mapBDefaultLayer] | |
}); | |
var hash = new L.Hash(mapA); | |
/* | |
new L.Control.GeoSearch({ | |
provider: new L.GeoSearch.Provider.Nominatim(), | |
showMarker: false | |
}).addTo(mapA); | |
*/ | |
mapA.sync(mapB); | |
mapB.sync(mapA); | |
// update the location of the cursor | |
function updateCursorA(e) { | |
updateCursor(e, (window.innerWidth / 2)); | |
} | |
function updateCursorB(e) { | |
updateCursor(e, -(window.innerWidth / 2)); | |
} | |
function updateCursor(e, offset){ | |
// the 15 is here to position to the center of the cursor icon in, not the top left of the cursor image | |
$('cursor').top = e.clientY - 15; | |
$('cursor').left = offset + e.clientX - 15; | |
$('cursor').setStyle({ | |
left: $('cursor').left, | |
top: $('cursor').top | |
}); | |
} | |
document.getElementById('mapA').onmousemove = updateCursorA; | |
document.getElementById('mapB').onmousemove = updateCursorB; | |
} | |
</script> | |
</head> | |
<body id="body"> | |
<div id="mapA"></div> | |
<div id="mapB"></div> | |
<div id="mapATitle" class="title">Toner old</div> | |
<div id="mapbTitle" class="title">Toner 2014</div> | |
<!-- | |
The following license applies to the following cross.png file originally from | |
http://gitorious.org/opensuse/art/blobs/master/cursors/dmz/pngs/32x32/cross.png | |
(c) 2007-2010 Novell, Inc. | |
This work is licenced under the Creative Commons Attribution-Share Alike 3.0 | |
United States License. To view a copy of this licence, visit | |
http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative | |
Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA. | |
--> | |
<div><img id="cursor" src="cross.png" alt="X"/></div> | |
</body> | |
</html> | |
/* | |
* L.Control.GeoSearch - search for an address and zoom to its location | |
* https://github.com/smeijer/leaflet.control.geosearch | |
*/ | |
L.GeoSearch = {}; | |
L.GeoSearch.Provider = {}; | |
L.GeoSearch.Result = function (x, y, label) { | |
this.X = x; | |
this.Y = y; | |
this.Label = label; | |
}; | |
L.Control.GeoSearch = L.Control.extend({ | |
options: { | |
position: 'topleft' | |
}, | |
initialize: function (options) { | |
this._config = {}; | |
L.Util.extend(this.options, options); | |
this.setConfig(options); | |
}, | |
setConfig: function (options) { | |
this._config = { | |
'provider': options.provider, | |
'searchLabel': options.searchLabel || 'Enter address', | |
'notFoundMessage' : options.notFoundMessage || 'Sorry, that address could not be found.', | |
'zoomLevel': options.zoomLevel || 17, | |
'showMarker': typeof options.showMarker !== 'undefined' ? options.showMarker : true | |
}; | |
}, | |
resetLink: function(extraClass) { | |
var link = this._container.querySelector('a'); | |
link.className = 'leaflet-bar-part leaflet-bar-part-single' + ' ' + extraClass; | |
}, | |
onAdd: function (map) { | |
// create the container | |
this._container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-geosearch'); | |
// create the link - this will contain one of the icons | |
var link = L.DomUtil.create('a', '', this._container); | |
link.href = '#'; | |
link.title = this._config.searchLabel; | |
// set the link's icon to magnifying glass | |
this.resetLink('glass'); | |
var displayNoneClass = 'displayNone'; | |
// create the form that will contain the input | |
var form = L.DomUtil.create('form', displayNoneClass, this._container); | |
// create the input, and set its placeholder ("Enter address") text | |
var input = L.DomUtil.create('input', null, form); | |
input.placeholder = 'Enter address'; | |
// create the error message div | |
var message = L.DomUtil.create('div', 'leaflet-bar message displayNone', this._container); | |
L.DomEvent | |
.on(link, 'click', L.DomEvent.stopPropagation) | |
.on(link, 'click', L.DomEvent.preventDefault) | |
.on(link, 'click', function() { | |
if (L.DomUtil.hasClass(form, displayNoneClass)) { | |
L.DomUtil.removeClass(form, 'displayNone'); // unhide form | |
input.focus(); | |
} else { | |
L.DomUtil.addClass(form, 'displayNone'); // hide form | |
} | |
}) | |
.on(link, 'dblclick', L.DomEvent.stopPropagation); | |
L.DomEvent | |
.on(input, 'keypress', this.onKeyPress, this) | |
.on(input, 'keyup', this.onKeyUp, this) | |
.on(input, 'input', this.onInput, this); | |
return this._container; | |
}, | |
geosearch: function (qry) { | |
try { | |
var provider = this._config.provider; | |
if(typeof provider.GetLocations == 'function') { | |
var results = provider.GetLocations(qry, this._map, function(err, results) { | |
if (err) { | |
return this._printError(err); | |
} | |
this._processResults(results); | |
}.bind(this)); | |
} | |
else { | |
var url = provider.GetServiceUrl(qry); | |
$.getJSON(url, function (data) { | |
try { | |
var results = provider.ParseJSON(data); | |
this._processResults(results); | |
} | |
catch (error) { | |
this._printError(error); | |
} | |
}.bind(this)); | |
} | |
} | |
catch (error) { | |
this._printError(error); | |
} | |
}, | |
_processResults: function(results) { | |
if (results.length === 0) | |
throw this._config.notFoundMessage; | |
this.cancelSearch(); | |
this._showLocation(results[0]); | |
}, | |
_showLocation: function (location) { | |
if (this._config.showMarker) { | |
if (typeof this._positionMarker === 'undefined') | |
this._positionMarker = L.marker([location.Y, location.X]).addTo(this._map); | |
else | |
this._positionMarker.setLatLng([location.Y, location.X]); | |
} | |
// this._map.setView([location.Y, location.X], this._config.zoomLevel, false); | |
}, | |
_isShowingError: false, | |
_printError: function(error) { | |
var message = this._container.querySelector('.message'); | |
message.innerHTML = error; | |
L.DomUtil.removeClass(message, 'displayNone'); | |
// show alert icon | |
this.resetLink('alert'); | |
this._isShowingError = true; | |
}, | |
cancelSearch: function() { | |
var form = this._container.querySelector('form'); | |
L.DomUtil.addClass(form, 'displayNone'); // hide form | |
var input = form.querySelector('input'); | |
input.value = ''; // clear form | |
// show glass icon | |
this.resetLink('glass'); | |
var message = this._container.querySelector('.message'); | |
L.DomUtil.addClass(message, 'displayNone'); // hide message | |
}, | |
startSearch: function() { | |
// show spinner icon | |
this.resetLink('spinner'); | |
var input = this._container.querySelector('input'); | |
this.geosearch(input.value); | |
}, | |
onInput: function() { | |
if (this._isShowingError) { | |
// show glass icon | |
this.resetLink('glass'); | |
var message = this._container.querySelector('.message'); | |
L.DomUtil.addClass(message, 'displayNone'); // hide message | |
this._isShowingError = false; | |
} | |
}, | |
onKeyPress: function (e) { | |
var enterKey = 13; | |
if (e.keyCode === enterKey) { | |
L.DomEvent.preventDefault(e); // prevent default form submission | |
this.startSearch(); | |
} | |
}, | |
onKeyUp: function (e) { | |
var escapeKey = 27; | |
if (e.keyCode === escapeKey) { | |
this.cancelSearch(); | |
} | |
} | |
}); |
/** | |
* L.Control.GeoSearch - search for an address and zoom to it's location | |
* L.GeoSearch.Provider.OpenStreetMap uses openstreetmap geocoding service | |
* https://github.com/smeijer/leaflet.control.geosearch | |
*/ | |
L.GeoSearch.Provider.Nominatim = L.Class.extend({ | |
options: { | |
}, | |
initialize: function(options) { | |
options = L.Util.setOptions(this, options); | |
}, | |
GetLocations: function(query, map, callback) { | |
callback = callback || function() {}; | |
var url = this.GetServiceUrl(query); | |
$.getJSON(url, function (data) { | |
var results; | |
try { | |
results = this.ParseJSON(data); | |
} catch (err) { | |
return callback(err); | |
} | |
if (data.length > 0) { | |
var bbox = data[0].boundingbox, | |
viewport = [ | |
[bbox[0], bbox[2]], | |
[bbox[1], bbox[3]] | |
]; | |
map.fitBounds(viewport, { | |
maxZoom: 15 | |
}); | |
} | |
return callback(null, results); | |
}.bind(this)); | |
}, | |
GetServiceUrl: function (qry) { | |
var parameters = L.Util.extend({ | |
q: qry, | |
format: 'json' | |
}, this.options); | |
return 'http://nominatim.openstreetmap.org/search' | |
+ L.Util.getParamString(parameters); | |
}, | |
ParseJSON: function (data) { | |
if (data.length == 0) | |
return []; | |
var results = []; | |
for (var i = 0; i < data.length; i++) | |
results.push(new L.GeoSearch.Result( | |
data[i].lon, | |
data[i].lat, | |
data[i].display_name | |
)); | |
return results; | |
} | |
}); |
.displayNone { | |
display: none; | |
} | |
.leaflet-control-geosearch { | |
position: relative; | |
} | |
.leaflet-control-geosearch a { | |
-webkit-border-radius: 4px; | |
border-radius: 4px; | |
border-bottom: none; | |
} | |
.leaflet-control-geosearch a.glass { | |
background-image: url(geosearch.png); | |
background-size: 100% 100%; | |
} | |
.leaflet-control-geosearch a.spinner { | |
background-image: url(spinner.gif); | |
background-position: 50% 50%; | |
} | |
.leaflet-control-geosearch a.alert { | |
background-image: url(alert.png); | |
background-size: 64% 64%; | |
} | |
.leaflet-control-geosearch a:hover { | |
border-bottom: none; | |
} | |
.leaflet-control-geosearch form { | |
position: absolute; | |
top: 0; | |
left: 22px; | |
box-shadow: 0 1px 7px rgba(0, 0, 0, 0.65); | |
-webkit-border-radius: 4px; | |
border-radius: 0px 4px 4px 0px; | |
z-index: -1; | |
background: #FFF; | |
height: 26px; | |
padding: 0 6px 0 6px; | |
} | |
.leaflet-control-geosearch form input { | |
width: 200px; | |
border: none; | |
outline: none; | |
margin: 0; | |
padding: 0; | |
font-size: 12px; | |
margin-top: 5px; | |
} | |
.leaflet-control-geosearch .message { | |
position: absolute; | |
top: 26px; | |
left: 0px; | |
width: 226px; | |
color: #FFF; | |
background: rgb(40, 40, 40); | |
padding: 4px 0 4px 8px; | |
} |
(function(window) { | |
var HAS_HASHCHANGE = (function() { | |
var doc_mode = window.documentMode; | |
return ('onhashchange' in window) && | |
(doc_mode === undefined || doc_mode > 7); | |
})(); | |
L.Hash = function(map) { | |
this.onHashChange = L.Util.bind(this.onHashChange, this); | |
if (map) { | |
this.init(map); | |
} | |
}; | |
L.Hash.parseHash = function(hash) { | |
if(hash.indexOf('#') === 0) { | |
hash = hash.substr(1); | |
} | |
var args = hash.split("/"); | |
if (args.length == 3) { | |
var zoom = parseInt(args[0], 10), | |
lat = parseFloat(args[1]), | |
lon = parseFloat(args[2]); | |
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) { | |
return false; | |
} else { | |
return { | |
center: new L.LatLng(lat, lon), | |
zoom: zoom | |
}; | |
} | |
} else { | |
return false; | |
} | |
}; | |
L.Hash.formatHash = function(map) { | |
var center = map.getCenter(), | |
zoom = map.getZoom(), | |
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)); | |
return "#" + [zoom, | |
center.lat.toFixed(precision), | |
center.lng.toFixed(precision) | |
].join("/"); | |
}, | |
L.Hash.prototype = { | |
map: null, | |
lastHash: null, | |
parseHash: L.Hash.parseHash, | |
formatHash: L.Hash.formatHash, | |
init: function(map) { | |
this.map = map; | |
// reset the hash | |
this.lastHash = null; | |
this.onHashChange(); | |
if (!this.isListening) { | |
this.startListening(); | |
} | |
}, | |
removeFrom: function(map) { | |
if (this.changeTimeout) { | |
clearTimeout(this.changeTimeout); | |
} | |
if (this.isListening) { | |
this.stopListening(); | |
} | |
this.map = null; | |
}, | |
onMapMove: function() { | |
// bail if we're moving the map (updating from a hash), | |
// or if the map is not yet loaded | |
if (this.movingMap || !this.map._loaded) { | |
return false; | |
} | |
var hash = this.formatHash(this.map); | |
if (this.lastHash != hash) { | |
location.replace(hash); | |
this.lastHash = hash; | |
} | |
}, | |
movingMap: false, | |
update: function() { | |
var hash = location.hash; | |
if (hash === this.lastHash) { | |
return; | |
} | |
var parsed = this.parseHash(hash); | |
if (parsed) { | |
this.movingMap = true; | |
this.map.setView(parsed.center, parsed.zoom, { animate: false }); | |
this.movingMap = false; | |
} else { | |
this.onMapMove(this.map); | |
} | |
}, | |
// defer hash change updates every 100ms | |
changeDefer: 100, | |
changeTimeout: null, | |
onHashChange: function() { | |
// throttle calls to update() so that they only happen every | |
// `changeDefer` ms | |
if (!this.changeTimeout) { | |
var that = this; | |
this.changeTimeout = setTimeout(function() { | |
that.update(); | |
that.changeTimeout = null; | |
}, this.changeDefer); | |
} | |
}, | |
isListening: false, | |
hashChangeInterval: null, | |
startListening: function() { | |
this.map.on("moveend", this.onMapMove, this); | |
if (HAS_HASHCHANGE) { | |
L.DomEvent.addListener(window, "hashchange", this.onHashChange); | |
} else { | |
clearInterval(this.hashChangeInterval); | |
this.hashChangeInterval = setInterval(this.onHashChange, 50); | |
} | |
this.isListening = true; | |
}, | |
stopListening: function() { | |
this.map.off("moveend", this.onMapMove, this); | |
if (HAS_HASHCHANGE) { | |
L.DomEvent.removeListener(window, "hashchange", this.onHashChange); | |
} else { | |
clearInterval(this.hashChangeInterval); | |
} | |
this.isListening = false; | |
} | |
}; | |
L.hash = function(map) { | |
return new L.Hash(map); | |
}; | |
L.Map.prototype.addHash = function() { | |
this._hash = L.hash(this); | |
}; | |
L.Map.prototype.removeHash = function() { | |
this._hash.removeFrom(); | |
}; | |
})(window); |
/* Prototype JavaScript framework, version 1.7.2 | |
* (c) 2005-2010 Sam Stephenson | |
* | |
* Prototype is freely distributable under the terms of an MIT-style license. | |
* For details, see the Prototype web site: http://www.prototypejs.org/ | |
* | |
*--------------------------------------------------------------------------*/ | |
var Prototype = { | |
Version: '1.7.2', | |
Browser: (function(){ | |
var ua = navigator.userAgent; | |
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; | |
return { | |
IE: !!window.attachEvent && !isOpera, | |
Opera: isOpera, | |
WebKit: ua.indexOf('AppleWebKit/') > -1, | |
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, | |
MobileSafari: /Apple.*Mobile/.test(ua) | |
} | |
})(), | |
BrowserFeatures: { | |
XPath: !!document.evaluate, | |
SelectorsAPI: !!document.querySelector, | |
ElementExtensions: (function() { | |
var constructor = window.Element || window.HTMLElement; | |
return !!(constructor && constructor.prototype); | |
})(), | |
SpecificElementExtensions: (function() { | |
if (typeof window.HTMLDivElement !== 'undefined') | |
return true; | |
var div = document.createElement('div'), | |
form = document.createElement('form'), | |
isSupported = false; | |
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { | |
isSupported = true; | |
} | |
div = form = null; | |
return isSupported; | |
})() | |
}, | |
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script\\s*>', | |
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, | |
emptyFunction: function() { }, | |
K: function(x) { return x } | |
}; | |
if (Prototype.Browser.MobileSafari) | |
Prototype.BrowserFeatures.SpecificElementExtensions = false; | |
/* Based on Alex Arnell's inheritance implementation. */ | |
var Class = (function() { | |
var IS_DONTENUM_BUGGY = (function(){ | |
for (var p in { toString: 1 }) { | |
if (p === 'toString') return false; | |
} | |
return true; | |
})(); | |
function subclass() {}; | |
function create() { | |
var parent = null, properties = $A(arguments); | |
if (Object.isFunction(properties[0])) | |
parent = properties.shift(); | |
function klass() { | |
this.initialize.apply(this, arguments); | |
} | |
Object.extend(klass, Class.Methods); | |
klass.superclass = parent; | |
klass.subclasses = []; | |
if (parent) { | |
subclass.prototype = parent.prototype; | |
klass.prototype = new subclass; | |
parent.subclasses.push(klass); | |
} | |
for (var i = 0, length = properties.length; i < length; i++) | |
klass.addMethods(properties[i]); | |
if (!klass.prototype.initialize) | |
klass.prototype.initialize = Prototype.emptyFunction; | |
klass.prototype.constructor = klass; | |
return klass; | |
} | |
function addMethods(source) { | |
var ancestor = this.superclass && this.superclass.prototype, | |
properties = Object.keys(source); | |
if (IS_DONTENUM_BUGGY) { | |
if (source.toString != Object.prototype.toString) | |
properties.push("toString"); | |
if (source.valueOf != Object.prototype.valueOf) | |
properties.push("valueOf"); | |
} | |
for (var i = 0, length = properties.length; i < length; i++) { | |
var property = properties[i], value = source[property]; | |
if (ancestor && Object.isFunction(value) && | |
value.argumentNames()[0] == "$super") { | |
var method = value; | |
value = (function(m) { | |
return function() { return ancestor[m].apply(this, arguments); }; | |
})(property).wrap(method); | |
value.valueOf = (function(method) { | |
return function() { return method.valueOf.call(method); }; | |
})(method); | |
value.toString = (function(method) { | |
return function() { return method.toString.call(method); }; | |
})(method); | |
} | |
this.prototype[property] = value; | |
} | |
return this; | |
} | |
return { | |
create: create, | |
Methods: { | |
addMethods: addMethods | |
} | |
}; | |
})(); | |
(function() { | |
var _toString = Object.prototype.toString, | |
_hasOwnProperty = Object.prototype.hasOwnProperty, | |
NULL_TYPE = 'Null', | |
UNDEFINED_TYPE = 'Undefined', | |
BOOLEAN_TYPE = 'Boolean', | |
NUMBER_TYPE = 'Number', | |
STRING_TYPE = 'String', | |
OBJECT_TYPE = 'Object', | |
FUNCTION_CLASS = '[object Function]', | |
BOOLEAN_CLASS = '[object Boolean]', | |
NUMBER_CLASS = '[object Number]', | |
STRING_CLASS = '[object String]', | |
ARRAY_CLASS = '[object Array]', | |
DATE_CLASS = '[object Date]', | |
NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && | |
typeof JSON.stringify === 'function' && | |
JSON.stringify(0) === '0' && | |
typeof JSON.stringify(Prototype.K) === 'undefined'; | |
var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf', | |
'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor']; | |
var IS_DONTENUM_BUGGY = (function(){ | |
for (var p in { toString: 1 }) { | |
if (p === 'toString') return false; | |
} | |
return true; | |
})(); | |
function Type(o) { | |
switch(o) { | |
case null: return NULL_TYPE; | |
case (void 0): return UNDEFINED_TYPE; | |
} | |
var type = typeof o; | |
switch(type) { | |
case 'boolean': return BOOLEAN_TYPE; | |
case 'number': return NUMBER_TYPE; | |
case 'string': return STRING_TYPE; | |
} | |
return OBJECT_TYPE; | |
} | |
function extend(destination, source) { | |
for (var property in source) | |
destination[property] = source[property]; | |
return destination; | |
} | |
function inspect(object) { | |
try { | |
if (isUndefined(object)) return 'undefined'; | |
if (object === null) return 'null'; | |
return object.inspect ? object.inspect() : String(object); | |
} catch (e) { | |
if (e instanceof RangeError) return '...'; | |
throw e; | |
} | |
} | |
function toJSON(value) { | |
return Str('', { '': value }, []); | |
} | |
function Str(key, holder, stack) { | |
var value = holder[key]; | |
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { | |
value = value.toJSON(key); | |
} | |
var _class = _toString.call(value); | |
switch (_class) { | |
case NUMBER_CLASS: | |
case BOOLEAN_CLASS: | |
case STRING_CLASS: | |
value = value.valueOf(); | |
} | |
switch (value) { | |
case null: return 'null'; | |
case true: return 'true'; | |
case false: return 'false'; | |
} | |
var type = typeof value; | |
switch (type) { | |
case 'string': | |
return value.inspect(true); | |
case 'number': | |
return isFinite(value) ? String(value) : 'null'; | |
case 'object': | |
for (var i = 0, length = stack.length; i < length; i++) { | |
if (stack[i] === value) { | |
throw new TypeError("Cyclic reference to '" + value + "' in object"); | |
} | |
} | |
stack.push(value); | |
var partial = []; | |
if (_class === ARRAY_CLASS) { | |
for (var i = 0, length = value.length; i < length; i++) { | |
var str = Str(i, value, stack); | |
partial.push(typeof str === 'undefined' ? 'null' : str); | |
} | |
partial = '[' + partial.join(',') + ']'; | |
} else { | |
var keys = Object.keys(value); | |
for (var i = 0, length = keys.length; i < length; i++) { | |
var key = keys[i], str = Str(key, value, stack); | |
if (typeof str !== "undefined") { | |
partial.push(key.inspect(true)+ ':' + str); | |
} | |
} | |
partial = '{' + partial.join(',') + '}'; | |
} | |
stack.pop(); | |
return partial; | |
} | |
} | |
function stringify(object) { | |
return JSON.stringify(object); | |
} | |
function toQueryString(object) { | |
return $H(object).toQueryString(); | |
} | |
function toHTML(object) { | |
return object && object.toHTML ? object.toHTML() : String.interpret(object); | |
} | |
function keys(object) { | |
if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } | |
var results = []; | |
for (var property in object) { | |
if (_hasOwnProperty.call(object, property)) | |
results.push(property); | |
} | |
if (IS_DONTENUM_BUGGY) { | |
for (var i = 0; property = DONT_ENUMS[i]; i++) { | |
if (_hasOwnProperty.call(object, property)) | |
results.push(property); | |
} | |
} | |
return results; | |
} | |
function values(object) { | |
var results = []; | |
for (var property in object) | |
results.push(object[property]); | |
return results; | |
} | |
function clone(object) { | |
return extend({ }, object); | |
} | |
function isElement(object) { | |
return !!(object && object.nodeType == 1); | |
} | |
function isArray(object) { | |
return _toString.call(object) === ARRAY_CLASS; | |
} | |
var hasNativeIsArray = (typeof Array.isArray == 'function') | |
&& Array.isArray([]) && !Array.isArray({}); | |
if (hasNativeIsArray) { | |
isArray = Array.isArray; | |
} | |
function isHash(object) { | |
return object instanceof Hash; | |
} | |
function isFunction(object) { | |
return _toString.call(object) === FUNCTION_CLASS; | |
} | |
function isString(object) { | |
return _toString.call(object) === STRING_CLASS; | |
} | |
function isNumber(object) { | |
return _toString.call(object) === NUMBER_CLASS; | |
} | |
function isDate(object) { | |
return _toString.call(object) === DATE_CLASS; | |
} | |
function isUndefined(object) { | |
return typeof object === "undefined"; | |
} | |
extend(Object, { | |
extend: extend, | |
inspect: inspect, | |
toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, | |
toQueryString: toQueryString, | |
toHTML: toHTML, | |
keys: Object.keys || keys, | |
values: values, | |
clone: clone, | |
isElement: isElement, | |
isArray: isArray, | |
isHash: isHash, | |
isFunction: isFunction, | |
isString: isString, | |
isNumber: isNumber, | |
isDate: isDate, | |
isUndefined: isUndefined | |
}); | |
})(); | |
Object.extend(Function.prototype, (function() { | |
var slice = Array.prototype.slice; | |
function update(array, args) { | |
var arrayLength = array.length, length = args.length; | |
while (length--) array[arrayLength + length] = args[length]; | |
return array; | |
} | |
function merge(array, args) { | |
array = slice.call(array, 0); | |
return update(array, args); | |
} | |
function argumentNames() { | |
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] | |
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') | |
.replace(/\s+/g, '').split(','); | |
return names.length == 1 && !names[0] ? [] : names; | |
} | |
function bind(context) { | |
if (arguments.length < 2 && Object.isUndefined(arguments[0])) | |
return this; | |
if (!Object.isFunction(this)) | |
throw new TypeError("The object is not callable."); | |
var nop = function() {}; | |
var __method = this, args = slice.call(arguments, 1); | |
var bound = function() { | |
var a = merge(args, arguments); | |
var c = this instanceof bound ? this : context; | |
return __method.apply(c, a); | |
}; | |
nop.prototype = this.prototype; | |
bound.prototype = new nop(); | |
return bound; | |
} | |
function bindAsEventListener(context) { | |
var __method = this, args = slice.call(arguments, 1); | |
return function(event) { | |
var a = update([event || window.event], args); | |
return __method.apply(context, a); | |
} | |
} | |
function curry() { | |
if (!arguments.length) return this; | |
var __method = this, args = slice.call(arguments, 0); | |
return function() { | |
var a = merge(args, arguments); | |
return __method.apply(this, a); | |
} | |
} | |
function delay(timeout) { | |
var __method = this, args = slice.call(arguments, 1); | |
timeout = timeout * 1000; | |
return window.setTimeout(function() { | |
return __method.apply(__method, args); | |
}, timeout); | |
} | |
function defer() { | |
var args = update([0.01], arguments); | |
return this.delay.apply(this, args); | |
} | |
function wrap(wrapper) { | |
var __method = this; | |
return function() { | |
var a = update([__method.bind(this)], arguments); | |
return wrapper.apply(this, a); | |
} | |
} | |
function methodize() { | |
if (this._methodized) return this._methodized; | |
var __method = this; | |
return this._methodized = function() { | |
var a = update([this], arguments); | |
return __method.apply(null, a); | |
}; | |
} | |
var extensions = { | |
argumentNames: argumentNames, | |
bindAsEventListener: bindAsEventListener, | |
curry: curry, | |
delay: delay, | |
defer: defer, | |
wrap: wrap, | |
methodize: methodize | |
}; | |
if (!Function.prototype.bind) | |
extensions.bind = bind; | |
return extensions; | |
})()); | |
(function(proto) { | |
function toISOString() { | |
return this.getUTCFullYear() + '-' + | |
(this.getUTCMonth() + 1).toPaddedString(2) + '-' + | |
this.getUTCDate().toPaddedString(2) + 'T' + | |
this.getUTCHours().toPaddedString(2) + ':' + | |
this.getUTCMinutes().toPaddedString(2) + ':' + | |
this.getUTCSeconds().toPaddedString(2) + 'Z'; | |
} | |
function toJSON() { | |
return this.toISOString(); | |
} | |
if (!proto.toISOString) proto.toISOString = toISOString; | |
if (!proto.toJSON) proto.toJSON = toJSON; | |
})(Date.prototype); | |
RegExp.prototype.match = RegExp.prototype.test; | |
RegExp.escape = function(str) { | |
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | |
}; | |
var PeriodicalExecuter = Class.create({ | |
initialize: function(callback, frequency) { | |
this.callback = callback; | |
this.frequency = frequency; | |
this.currentlyExecuting = false; | |
this.registerCallback(); | |
}, | |
registerCallback: function() { | |
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); | |
}, | |
execute: function() { | |
this.callback(this); | |
}, | |
stop: function() { | |
if (!this.timer) return; | |
clearInterval(this.timer); | |
this.timer = null; | |
}, | |
onTimerEvent: function() { | |
if (!this.currentlyExecuting) { | |
try { | |
this.currentlyExecuting = true; | |
this.execute(); | |
this.currentlyExecuting = false; | |
} catch(e) { | |
this.currentlyExecuting = false; | |
throw e; | |
} | |
} | |
} | |
}); | |
Object.extend(String, { | |
interpret: function(value) { | |
return value == null ? '' : String(value); | |
}, | |
specialChar: { | |
'\b': '\\b', | |
'\t': '\\t', | |
'\n': '\\n', | |
'\f': '\\f', | |
'\r': '\\r', | |
'\\': '\\\\' | |
} | |
}); | |
Object.extend(String.prototype, (function() { | |
var NATIVE_JSON_PARSE_SUPPORT = window.JSON && | |
typeof JSON.parse === 'function' && | |
JSON.parse('{"test": true}').test; | |
function prepareReplacement(replacement) { | |
if (Object.isFunction(replacement)) return replacement; | |
var template = new Template(replacement); | |
return function(match) { return template.evaluate(match) }; | |
} | |
function isNonEmptyRegExp(regexp) { | |
return regexp.source && regexp.source !== '(?:)'; | |
} | |
function gsub(pattern, replacement) { | |
var result = '', source = this, match; | |
replacement = prepareReplacement(replacement); | |
if (Object.isString(pattern)) | |
pattern = RegExp.escape(pattern); | |
if (!(pattern.length || isNonEmptyRegExp(pattern))) { | |
replacement = replacement(''); | |
return replacement + source.split('').join(replacement) + replacement; | |
} | |
while (source.length > 0) { | |
match = source.match(pattern) | |
if (match && match[0].length > 0) { | |
result += source.slice(0, match.index); | |
result += String.interpret(replacement(match)); | |
source = source.slice(match.index + match[0].length); | |
} else { | |
result += source, source = ''; | |
} | |
} | |
return result; | |
} | |
function sub(pattern, replacement, count) { | |
replacement = prepareReplacement(replacement); | |
count = Object.isUndefined(count) ? 1 : count; | |
return this.gsub(pattern, function(match) { | |
if (--count < 0) return match[0]; | |
return replacement(match); | |
}); | |
} | |
function scan(pattern, iterator) { | |
this.gsub(pattern, iterator); | |
return String(this); | |
} | |
function truncate(length, truncation) { | |
length = length || 30; | |
truncation = Object.isUndefined(truncation) ? '...' : truncation; | |
return this.length > length ? | |
this.slice(0, length - truncation.length) + truncation : String(this); | |
} | |
function strip() { | |
return this.replace(/^\s+/, '').replace(/\s+$/, ''); | |
} | |
function stripTags() { | |
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); | |
} | |
function stripScripts() { | |
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); | |
} | |
function extractScripts() { | |
var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), | |
matchOne = new RegExp(Prototype.ScriptFragment, 'im'); | |
return (this.match(matchAll) || []).map(function(scriptTag) { | |
return (scriptTag.match(matchOne) || ['', ''])[1]; | |
}); | |
} | |
function evalScripts() { | |
return this.extractScripts().map(function(script) { return eval(script); }); | |
} | |
function escapeHTML() { | |
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |
} | |
function unescapeHTML() { | |
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); | |
} | |
function toQueryParams(separator) { | |
var match = this.strip().match(/([^?#]*)(#.*)?$/); | |
if (!match) return { }; | |
return match[1].split(separator || '&').inject({ }, function(hash, pair) { | |
if ((pair = pair.split('='))[0]) { | |
var key = decodeURIComponent(pair.shift()), | |
value = pair.length > 1 ? pair.join('=') : pair[0]; | |
if (value != undefined) { | |
value = value.gsub('+', ' '); | |
value = decodeURIComponent(value); | |
} | |
if (key in hash) { | |
if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; | |
hash[key].push(value); | |
} | |
else hash[key] = value; | |
} | |
return hash; | |
}); | |
} | |
function toArray() { | |
return this.split(''); | |
} | |
function succ() { | |
return this.slice(0, this.length - 1) + | |
String.fromCharCode(this.charCodeAt(this.length - 1) + 1); | |
} | |
function times(count) { | |
return count < 1 ? '' : new Array(count + 1).join(this); | |
} | |
function camelize() { | |
return this.replace(/-+(.)?/g, function(match, chr) { | |
return chr ? chr.toUpperCase() : ''; | |
}); | |
} | |
function capitalize() { | |
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); | |
} | |
function underscore() { | |
return this.replace(/::/g, '/') | |
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') | |
.replace(/([a-z\d])([A-Z])/g, '$1_$2') | |
.replace(/-/g, '_') | |
.toLowerCase(); | |
} | |
function dasherize() { | |
return this.replace(/_/g, '-'); | |
} | |
function inspect(useDoubleQuotes) { | |
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { | |
if (character in String.specialChar) { | |
return String.specialChar[character]; | |
} | |
return '\\u00' + character.charCodeAt().toPaddedString(2, 16); | |
}); | |
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; | |
return "'" + escapedString.replace(/'/g, '\\\'') + "'"; | |
} | |
function unfilterJSON(filter) { | |
return this.replace(filter || Prototype.JSONFilter, '$1'); | |
} | |
function isJSON() { | |
var str = this; | |
if (str.blank()) return false; | |
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); | |
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); | |
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); | |
return (/^[\],:{}\s]*$/).test(str); | |
} | |
function evalJSON(sanitize) { | |
var json = this.unfilterJSON(), | |
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; | |
if (cx.test(json)) { | |
json = json.replace(cx, function (a) { | |
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | |
}); | |
} | |
try { | |
if (!sanitize || json.isJSON()) return eval('(' + json + ')'); | |
} catch (e) { } | |
throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); | |
} | |
function parseJSON() { | |
var json = this.unfilterJSON(); | |
return JSON.parse(json); | |
} | |
function include(pattern) { | |
return this.indexOf(pattern) > -1; | |
} | |
function startsWith(pattern, position) { | |
position = Object.isNumber(position) ? position : 0; | |
return this.lastIndexOf(pattern, position) === position; | |
} | |
function endsWith(pattern, position) { | |
pattern = String(pattern); | |
position = Object.isNumber(position) ? position : this.length; | |
if (position < 0) position = 0; | |
if (position > this.length) position = this.length; | |
var d = position - pattern.length; | |
return d >= 0 && this.indexOf(pattern, d) === d; | |
} | |
function empty() { | |
return this == ''; | |
} | |
function blank() { | |
return /^\s*$/.test(this); | |
} | |
function interpolate(object, pattern) { | |
return new Template(this, pattern).evaluate(object); | |
} | |
return { | |
gsub: gsub, | |
sub: sub, | |
scan: scan, | |
truncate: truncate, | |
strip: String.prototype.trim || strip, | |
stripTags: stripTags, | |
stripScripts: stripScripts, | |
extractScripts: extractScripts, | |
evalScripts: evalScripts, | |
escapeHTML: escapeHTML, | |
unescapeHTML: unescapeHTML, | |
toQueryParams: toQueryParams, | |
parseQuery: toQueryParams, | |
toArray: toArray, | |
succ: succ, | |
times: times, | |
camelize: camelize, | |
capitalize: capitalize, | |
underscore: underscore, | |
dasherize: dasherize, | |
inspect: inspect, | |
unfilterJSON: unfilterJSON, | |
isJSON: isJSON, | |
evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, | |
include: include, | |
startsWith: String.prototype.startsWith || startsWith, | |
endsWith: String.prototype.endsWith || endsWith, | |
empty: empty, | |
blank: blank, | |
interpolate: interpolate | |
}; | |
})()); | |
var Template = Class.create({ | |
initialize: function(template, pattern) { | |
this.template = template.toString(); | |
this.pattern = pattern || Template.Pattern; | |
}, | |
evaluate: function(object) { | |
if (object && Object.isFunction(object.toTemplateReplacements)) | |
object = object.toTemplateReplacements(); | |
return this.template.gsub(this.pattern, function(match) { | |
if (object == null) return (match[1] + ''); | |
var before = match[1] || ''; | |
if (before == '\\') return match[2]; | |
var ctx = object, expr = match[3], | |
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; | |
match = pattern.exec(expr); | |
if (match == null) return before; | |
while (match != null) { | |
var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; | |
ctx = ctx[comp]; | |
if (null == ctx || '' == match[3]) break; | |
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); | |
match = pattern.exec(expr); | |
} | |
return before + String.interpret(ctx); | |
}); | |
} | |
}); | |
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; | |
var $break = { }; | |
var Enumerable = (function() { | |
function each(iterator, context) { | |
try { | |
this._each(iterator, context); | |
} catch (e) { | |
if (e != $break) throw e; | |
} | |
return this; | |
} | |
function eachSlice(number, iterator, context) { | |
var index = -number, slices = [], array = this.toArray(); | |
if (number < 1) return array; | |
while ((index += number) < array.length) | |
slices.push(array.slice(index, index+number)); | |
return slices.collect(iterator, context); | |
} | |
function all(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result = true; | |
this.each(function(value, index) { | |
result = result && !!iterator.call(context, value, index, this); | |
if (!result) throw $break; | |
}, this); | |
return result; | |
} | |
function any(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result = false; | |
this.each(function(value, index) { | |
if (result = !!iterator.call(context, value, index, this)) | |
throw $break; | |
}, this); | |
return result; | |
} | |
function collect(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var results = []; | |
this.each(function(value, index) { | |
results.push(iterator.call(context, value, index, this)); | |
}, this); | |
return results; | |
} | |
function detect(iterator, context) { | |
var result; | |
this.each(function(value, index) { | |
if (iterator.call(context, value, index, this)) { | |
result = value; | |
throw $break; | |
} | |
}, this); | |
return result; | |
} | |
function findAll(iterator, context) { | |
var results = []; | |
this.each(function(value, index) { | |
if (iterator.call(context, value, index, this)) | |
results.push(value); | |
}, this); | |
return results; | |
} | |
function grep(filter, iterator, context) { | |
iterator = iterator || Prototype.K; | |
var results = []; | |
if (Object.isString(filter)) | |
filter = new RegExp(RegExp.escape(filter)); | |
this.each(function(value, index) { | |
if (filter.match(value)) | |
results.push(iterator.call(context, value, index, this)); | |
}, this); | |
return results; | |
} | |
function include(object) { | |
if (Object.isFunction(this.indexOf) && this.indexOf(object) != -1) | |
return true; | |
var found = false; | |
this.each(function(value) { | |
if (value == object) { | |
found = true; | |
throw $break; | |
} | |
}); | |
return found; | |
} | |
function inGroupsOf(number, fillWith) { | |
fillWith = Object.isUndefined(fillWith) ? null : fillWith; | |
return this.eachSlice(number, function(slice) { | |
while(slice.length < number) slice.push(fillWith); | |
return slice; | |
}); | |
} | |
function inject(memo, iterator, context) { | |
this.each(function(value, index) { | |
memo = iterator.call(context, memo, value, index, this); | |
}, this); | |
return memo; | |
} | |
function invoke(method) { | |
var args = $A(arguments).slice(1); | |
return this.map(function(value) { | |
return value[method].apply(value, args); | |
}); | |
} | |
function max(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result; | |
this.each(function(value, index) { | |
value = iterator.call(context, value, index, this); | |
if (result == null || value >= result) | |
result = value; | |
}, this); | |
return result; | |
} | |
function min(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result; | |
this.each(function(value, index) { | |
value = iterator.call(context, value, index, this); | |
if (result == null || value < result) | |
result = value; | |
}, this); | |
return result; | |
} | |
function partition(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var trues = [], falses = []; | |
this.each(function(value, index) { | |
(iterator.call(context, value, index, this) ? | |
trues : falses).push(value); | |
}, this); | |
return [trues, falses]; | |
} | |
function pluck(property) { | |
var results = []; | |
this.each(function(value) { | |
results.push(value[property]); | |
}); | |
return results; | |
} | |
function reject(iterator, context) { | |
var results = []; | |
this.each(function(value, index) { | |
if (!iterator.call(context, value, index, this)) | |
results.push(value); | |
}, this); | |
return results; | |
} | |
function sortBy(iterator, context) { | |
return this.map(function(value, index) { | |
return { | |
value: value, | |
criteria: iterator.call(context, value, index, this) | |
}; | |
}, this).sort(function(left, right) { | |
var a = left.criteria, b = right.criteria; | |
return a < b ? -1 : a > b ? 1 : 0; | |
}).pluck('value'); | |
} | |
function toArray() { | |
return this.map(); | |
} | |
function zip() { | |
var iterator = Prototype.K, args = $A(arguments); | |
if (Object.isFunction(args.last())) | |
iterator = args.pop(); | |
var collections = [this].concat(args).map($A); | |
return this.map(function(value, index) { | |
return iterator(collections.pluck(index)); | |
}); | |
} | |
function size() { | |
return this.toArray().length; | |
} | |
function inspect() { | |
return '#<Enumerable:' + this.toArray().inspect() + '>'; | |
} | |
return { | |
each: each, | |
eachSlice: eachSlice, | |
all: all, | |
every: all, | |
any: any, | |
some: any, | |
collect: collect, | |
map: collect, | |
detect: detect, | |
findAll: findAll, | |
select: findAll, | |
filter: findAll, | |
grep: grep, | |
include: include, | |
member: include, | |
inGroupsOf: inGroupsOf, | |
inject: inject, | |
invoke: invoke, | |
max: max, | |
min: min, | |
partition: partition, | |
pluck: pluck, | |
reject: reject, | |
sortBy: sortBy, | |
toArray: toArray, | |
entries: toArray, | |
zip: zip, | |
size: size, | |
inspect: inspect, | |
find: detect | |
}; | |
})(); | |
function $A(iterable) { | |
if (!iterable) return []; | |
if ('toArray' in Object(iterable)) return iterable.toArray(); | |
var length = iterable.length || 0, results = new Array(length); | |
while (length--) results[length] = iterable[length]; | |
return results; | |
} | |
function $w(string) { | |
if (!Object.isString(string)) return []; | |
string = string.strip(); | |
return string ? string.split(/\s+/) : []; | |
} | |
Array.from = $A; | |
(function() { | |
var arrayProto = Array.prototype, | |
slice = arrayProto.slice, | |
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available | |
function each(iterator, context) { | |
for (var i = 0, length = this.length >>> 0; i < length; i++) { | |
if (i in this) iterator.call(context, this[i], i, this); | |
} | |
} | |
if (!_each) _each = each; | |
function clear() { | |
this.length = 0; | |
return this; | |
} | |
function first() { | |
return this[0]; | |
} | |
function last() { | |
return this[this.length - 1]; | |
} | |
function compact() { | |
return this.select(function(value) { | |
return value != null; | |
}); | |
} | |
function flatten() { | |
return this.inject([], function(array, value) { | |
if (Object.isArray(value)) | |
return array.concat(value.flatten()); | |
array.push(value); | |
return array; | |
}); | |
} | |
function without() { | |
var values = slice.call(arguments, 0); | |
return this.select(function(value) { | |
return !values.include(value); | |
}); | |
} | |
function reverse(inline) { | |
return (inline === false ? this.toArray() : this)._reverse(); | |
} | |
function uniq(sorted) { | |
return this.inject([], function(array, value, index) { | |
if (0 == index || (sorted ? array.last() != value : !array.include(value))) | |
array.push(value); | |
return array; | |
}); | |
} | |
function intersect(array) { | |
return this.uniq().findAll(function(item) { | |
return array.indexOf(item) !== -1; | |
}); | |
} | |
function clone() { | |
return slice.call(this, 0); | |
} | |
function size() { | |
return this.length; | |
} | |
function inspect() { | |
return '[' + this.map(Object.inspect).join(', ') + ']'; | |
} | |
function indexOf(item, i) { | |
if (this == null) throw new TypeError(); | |
var array = Object(this), length = array.length >>> 0; | |
if (length === 0) return -1; | |
i = Number(i); | |
if (isNaN(i)) { | |
i = 0; | |
} else if (i !== 0 && isFinite(i)) { | |
i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); | |
} | |
if (i > length) return -1; | |
var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0); | |
for (; k < length; k++) | |
if (k in array && array[k] === item) return k; | |
return -1; | |
} | |
function lastIndexOf(item, i) { | |
if (this == null) throw new TypeError(); | |
var array = Object(this), length = array.length >>> 0; | |
if (length === 0) return -1; | |
if (!Object.isUndefined(i)) { | |
i = Number(i); | |
if (isNaN(i)) { | |
i = 0; | |
} else if (i !== 0 && isFinite(i)) { | |
i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); | |
} | |
} else { | |
i = length; | |
} | |
var k = i >= 0 ? Math.min(i, length - 1) : | |
length - Math.abs(i); | |
for (; k >= 0; k--) | |
if (k in array && array[k] === item) return k; | |
return -1; | |
} | |
function concat(_) { | |
var array = [], items = slice.call(arguments, 0), item, n = 0; | |
items.unshift(this); | |
for (var i = 0, length = items.length; i < length; i++) { | |
item = items[i]; | |
if (Object.isArray(item) && !('callee' in item)) { | |
for (var j = 0, arrayLength = item.length; j < arrayLength; j++) { | |
if (j in item) array[n] = item[j]; | |
n++; | |
} | |
} else { | |
array[n++] = item; | |
} | |
} | |
array.length = n; | |
return array; | |
} | |
function wrapNative(method) { | |
return function() { | |
if (arguments.length === 0) { | |
return method.call(this, Prototype.K); | |
} else if (arguments[0] === undefined) { | |
var args = slice.call(arguments, 1); | |
args.unshift(Prototype.K); | |
return method.apply(this, args); | |
} else { | |
return method.apply(this, arguments); | |
} | |
}; | |
} | |
function map(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var object = Object(this); | |
var results = [], context = arguments[1], n = 0; | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object) { | |
results[n] = iterator.call(context, object[i], i, object); | |
} | |
n++; | |
} | |
results.length = n; | |
return results; | |
} | |
if (arrayProto.map) { | |
map = wrapNative(Array.prototype.map); | |
} | |
function filter(iterator) { | |
if (this == null || !Object.isFunction(iterator)) | |
throw new TypeError(); | |
var object = Object(this); | |
var results = [], context = arguments[1], value; | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object) { | |
value = object[i]; | |
if (iterator.call(context, value, i, object)) { | |
results.push(value); | |
} | |
} | |
} | |
return results; | |
} | |
if (arrayProto.filter) { | |
filter = Array.prototype.filter; | |
} | |
function some(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var context = arguments[1]; | |
var object = Object(this); | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object && iterator.call(context, object[i], i, object)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
if (arrayProto.some) { | |
var some = wrapNative(Array.prototype.some); | |
} | |
function every(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var context = arguments[1]; | |
var object = Object(this); | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object && !iterator.call(context, object[i], i, object)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
if (arrayProto.every) { | |
var every = wrapNative(Array.prototype.every); | |
} | |
var _reduce = arrayProto.reduce; | |
function inject(memo, iterator) { | |
iterator = iterator || Prototype.K; | |
var context = arguments[2]; | |
return _reduce.call(this, iterator.bind(context), memo); | |
} | |
if (!arrayProto.reduce) { | |
var inject = Enumerable.inject; | |
} | |
Object.extend(arrayProto, Enumerable); | |
if (!arrayProto._reverse) | |
arrayProto._reverse = arrayProto.reverse; | |
Object.extend(arrayProto, { | |
_each: _each, | |
map: map, | |
collect: map, | |
select: filter, | |
filter: filter, | |
findAll: filter, | |
some: some, | |
any: some, | |
every: every, | |
all: every, | |
inject: inject, | |
clear: clear, | |
first: first, | |
last: last, | |
compact: compact, | |
flatten: flatten, | |
without: without, | |
reverse: reverse, | |
uniq: uniq, | |
intersect: intersect, | |
clone: clone, | |
toArray: clone, | |
size: size, | |
inspect: inspect | |
}); | |
var CONCAT_ARGUMENTS_BUGGY = (function() { | |
return [].concat(arguments)[0][0] !== 1; | |
})(1,2); | |
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; | |
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; | |
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; | |
})(); | |
function $H(object) { | |
return new Hash(object); | |
}; | |
var Hash = Class.create(Enumerable, (function() { | |
function initialize(object) { | |
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); | |
} | |
function _each(iterator, context) { | |
var i = 0; | |
for (var key in this._object) { | |
var value = this._object[key], pair = [key, value]; | |
pair.key = key; | |
pair.value = value; | |
iterator.call(context, pair, i); | |
i++; | |
} | |
} | |
function set(key, value) { | |
return this._object[key] = value; | |
} | |
function get(key) { | |
if (this._object[key] !== Object.prototype[key]) | |
return this._object[key]; | |
} | |
function unset(key) { | |
var value = this._object[key]; | |
delete this._object[key]; | |
return value; | |
} | |
function toObject() { | |
return Object.clone(this._object); | |
} | |
function keys() { | |
return this.pluck('key'); | |
} | |
function values() { | |
return this.pluck('value'); | |
} | |
function index(value) { | |
var match = this.detect(function(pair) { | |
return pair.value === value; | |
}); | |
return match && match.key; | |
} | |
function merge(object) { | |
return this.clone().update(object); | |
} | |
function update(object) { | |
return new Hash(object).inject(this, function(result, pair) { | |
result.set(pair.key, pair.value); | |
return result; | |
}); | |
} | |
function toQueryPair(key, value) { | |
if (Object.isUndefined(value)) return key; | |
value = String.interpret(value); | |
value = value.gsub(/(\r)?\n/, '\r\n'); | |
value = encodeURIComponent(value); | |
value = value.gsub(/%20/, '+'); | |
return key + '=' + value; | |
} | |
function toQueryString() { | |
return this.inject([], function(results, pair) { | |
var key = encodeURIComponent(pair.key), values = pair.value; | |
if (values && typeof values == 'object') { | |
if (Object.isArray(values)) { | |
var queryValues = []; | |
for (var i = 0, len = values.length, value; i < len; i++) { | |
value = values[i]; | |
queryValues.push(toQueryPair(key, value)); | |
} | |
return results.concat(queryValues); | |
} | |
} else results.push(toQueryPair(key, values)); | |
return results; | |
}).join('&'); | |
} | |
function inspect() { | |
return '#<Hash:{' + this.map(function(pair) { | |
return pair.map(Object.inspect).join(': '); | |
}).join(', ') + '}>'; | |
} | |
function clone() { | |
return new Hash(this); | |
} | |
return { | |
initialize: initialize, | |
_each: _each, | |
set: set, | |
get: get, | |
unset: unset, | |
toObject: toObject, | |
toTemplateReplacements: toObject, | |
keys: keys, | |
values: values, | |
index: index, | |
merge: merge, | |
update: update, | |
toQueryString: toQueryString, | |
inspect: inspect, | |
toJSON: toObject, | |
clone: clone | |
}; | |
})()); | |
Hash.from = $H; | |
Object.extend(Number.prototype, (function() { | |
function toColorPart() { | |
return this.toPaddedString(2, 16); | |
} | |
function succ() { | |
return this + 1; | |
} | |
function times(iterator, context) { | |
$R(0, this, true).each(iterator, context); | |
return this; | |
} | |
function toPaddedString(length, radix) { | |
var string = this.toString(radix || 10); | |
return '0'.times(length - string.length) + string; | |
} | |
function abs() { | |
return Math.abs(this); | |
} | |
function round() { | |
return Math.round(this); | |
} | |
function ceil() { | |
return Math.ceil(this); | |
} | |
function floor() { | |
return Math.floor(this); | |
} | |
return { | |
toColorPart: toColorPart, | |
succ: succ, | |
times: times, | |
toPaddedString: toPaddedString, | |
abs: abs, | |
round: round, | |
ceil: ceil, | |
floor: floor | |
}; | |
})()); | |
function $R(start, end, exclusive) { | |
return new ObjectRange(start, end, exclusive); | |
} | |
var ObjectRange = Class.create(Enumerable, (function() { | |
function initialize(start, end, exclusive) { | |
this.start = start; | |
this.end = end; | |
this.exclusive = exclusive; | |
} | |
function _each(iterator, context) { | |
var value = this.start, i; | |
for (i = 0; this.include(value); i++) { | |
iterator.call(context, value, i); | |
value = value.succ(); | |
} | |
} | |
function include(value) { | |
if (value < this.start) | |
return false; | |
if (this.exclusive) | |
return value < this.end; | |
return value <= this.end; | |
} | |
return { | |
initialize: initialize, | |
_each: _each, | |
include: include | |
}; | |
})()); | |
var Abstract = { }; | |
var Try = { | |
these: function() { | |
var returnValue; | |
for (var i = 0, length = arguments.length; i < length; i++) { | |
var lambda = arguments[i]; | |
try { | |
returnValue = lambda(); | |
break; | |
} catch (e) { } | |
} | |
return returnValue; | |
} | |
}; | |
var Ajax = { | |
getTransport: function() { | |
return Try.these( | |
function() {return new XMLHttpRequest()}, | |
function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | |
function() {return new ActiveXObject('Microsoft.XMLHTTP')} | |
) || false; | |
}, | |
activeRequestCount: 0 | |
}; | |
Ajax.Responders = { | |
responders: [], | |
_each: function(iterator, context) { | |
this.responders._each(iterator, context); | |
}, | |
register: function(responder) { | |
if (!this.include(responder)) | |
this.responders.push(responder); | |
}, | |
unregister: function(responder) { | |
this.responders = this.responders.without(responder); | |
}, | |
dispatch: function(callback, request, transport, json) { | |
this.each(function(responder) { | |
if (Object.isFunction(responder[callback])) { | |
try { | |
responder[callback].apply(responder, [request, transport, json]); | |
} catch (e) { } | |
} | |
}); | |
} | |
}; | |
Object.extend(Ajax.Responders, Enumerable); | |
Ajax.Responders.register({ | |
onCreate: function() { Ajax.activeRequestCount++ }, | |
onComplete: function() { Ajax.activeRequestCount-- } | |
}); | |
Ajax.Base = Class.create({ | |
initialize: function(options) { | |
this.options = { | |
method: 'post', | |
asynchronous: true, | |
contentType: 'application/x-www-form-urlencoded', | |
encoding: 'UTF-8', | |
parameters: '', | |
evalJSON: true, | |
evalJS: true | |
}; | |
Object.extend(this.options, options || { }); | |
this.options.method = this.options.method.toLowerCase(); | |
if (Object.isHash(this.options.parameters)) | |
this.options.parameters = this.options.parameters.toObject(); | |
} | |
}); | |
Ajax.Request = Class.create(Ajax.Base, { | |
_complete: false, | |
initialize: function($super, url, options) { | |
$super(options); | |
this.transport = Ajax.getTransport(); | |
this.request(url); | |
}, | |
request: function(url) { | |
this.url = url; | |
this.method = this.options.method; | |
var params = Object.isString(this.options.parameters) ? | |
this.options.parameters : | |
Object.toQueryString(this.options.parameters); | |
if (!['get', 'post'].include(this.method)) { | |
params += (params ? '&' : '') + "_method=" + this.method; | |
this.method = 'post'; | |
} | |
if (params && this.method === 'get') { | |
this.url += (this.url.include('?') ? '&' : '?') + params; | |
} | |
this.parameters = params.toQueryParams(); | |
try { | |
var response = new Ajax.Response(this); | |
if (this.options.onCreate) this.options.onCreate(response); | |
Ajax.Responders.dispatch('onCreate', this, response); | |
this.transport.open(this.method.toUpperCase(), this.url, | |
this.options.asynchronous); | |
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); | |
this.transport.onreadystatechange = this.onStateChange.bind(this); | |
this.setRequestHeaders(); | |
this.body = this.method == 'post' ? (this.options.postBody || params) : null; | |
this.transport.send(this.body); | |
/* Force Firefox to handle ready state 4 for synchronous requests */ | |
if (!this.options.asynchronous && this.transport.overrideMimeType) | |
this.onStateChange(); | |
} | |
catch (e) { | |
this.dispatchException(e); | |
} | |
}, | |
onStateChange: function() { | |
var readyState = this.transport.readyState; | |
if (readyState > 1 && !((readyState == 4) && this._complete)) | |
this.respondToReadyState(this.transport.readyState); | |
}, | |
setRequestHeaders: function() { | |
var headers = { | |
'X-Requested-With': 'XMLHttpRequest', | |
'X-Prototype-Version': Prototype.Version, | |
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' | |
}; | |
if (this.method == 'post') { | |
headers['Content-type'] = this.options.contentType + | |
(this.options.encoding ? '; charset=' + this.options.encoding : ''); | |
/* Force "Connection: close" for older Mozilla browsers to work | |
* around a bug where XMLHttpRequest sends an incorrect | |
* Content-length header. See Mozilla Bugzilla #246651. | |
*/ | |
if (this.transport.overrideMimeType && | |
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) | |
headers['Connection'] = 'close'; | |
} | |
if (typeof this.options.requestHeaders == 'object') { | |
var extras = this.options.requestHeaders; | |
if (Object.isFunction(extras.push)) | |
for (var i = 0, length = extras.length; i < length; i += 2) | |
headers[extras[i]] = extras[i+1]; | |
else | |
$H(extras).each(function(pair) { headers[pair.key] = pair.value }); | |
} | |
for (var name in headers) | |
if (headers[name] != null) | |
this.transport.setRequestHeader(name, headers[name]); | |
}, | |
success: function() { | |
var status = this.getStatus(); | |
return !status || (status >= 200 && status < 300) || status == 304; | |
}, | |
getStatus: function() { | |
try { | |
if (this.transport.status === 1223) return 204; | |
return this.transport.status || 0; | |
} catch (e) { return 0 } | |
}, | |
respondToReadyState: function(readyState) { | |
var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); | |
if (state == 'Complete') { | |
try { | |
this._complete = true; | |
(this.options['on' + response.status] | |
|| this.options['on' + (this.success() ? 'Success' : 'Failure')] | |
|| Prototype.emptyFunction)(response, response.headerJSON); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
var contentType = response.getHeader('Content-type'); | |
if (this.options.evalJS == 'force' | |
|| (this.options.evalJS && this.isSameOrigin() && contentType | |
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) | |
this.evalResponse(); | |
} | |
try { | |
(this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); | |
Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
if (state == 'Complete') { | |
this.transport.onreadystatechange = Prototype.emptyFunction; | |
} | |
}, | |
isSameOrigin: function() { | |
var m = this.url.match(/^\s*https?:\/\/[^\/]*/); | |
return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ | |
protocol: location.protocol, | |
domain: document.domain, | |
port: location.port ? ':' + location.port : '' | |
})); | |
}, | |
getHeader: function(name) { | |
try { | |
return this.transport.getResponseHeader(name) || null; | |
} catch (e) { return null; } | |
}, | |
evalResponse: function() { | |
try { | |
return eval((this.transport.responseText || '').unfilterJSON()); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
}, | |
dispatchException: function(exception) { | |
(this.options.onException || Prototype.emptyFunction)(this, exception); | |
Ajax.Responders.dispatch('onException', this, exception); | |
} | |
}); | |
Ajax.Request.Events = | |
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; | |
Ajax.Response = Class.create({ | |
initialize: function(request){ | |
this.request = request; | |
var transport = this.transport = request.transport, | |
readyState = this.readyState = transport.readyState; | |
if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { | |
this.status = this.getStatus(); | |
this.statusText = this.getStatusText(); | |
this.responseText = String.interpret(transport.responseText); | |
this.headerJSON = this._getHeaderJSON(); | |
} | |
if (readyState == 4) { | |
var xml = transport.responseXML; | |
this.responseXML = Object.isUndefined(xml) ? null : xml; | |
this.responseJSON = this._getResponseJSON(); | |
} | |
}, | |
status: 0, | |
statusText: '', | |
getStatus: Ajax.Request.prototype.getStatus, | |
getStatusText: function() { | |
try { | |
return this.transport.statusText || ''; | |
} catch (e) { return '' } | |
}, | |
getHeader: Ajax.Request.prototype.getHeader, | |
getAllHeaders: function() { | |
try { | |
return this.getAllResponseHeaders(); | |
} catch (e) { return null } | |
}, | |
getResponseHeader: function(name) { | |
return this.transport.getResponseHeader(name); | |
}, | |
getAllResponseHeaders: function() { | |
return this.transport.getAllResponseHeaders(); | |
}, | |
_getHeaderJSON: function() { | |
var json = this.getHeader('X-JSON'); | |
if (!json) return null; | |
try { | |
json = decodeURIComponent(escape(json)); | |
} catch(e) { | |
} | |
try { | |
return json.evalJSON(this.request.options.sanitizeJSON || | |
!this.request.isSameOrigin()); | |
} catch (e) { | |
this.request.dispatchException(e); | |
} | |
}, | |
_getResponseJSON: function() { | |
var options = this.request.options; | |
if (!options.evalJSON || (options.evalJSON != 'force' && | |
!(this.getHeader('Content-type') || '').include('application/json')) || | |
this.responseText.blank()) | |
return null; | |
try { | |
return this.responseText.evalJSON(options.sanitizeJSON || | |
!this.request.isSameOrigin()); | |
} catch (e) { | |
this.request.dispatchException(e); | |
} | |
} | |
}); | |
Ajax.Updater = Class.create(Ajax.Request, { | |
initialize: function($super, container, url, options) { | |
this.container = { | |
success: (container.success || container), | |
failure: (container.failure || (container.success ? null : container)) | |
}; | |
options = Object.clone(options); | |
var onComplete = options.onComplete; | |
options.onComplete = (function(response, json) { | |
this.updateContent(response.responseText); | |
if (Object.isFunction(onComplete)) onComplete(response, json); | |
}).bind(this); | |
$super(url, options); | |
}, | |
updateContent: function(responseText) { | |
var receiver = this.container[this.success() ? 'success' : 'failure'], | |
options = this.options; | |
if (!options.evalScripts) responseText = responseText.stripScripts(); | |
if (receiver = $(receiver)) { | |
if (options.insertion) { | |
if (Object.isString(options.insertion)) { | |
var insertion = { }; insertion[options.insertion] = responseText; | |
receiver.insert(insertion); | |
} | |
else options.insertion(receiver, responseText); | |
} | |
else receiver.update(responseText); | |
} | |
} | |
}); | |
Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { | |
initialize: function($super, container, url, options) { | |
$super(options); | |
this.onComplete = this.options.onComplete; | |
this.frequency = (this.options.frequency || 2); | |
this.decay = (this.options.decay || 1); | |
this.updater = { }; | |
this.container = container; | |
this.url = url; | |
this.start(); | |
}, | |
start: function() { | |
this.options.onComplete = this.updateComplete.bind(this); | |
this.onTimerEvent(); | |
}, | |
stop: function() { | |
this.updater.options.onComplete = undefined; | |
clearTimeout(this.timer); | |
(this.onComplete || Prototype.emptyFunction).apply(this, arguments); | |
}, | |
updateComplete: function(response) { | |
if (this.options.decay) { | |
this.decay = (response.responseText == this.lastText ? | |
this.decay * this.options.decay : 1); | |
this.lastText = response.responseText; | |
} | |
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); | |
}, | |
onTimerEvent: function() { | |
this.updater = new Ajax.Updater(this.container, this.url, this.options); | |
} | |
}); | |
(function(GLOBAL) { | |
var UNDEFINED; | |
var SLICE = Array.prototype.slice; | |
var DIV = document.createElement('div'); | |
function $(element) { | |
if (arguments.length > 1) { | |
for (var i = 0, elements = [], length = arguments.length; i < length; i++) | |
elements.push($(arguments[i])); | |
return elements; | |
} | |
if (Object.isString(element)) | |
element = document.getElementById(element); | |
return Element.extend(element); | |
} | |
GLOBAL.$ = $; | |
if (!GLOBAL.Node) GLOBAL.Node = {}; | |
if (!GLOBAL.Node.ELEMENT_NODE) { | |
Object.extend(GLOBAL.Node, { | |
ELEMENT_NODE: 1, | |
ATTRIBUTE_NODE: 2, | |
TEXT_NODE: 3, | |
CDATA_SECTION_NODE: 4, | |
ENTITY_REFERENCE_NODE: 5, | |
ENTITY_NODE: 6, | |
PROCESSING_INSTRUCTION_NODE: 7, | |
COMMENT_NODE: 8, | |
DOCUMENT_NODE: 9, | |
DOCUMENT_TYPE_NODE: 10, | |
DOCUMENT_FRAGMENT_NODE: 11, | |
NOTATION_NODE: 12 | |
}); | |
} | |
var ELEMENT_CACHE = {}; | |
function shouldUseCreationCache(tagName, attributes) { | |
if (tagName === 'select') return false; | |
if ('type' in attributes) return false; | |
return true; | |
} | |
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ | |
try { | |
var el = document.createElement('<input name="x">'); | |
return el.tagName.toLowerCase() === 'input' && el.name === 'x'; | |
} | |
catch(err) { | |
return false; | |
} | |
})(); | |
var oldElement = GLOBAL.Element; | |
function Element(tagName, attributes) { | |
attributes = attributes || {}; | |
tagName = tagName.toLowerCase(); | |
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { | |
tagName = '<' + tagName + ' name="' + attributes.name + '">'; | |
delete attributes.name; | |
return Element.writeAttribute(document.createElement(tagName), attributes); | |
} | |
if (!ELEMENT_CACHE[tagName]) | |
ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName)); | |
var node = shouldUseCreationCache(tagName, attributes) ? | |
ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName); | |
return Element.writeAttribute(node, attributes); | |
} | |
GLOBAL.Element = Element; | |
Object.extend(GLOBAL.Element, oldElement || {}); | |
if (oldElement) GLOBAL.Element.prototype = oldElement.prototype; | |
Element.Methods = { ByTag: {}, Simulated: {} }; | |
var methods = {}; | |
var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' }; | |
function inspect(element) { | |
element = $(element); | |
var result = '<' + element.tagName.toLowerCase(); | |
var attribute, value; | |
for (var property in INSPECT_ATTRIBUTES) { | |
attribute = INSPECT_ATTRIBUTES[property]; | |
value = (element[property] || '').toString(); | |
if (value) result += ' ' + attribute + '=' + value.inspect(true); | |
} | |
return result + '>'; | |
} | |
methods.inspect = inspect; | |
function visible(element) { | |
return $(element).style.display !== 'none'; | |
} | |
function toggle(element, bool) { | |
element = $(element); | |
if (Object.isUndefined(bool)) | |
bool = !Element.visible(element); | |
Element[bool ? 'show' : 'hide'](element); | |
return element; | |
} | |
function hide(element) { | |
element = $(element); | |
element.style.display = 'none'; | |
return element; | |
} | |
function show(element) { | |
element = $(element); | |
element.style.display = ''; | |
return element; | |
} | |
Object.extend(methods, { | |
visible: visible, | |
toggle: toggle, | |
hide: hide, | |
show: show | |
}); | |
function remove(element) { | |
element = $(element); | |
element.parentNode.removeChild(element); | |
return element; | |
} | |
var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ | |
var el = document.createElement("select"), | |
isBuggy = true; | |
el.innerHTML = "<option value=\"test\">test</option>"; | |
if (el.options && el.options[0]) { | |
isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; | |
} | |
el = null; | |
return isBuggy; | |
})(); | |
var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ | |
try { | |
var el = document.createElement("table"); | |
if (el && el.tBodies) { | |
el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; | |
var isBuggy = typeof el.tBodies[0] == "undefined"; | |
el = null; | |
return isBuggy; | |
} | |
} catch (e) { | |
return true; | |
} | |
})(); | |
var LINK_ELEMENT_INNERHTML_BUGGY = (function() { | |
try { | |
var el = document.createElement('div'); | |
el.innerHTML = "<link />"; | |
var isBuggy = (el.childNodes.length === 0); | |
el = null; | |
return isBuggy; | |
} catch(e) { | |
return true; | |
} | |
})(); | |
var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || | |
TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; | |
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { | |
var s = document.createElement("script"), | |
isBuggy = false; | |
try { | |
s.appendChild(document.createTextNode("")); | |
isBuggy = !s.firstChild || | |
s.firstChild && s.firstChild.nodeType !== 3; | |
} catch (e) { | |
isBuggy = true; | |
} | |
s = null; | |
return isBuggy; | |
})(); | |
function update(element, content) { | |
element = $(element); | |
var descendants = element.getElementsByTagName('*'), | |
i = descendants.length; | |
while (i--) purgeElement(descendants[i]); | |
if (content && content.toElement) | |
content = content.toElement(); | |
if (Object.isElement(content)) | |
return element.update().insert(content); | |
content = Object.toHTML(content); | |
var tagName = element.tagName.toUpperCase(); | |
if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { | |
element.text = content; | |
return element; | |
} | |
if (ANY_INNERHTML_BUGGY) { | |
if (tagName in INSERTION_TRA |
/* Zepto v1.1.4 - zepto event ajax form ie - zeptojs.com/license */ | |
var Zepto=function(){function L(t){return null==t?String(t):j[S.call(t)]||"object"}function Z(t){return"function"==L(t)}function $(t){return null!=t&&t==t.window}function _(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function D(t){return"object"==L(t)}function R(t){return D(t)&&!$(t)&&Object.getPrototypeOf(t)==Object.prototype}function M(t){return"number"==typeof t.length}function k(t){return s.call(t,function(t){return null!=t})}function z(t){return t.length>0?n.fn.concat.apply([],t):t}function F(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function q(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function H(t,e){return"number"!=typeof e||c[F(t)]?e:e+"px"}function I(t){var e,n;return u[t]||(e=a.createElement(t),a.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),u[t]=n),u[t]}function V(t){return"children"in t?o.call(t.children):n.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function B(n,i,r){for(e in i)r&&(R(i[e])||A(i[e]))?(R(i[e])&&!R(n[e])&&(n[e]={}),A(i[e])&&!A(n[e])&&(n[e]=[]),B(n[e],i[e],r)):i[e]!==t&&(n[e]=i[e])}function U(t,e){return null==e?n(t):n(t).filter(e)}function J(t,e,n,i){return Z(e)?e.call(t,n,i):e}function X(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function W(e,n){var i=e.className,r=i&&i.baseVal!==t;return n===t?r?i.baseVal:i:void(r?i.baseVal=n:e.className=n)}function Y(t){var e;try{return t?"true"==t||("false"==t?!1:"null"==t?null:/^0/.test(t)||isNaN(e=Number(t))?/^[\[\{]/.test(t)?n.parseJSON(t):t:e):t}catch(i){return t}}function G(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)G(t.childNodes[n],e)}var t,e,n,i,C,N,r=[],o=r.slice,s=r.filter,a=window.document,u={},f={},c={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,h=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,d=/^(?:body|html)$/i,m=/([A-Z])/g,g=["val","css","html","text","data","width","height","offset"],v=["after","prepend","before","append"],y=a.createElement("table"),x=a.createElement("tr"),b={tr:a.createElement("tbody"),tbody:y,thead:y,tfoot:y,td:x,th:x,"*":a.createElement("div")},w=/complete|loaded|interactive/,E=/^[\w-]*$/,j={},S=j.toString,T={},O=a.createElement("div"),P={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},A=Array.isArray||function(t){return t instanceof Array};return T.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;return o&&(r=O).appendChild(t),i=~T.qsa(r,e).indexOf(t),o&&O.removeChild(t),i},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})},T.fragment=function(e,i,r){var s,u,f;return h.test(e)&&(s=n(a.createElement(RegExp.$1))),s||(e.replace&&(e=e.replace(p,"<$1></$2>")),i===t&&(i=l.test(e)&&RegExp.$1),i in b||(i="*"),f=b[i],f.innerHTML=""+e,s=n.each(o.call(f.childNodes),function(){f.removeChild(this)})),R(r)&&(u=n(s),n.each(r,function(t,e){g.indexOf(t)>-1?u[t](e):u.attr(t,e)})),s},T.Z=function(t,e){return t=t||[],t.__proto__=n.fn,t.selector=e||"",t},T.isZ=function(t){return t instanceof T.Z},T.init=function(e,i){var r;if(!e)return T.Z();if("string"==typeof e)if(e=e.trim(),"<"==e[0]&&l.test(e))r=T.fragment(e,RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}else{if(Z(e))return n(a).ready(e);if(T.isZ(e))return e;if(A(e))r=k(e);else if(D(e))r=[e],e=null;else if(l.test(e))r=T.fragment(e.trim(),RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}}return T.Z(r,e)},n=function(t,e){return T.init(t,e)},n.extend=function(t){var e,n=o.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){B(t,n,e)}),t},T.qsa=function(t,e){var n,i="#"==e[0],r=!i&&"."==e[0],s=i||r?e.slice(1):e,a=E.test(s);return _(t)&&a&&i?(n=t.getElementById(s))?[n]:[]:1!==t.nodeType&&9!==t.nodeType?[]:o.call(a&&!i?r?t.getElementsByClassName(s):t.getElementsByTagName(e):t.querySelectorAll(e))},n.contains=a.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},n.type=L,n.isFunction=Z,n.isWindow=$,n.isArray=A,n.isPlainObject=R,n.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)},n.camelCase=C,n.trim=function(t){return null==t?"":String.prototype.trim.call(t)},n.uuid=0,n.support={},n.expr={},n.map=function(t,e){var n,r,o,i=[];if(M(t))for(r=0;r<t.length;r++)n=e(t[r],r),null!=n&&i.push(n);else for(o in t)n=e(t[o],o),null!=n&&i.push(n);return z(i)},n.each=function(t,e){var n,i;if(M(t)){for(n=0;n<t.length;n++)if(e.call(t[n],n,t[n])===!1)return t}else for(i in t)if(e.call(t[i],i,t[i])===!1)return t;return t},n.grep=function(t,e){return s.call(t,e)},window.JSON&&(n.parseJSON=JSON.parse),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(t,e){j["[object "+e+"]"]=e.toLowerCase()}),n.fn={forEach:r.forEach,reduce:r.reduce,push:r.push,sort:r.sort,indexOf:r.indexOf,concat:r.concat,map:function(t){return n(n.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return n(o.apply(this,arguments))},ready:function(t){return w.test(a.readyState)&&a.body?t(n):a.addEventListener("DOMContentLoaded",function(){t(n)},!1),this},get:function(e){return e===t?o.call(this):this[e>=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return r.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return Z(t)?this.not(this.not(t)):n(s.call(this,function(e){return T.matches(e,t)}))},add:function(t,e){return n(N(this.concat(n(t,e))))},is:function(t){return this.length>0&&T.matches(this[0],t)},not:function(e){var i=[];if(Z(e)&&e.call!==t)this.each(function(t){e.call(this,t)||i.push(this)});else{var r="string"==typeof e?this.filter(e):M(e)&&Z(e.item)?o.call(e):n(e);this.forEach(function(t){r.indexOf(t)<0&&i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return D(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!D(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!D(t)?t:n(t)},find:function(t){var e,i=this;return e=t?"object"==typeof t?n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})}):1==this.length?n(T.qsa(this[0],t)):this.map(function(){return T.qsa(this,t)}):[]},closest:function(t,e){var i=this[0],r=!1;for("object"==typeof t&&(r=n(t));i&&!(r?r.indexOf(i)>=0:T.matches(i,t));)i=i!==e&&!_(i)&&i.parentNode;return n(i)},parents:function(t){for(var e=[],i=this;i.length>0;)i=n.map(i,function(t){return(t=t.parentNode)&&!_(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return U(e,t)},parent:function(t){return U(N(this.pluck("parentNode")),t)},children:function(t){return U(this.map(function(){return V(this)}),t)},contents:function(){return this.map(function(){return o.call(this.childNodes)})},siblings:function(t){return U(this.map(function(t,e){return s.call(V(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=I(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=Z(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));for(var e;(e=t.children()).length;)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=Z(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){return this.parent().each(function(){n(this).replaceWith(n(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?"none"==i.css("display"):e)?i.show():i.hide()})},prev:function(t){return n(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return n(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(J(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=J(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this[0].textContent:null},attr:function(n,i){var r;return"string"!=typeof n||1 in arguments?this.each(function(t){if(1===this.nodeType)if(D(n))for(e in n)X(this,e,n[e]);else X(this,n,J(this,i,t,this.getAttribute(n)))}):this.length&&1===this[0].nodeType?!(r=this[0].getAttribute(n))&&n in this[0]?this[0][n]:r:t},removeAttr:function(t){return this.each(function(){1===this.nodeType&&X(this,t)})},prop:function(t,e){return t=P[t]||t,1 in arguments?this.each(function(n){this[t]=J(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(e,n){var i="data-"+e.replace(m,"-$1").toLowerCase(),r=1 in arguments?this.attr(i,n):this.attr(i);return null!==r?Y(r):t},val:function(t){return 0 in arguments?this.each(function(e){this.value=J(this,t,e,this.value)}):this[0]&&(this[0].multiple?n(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=J(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};"static"==i.css("position")&&(s.position="relative"),i.css(s)});if(!this.length)return null;var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r=this[0],o=getComputedStyle(r,"");if(!r)return;if("string"==typeof t)return r.style[C(t)]||o.getPropertyValue(t);if(A(t)){var s={};return n.each(A(t)?t:[t],function(t,e){s[e]=r.style[C(e)]||o.getPropertyValue(e)}),s}}var a="";if("string"==L(t))i||0===i?a=F(t)+":"+H(t,i):this.each(function(){this.style.removeProperty(F(t))});else for(e in t)t[e]||0===t[e]?a+=F(e)+":"+H(e,t[e])+";":this.each(function(){this.style.removeProperty(F(e))});return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?r.some.call(this,function(t){return this.test(W(t))},q(t)):!1},addClass:function(t){return t?this.each(function(e){i=[];var r=W(this),o=J(this,t,e,r);o.split(/\s+/g).forEach(function(t){n(this).hasClass(t)||i.push(t)},this),i.length&&W(this,r+(r?" ":"")+i.join(" "))}):this},removeClass:function(e){return this.each(function(n){return e===t?W(this,""):(i=W(this),J(this,e,n,i).split(/\s+/g).forEach(function(t){i=i.replace(q(t)," ")}),void W(this,i.trim()))})},toggleClass:function(e,i){return e?this.each(function(r){var o=n(this),s=J(this,e,r,W(this));s.split(/\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})}):this},scrollTop:function(e){if(this.length){var n="scrollTop"in this[0];return e===t?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})}},scrollLeft:function(e){if(this.length){var n="scrollLeft"in this[0];return e===t?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),i=this.offset(),r=d.test(e[0].nodeName)?{top:0,left:0}:e.offset();return i.top-=parseFloat(n(t).css("margin-top"))||0,i.left-=parseFloat(n(t).css("margin-left"))||0,r.top+=parseFloat(n(e[0]).css("border-top-width"))||0,r.left+=parseFloat(n(e[0]).css("border-left-width"))||0,{top:i.top-r.top,left:i.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||a.body;t&&!d.test(t.nodeName)&&"static"==n(t).css("position");)t=t.offsetParent;return t})}},n.fn.detach=n.fn.remove,["width","height"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];return r===t?$(s)?s["inner"+i]:_(s)?s.documentElement["scroll"+i]:(o=this.offset())&&o[e]:this.each(function(t){s=n(this),s.css(e,J(this,r,t,s[e]()))})}}),v.forEach(function(t,e){var i=e%2;n.fn[t]=function(){var t,o,r=n.map(arguments,function(e){return t=L(e),"object"==t||"array"==t||null==e?e:T.fragment(e)}),s=this.length>1;return r.length<1?this:this.each(function(t,u){o=i?u:u.parentNode,u=0==e?u.nextSibling:1==e?u.firstChild:2==e?u:null;var f=n.contains(a.documentElement,o);r.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!o)return n(t).remove();o.insertBefore(t,u),f&&G(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},n.fn[i?t+"To":"insert"+(e?"Before":"After")]=function(e){return n(e)[t](this),this}}),T.Z.prototype=n.fn,T.uniq=N,T.deserializeValue=Y,n.zepto=T,n}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){if(e=p(e),e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return!(!t||e.e&&t.e!=e.e||e.ns&&!r.test(t.ns)||n&&l(t.fn)!==l(n)||i&&t.sel!=i)})}function p(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function d(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!u&&t.e in f||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\s/).forEach(function(i){if("ready"==i)return t(document).ready(r);var s=p(i);s.fn=r,s.sel=a,s.e in c&&(r=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?s.fn.apply(this,arguments):void 0}),s.del=u;var l=u||r;s.proxy=function(t){if(t=j(t),!t.isImmediatePropagationStopped()){t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));return i===!1&&(t.preventDefault(),t.stopPropagation()),i}},s.i=d.length,d.push(s),"addEventListener"in e&&e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||"").split(/\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i],"removeEventListener"in t&&t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}function j(e,i){return(i||!e.isDefaultPrevented)&&(i||(i=e),t.each(E,function(t,n){var r=i[t];e[t]=function(){return this[n]=x,r&&r.apply(i,arguments)},e[n]=b}),(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?i.returnValue===!1:i.getPreventDefault&&i.getPreventDefault())&&(e.isDefaultPrevented=x)),e}function S(t){var e,i={originalEvent:t};for(e in t)w.test(e)||t[e]===n||(i[e]=t[e]);return j(i,t)}var n,e=1,i=Array.prototype.slice,r=t.isFunction,o=function(t){return"string"==typeof t},s={},a={},u="onfocusin"in window,f={focus:"focusin",blur:"focusout"},c={mouseenter:"mouseover",mouseleave:"mouseout"};a.click=a.mousedown=a.mouseup=a.mousemove="MouseEvents",t.event={add:v,remove:y},t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};return a._zid=l(e),a}if(o(n))return s?(s.unshift(e[n],e),t.proxy.apply(null,s)):t.proxy(e[n],e);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var x=function(){return!0},b=function(){return!1},w=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,s,a,u,f){var c,l,h=this;return e&&!o(e)?(t.each(e,function(t,e){h.on(t,s,a,e,f)}),h):(o(s)||r(u)||u===!1||(u=a,a=s,s=n),(r(a)||a===!1)&&(u=a,a=n),u===!1&&(u=b),h.each(function(n,r){f&&(c=function(t){return y(r,t.type,u),u.apply(this,arguments)}),s&&(l=function(e){var n,o=t(e.target).closest(s,r).get(0);return o&&o!==r?(n=t.extend(S(e),{currentTarget:o,liveFired:r}),(c||u).apply(o,[n].concat(i.call(arguments,1)))):void 0}),v(r,e,u,a,s,l||c)}))},t.fn.off=function(e,i,s){var a=this;return e&&!o(e)?(t.each(e,function(t,e){a.off(t,i,e)}),a):(o(i)||r(s)||s===!1||(s=i,i=n),s===!1&&(s=b),a.each(function(){y(this,e,s,i)}))},t.fn.trigger=function(e,n){return e=o(e)||t.isPlainObject(e)?t.Event(e):j(e),e._args=n,this.each(function(){"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,n){var i,r;return this.each(function(s,a){i=S(o(e)?t.Event(e):e),i._args=n,i.target=a,t.each(h(a,e.type||e),function(t,e){return r=e.proxy(i),i.isImmediatePropagationStopped()?!1:void 0})}),r},"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.trigger(e)}}),["focus","blur"].forEach(function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.each(function(){try{this[e]()}catch(t){}}),this}}),t.Event=function(t,e){o(t)||(e=t,t=e.type);var n=document.createEvent(a[t]||"Events"),i=!0;if(e)for(var r in e)"bubbles"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),j(n)}}(Zepto),function(t){function l(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function h(t,e,i,r){return t.global?l(e||n,i,r):void 0}function p(e){e.global&&0===t.active++&&h(e,null,"ajaxStart")}function d(e){e.global&&!--t.active&&h(e,null,"ajaxStop")}function m(t,e){var n=e.context;return e.beforeSend.call(n,t,e)===!1||h(e,n,"ajaxBeforeSend",[t,e])===!1?!1:void h(e,n,"ajaxSend",[t,e])}function g(t,e,n,i){var r=n.context,o="success";n.success.call(r,t,o,e),i&&i.resolveWith(r,[t,o,e]),h(n,r,"ajaxSuccess",[e,n,t]),y(o,e,n)}function v(t,e,n,i,r){var o=i.context;i.error.call(o,n,e,t),r&&r.rejectWith(o,[n,e,t]),h(i,o,"ajaxError",[n,i,t||e]),y(e,n,i)}function y(t,e,n){var i=n.context;n.complete.call(i,e,t),h(n,i,"ajaxComplete",[e,n]),d(n)}function x(){}function b(t){return t&&(t=t.split(";",2)[0]),t&&(t==f?"html":t==u?"json":s.test(t)?"script":a.test(t)&&"xml")||"text"}function w(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function E(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=w(e.url,e.data),e.data=void 0)}function j(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function T(e,n,i,r){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),r&&(n=i?r:r+"["+(a||"object"==o||"array"==o?n:"")+"]"),!r&&s?e.add(u.name,u.value):"array"==o||!i&&"object"==o?T(e,u,i,n):e.add(n,u)})}var i,r,e=0,n=window.document,o=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,s=/^(?:text|application)\/javascript/i,a=/^(?:text|application)\/xml/i,u="application/json",f="text/html",c=/^\s*$/;t.active=0,t.ajaxJSONP=function(i,r){if(!("type"in i))return t.ajax(i);var f,h,o=i.jsonpCallback,s=(t.isFunction(o)?o():o)||"jsonp"+ ++e,a=n.createElement("script"),u=window[s],c=function(e){t(a).triggerHandler("error",e||"abort")},l={abort:c};return r&&r.promise(l),t(a).on("load error",function(e,n){clearTimeout(h),t(a).off().remove(),"error"!=e.type&&f?g(f[0],l,i,r):v(null,n||"error",l,i,r),window[s]=u,f&&t.isFunction(u)&&u(f[0]),u=f=void 0}),m(l,i)===!1?(c("abort"),l):(window[s]=function(){f=arguments},a.src=i.url.replace(/\?(.+)=\?/,"?$1="+s),n.head.appendChild(a),i.timeout>0&&(h=setTimeout(function(){c("timeout")},i.timeout)),l)},t.ajaxSettings={type:"GET",beforeSend:x,success:x,error:x,complete:x,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:u,xml:"application/xml, text/xml",html:f,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(e){var n=t.extend({},e||{}),o=t.Deferred&&t.Deferred();for(i in t.ajaxSettings)void 0===n[i]&&(n[i]=t.ajaxSettings[i]);p(n),n.crossDomain||(n.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(n.url)&&RegExp.$2!=window.location.host),n.url||(n.url=window.location.toString()),E(n);var s=n.dataType,a=/\?.+=\?/.test(n.url);if(a&&(s="jsonp"),n.cache!==!1&&(e&&e.cache===!0||"script"!=s&&"jsonp"!=s)||(n.url=w(n.url,"_="+Date.now())),"jsonp"==s)return a||(n.url=w(n.url,n.jsonp?n.jsonp+"=?":n.jsonp===!1?"":"callback=?")),t.ajaxJSONP(n,o);var j,u=n.accepts[s],f={},l=function(t,e){f[t.toLowerCase()]=[t,e]},h=/^([\w-]+:)\/\//.test(n.url)?RegExp.$1:window.location.protocol,d=n.xhr(),y=d.setRequestHeader;if(o&&o.promise(d),n.crossDomain||l("X-Requested-With","XMLHttpRequest"),l("Accept",u||"*/*"),(u=n.mimeType||u)&&(u.indexOf(",")>-1&&(u=u.split(",",2)[0]),d.overrideMimeType&&d.overrideMimeType(u)),(n.contentType||n.contentType!==!1&&n.data&&"GET"!=n.type.toUpperCase())&&l("Content-Type",n.contentType||"application/x-www-form-urlencoded"),n.headers)for(r in n.headers)l(r,n.headers[r]);if(d.setRequestHeader=l,d.onreadystatechange=function(){if(4==d.readyState){d.onreadystatechange=x,clearTimeout(j);var e,i=!1;if(d.status>=200&&d.status<300||304==d.status||0==d.status&&"file:"==h){s=s||b(n.mimeType||d.getResponseHeader("content-type")),e=d.responseText;try{"script"==s?(1,eval)(e):"xml"==s?e=d.responseXML:"json"==s&&(e=c.test(e)?null:t.parseJSON(e))}catch(r){i=r}i?v(i,"parsererror",d,n,o):g(e,d,n,o)}else v(d.statusText||null,d.status?"error":"abort",d,n,o)}},m(d,n)===!1)return d.abort(),v(null,"abort",d,n,o),d;if(n.xhrFields)for(r in n.xhrFields)d[r]=n.xhrFields[r];var S="async"in n?n.async:!0;d.open(n.type,n.url,S,n.username,n.password);for(r in f)y.apply(d,f[r]);return n.timeout>0&&(j=setTimeout(function(){d.onreadystatechange=x,d.abort(),v(null,"timeout",d,n,o)},n.timeout)),d.send(n.data?n.data:null),d},t.get=function(){return t.ajax(j.apply(null,arguments))},t.post=function(){var e=j.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=j.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,i){if(!this.length)return this;var a,r=this,s=e.split(/\s/),u=j(e,n,i),f=u.success;return s.length>1&&(u.url=s[0],a=s[1]),u.success=function(e){r.html(a?t("<div>").html(e.replace(o,"")).find(a):e),f&&f.apply(r,arguments)},t.ajax(u),this};var S=encodeURIComponent;t.param=function(t,e){var n=[];return n.add=function(t,e){this.push(S(t)+"="+S(e))},T(n,t,e),n.join("&").replace(/%20/g,"+")}}(Zepto),function(t){t.fn.serializeArray=function(){var n,e=[];return t([].slice.call(this.get(0).elements)).each(function(){n=t(this);var i=n.attr("type");"fieldset"!=this.nodeName.toLowerCase()&&!this.disabled&&"submit"!=i&&"reset"!=i&&"button"!=i&&("radio"!=i&&"checkbox"!=i||this.checked)&&e.push({name:n.attr("name"),value:n.val()})}),e},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(e)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(Zepto),function(t){"__proto__"in{}||t.extend(t.zepto,{Z:function(e,n){return e=e||[],t.extend(e,t.fn),e.selector=n||"",e.__Z=!0,e},isZ:function(e){return"array"===t.type(e)&&"__Z"in e}});try{getComputedStyle(void 0)}catch(e){var n=getComputedStyle;window.getComputedStyle=function(t){try{return n(t)}catch(e){return null}}}}(Zepto); |