Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fsini-informatik/fsfahrttool
  • kleemeis/fsfahrttool
2 results
Show changes
Showing
with 6458 additions and 0 deletions
/*
* Jeditable - jQuery in place edit plugin
*
* Copyright (c) 2006-2013 Mika Tuupola, Dylan Verheul
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/jeditable
*
* Based on editable by Dylan Verheul <dylan_at_dyve.net>:
* http://www.dyve.net/jquery/?editable
*
*/
/**
* Version 1.7.3
*
* ** means there is basic unit tests for this parameter.
*
* @name Jeditable
* @type jQuery
* @param String target (POST) URL or function to send edited content to **
* @param Hash options additional options
* @param String options[method] method to use to send edited content (POST or PUT) **
* @param Function options[callback] Function to run after submitting edited content **
* @param String options[name] POST parameter name of edited content
* @param String options[id] POST parameter name of edited div id
* @param Hash options[submitdata] Extra parameters to send when submitting edited content.
* @param String options[type] text, textarea or select (or any 3rd party input type) **
* @param Integer options[rows] number of rows if using textarea **
* @param Integer options[cols] number of columns if using textarea **
* @param Mixed options[height] 'auto', 'none' or height in pixels **
* @param Mixed options[width] 'auto', 'none' or width in pixels **
* @param String options[loadurl] URL to fetch input content before editing **
* @param String options[loadtype] Request type for load url. Should be GET or POST.
* @param String options[loadtext] Text to display while loading external content.
* @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
* @param Mixed options[data] Or content given as paramameter. String or function.**
* @param String options[indicator] indicator html to show when saving
* @param String options[tooltip] optional tooltip text via title attribute **
* @param String options[event] jQuery event such as 'click' of 'dblclick' **
* @param String options[submit] submit button value, empty means no button **
* @param String options[cancel] cancel button value, empty means no button **
* @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. **
* @param String options[style] Style to apply to input form 'inherit' to copy from parent. **
* @param String options[select] true or false, when true text is highlighted ??
* @param String options[placeholder] Placeholder text or html to insert when element is empty. **
* @param String options[onblur] 'cancel', 'submit', 'ignore' or function ??
*
* @param Function options[onsubmit] function(settings, original) { ... } called before submit
* @param Function options[onreset] function(settings, original) { ... } called before reset
* @param Function options[onerror] function(settings, original, xhr) { ... } called on error
*
* @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
*
*/
(function($) {
$.fn.editable = function(target, options) {
if ('disable' == target) {
$(this).data('disabled.editable', true);
return;
}
if ('enable' == target) {
$(this).data('disabled.editable', false);
return;
}
if ('destroy' == target) {
$(this)
.unbind($(this).data('event.editable'))
.removeData('disabled.editable')
.removeData('event.editable');
return;
}
var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options);
/* setup some functions */
var plugin = $.editable.types[settings.type].plugin || function() { };
var submit = $.editable.types[settings.type].submit || function() { };
var buttons = $.editable.types[settings.type].buttons
|| $.editable.types['defaults'].buttons;
var content = $.editable.types[settings.type].content
|| $.editable.types['defaults'].content;
var element = $.editable.types[settings.type].element
|| $.editable.types['defaults'].element;
var reset = $.editable.types[settings.type].reset
|| $.editable.types['defaults'].reset;
var callback = settings.callback || function() { };
var onedit = settings.onedit || function() { };
var onsubmit = settings.onsubmit || function() { };
var onreset = settings.onreset || function() { };
var onerror = settings.onerror || reset;
/* Show tooltip. */
if (settings.tooltip) {
$(this).attr('title', settings.tooltip);
}
settings.autowidth = 'auto' == settings.width;
settings.autoheight = 'auto' == settings.height;
return this.each(function() {
/* Save this to self because this changes when scope changes. */
var self = this;
/* Inlined block elements lose their width and height after first edit. */
/* Save them for later use as workaround. */
var savedwidth = $(self).width();
var savedheight = $(self).height();
/* Save so it can be later used by $.editable('destroy') */
$(this).data('event.editable', settings.event);
/* If element is empty add something clickable (if requested) */
if (!$.trim($(this).html())) {
$(this).html(settings.placeholder);
}
$(this).bind(settings.event, function(e) {
/* Abort if element is disabled. */
if (true === $(this).data('disabled.editable')) {
return;
}
/* Prevent throwing an exeption if edit field is clicked again. */
if (self.editing) {
return;
}
/* Abort if onedit hook returns false. */
if (false === onedit.apply(this, [settings, self])) {
return;
}
/* Prevent default action and bubbling. */
e.preventDefault();
e.stopPropagation();
/* Remove tooltip. */
if (settings.tooltip) {
$(self).removeAttr('title');
}
/* Figure out how wide and tall we are, saved width and height. */
/* Workaround for http://dev.jquery.com/ticket/2190 */
if (0 == $(self).width()) {
settings.width = savedwidth;
settings.height = savedheight;
} else {
if (settings.width != 'none') {
settings.width =
settings.autowidth ? $(self).width() : settings.width;
}
if (settings.height != 'none') {
settings.height =
settings.autoheight ? $(self).height() : settings.height;
}
}
/* Remove placeholder text, replace is here because of IE. */
if ($(this).html().toLowerCase().replace(/(;|"|\/)/g, '') ==
settings.placeholder.toLowerCase().replace(/(;|"|\/)/g, '')) {
$(this).html('');
}
self.editing = true;
self.revert = $(self).html();
$(self).html('');
/* Create the form object. */
var form = $('<form />');
/* Apply css or style or both. */
if (settings.cssclass) {
if ('inherit' == settings.cssclass) {
form.attr('class', $(self).attr('class'));
} else {
form.attr('class', settings.cssclass);
}
}
if (settings.style) {
if ('inherit' == settings.style) {
form.attr('style', $(self).attr('style'));
/* IE needs the second line or display wont be inherited. */
form.css('display', $(self).css('display'));
} else {
form.attr('style', settings.style);
}
}
/* Add main input element to form and store it in input. */
var input = element.apply(form, [settings, self]);
/* Set input content via POST, GET, given data or existing value. */
var input_content;
if (settings.loadurl) {
var t = setTimeout(function() {
input.disabled = true;
content.apply(form, [settings.loadtext, settings, self]);
}, 100);
var loaddata = {};
loaddata[settings.id] = self.id;
if ($.isFunction(settings.loaddata)) {
$.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
} else {
$.extend(loaddata, settings.loaddata);
}
$.ajax({
type : settings.loadtype,
url : settings.loadurl,
data : loaddata,
async : false,
success: function(result) {
window.clearTimeout(t);
input_content = result;
input.disabled = false;
}
});
} else if (settings.data) {
input_content = settings.data;
if ($.isFunction(settings.data)) {
input_content = settings.data.apply(self, [self.revert, settings]);
}
} else {
input_content = self.revert;
}
content.apply(form, [input_content, settings, self]);
input.attr('name', settings.name);
/* Add buttons to the form. */
buttons.apply(form, [settings, self]);
/* Add created form to self. */
$(self).append(form);
/* Attach 3rd party plugin if requested. */
plugin.apply(form, [settings, self]);
/* Focus to first visible form element. */
$(':input:visible:enabled:first', form).focus();
/* Highlight input contents when requested. */
if (settings.select) {
input.select();
}
/* discard changes if pressing esc */
input.keydown(function(e) {
if (e.keyCode == 27) {
e.preventDefault();
reset.apply(form, [settings, self]);
}
});
/* Discard, submit or nothing with changes when clicking outside. */
/* Do nothing is usable when navigating with tab. */
var t;
if ('cancel' == settings.onblur) {
input.blur(function(e) {
/* Prevent canceling if submit was clicked. */
t = setTimeout(function() {
reset.apply(form, [settings, self]);
}, 500);
});
} else if ('submit' == settings.onblur) {
input.blur(function(e) {
/* Prevent double submit if submit was clicked. */
t = setTimeout(function() {
form.submit();
}, 200);
});
} else if ($.isFunction(settings.onblur)) {
input.blur(function(e) {
settings.onblur.apply(self, [input.val(), settings]);
});
} else {
input.blur(function(e) {
/* TODO: maybe something here */
});
}
form.submit(function(e) {
if (t) {
clearTimeout(t);
}
/* Do no submit. */
e.preventDefault();
/* Call before submit hook. */
/* If it returns false abort submitting. */
if (false !== onsubmit.apply(form, [settings, self])) {
/* Custom inputs call before submit hook. */
/* If it returns false abort submitting. */
if (false !== submit.apply(form, [settings, self])) {
/* Check if given target is function */
if ($.isFunction(settings.target)) {
var str = settings.target.apply(self, [input.val(), settings]);
$(self).html(str);
self.editing = false;
callback.apply(self, [self.innerHTML, settings]);
/* TODO: this is not dry */
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
} else {
/* Add edited content and id of edited element to POST. */
var submitdata = {};
submitdata[settings.name] = input.val();
submitdata[settings.id] = self.id;
/* Add extra data to be POST:ed. */
if ($.isFunction(settings.submitdata)) {
$.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
} else {
$.extend(submitdata, settings.submitdata);
}
/* Quick and dirty PUT support. */
if ('PUT' == settings.method) {
submitdata['_method'] = 'put';
}
/* Show the saving indicator. */
$(self).html(settings.indicator);
/* Defaults for ajaxoptions. */
var ajaxoptions = {
type : 'POST',
data : submitdata,
dataType: 'html',
url : settings.target,
success : function(result, status) {
if (ajaxoptions.dataType == 'html') {
$(self).html(result);
}
self.editing = false;
callback.apply(self, [result, settings]);
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
},
error : function(xhr, status, error) {
onerror.apply(form, [settings, self, xhr]);
}
};
/* Override with what is given in settings.ajaxoptions. */
$.extend(ajaxoptions, settings.ajaxoptions);
$.ajax(ajaxoptions);
}
}
}
/* Show tooltip again. */
$(self).attr('title', settings.tooltip);
return false;
});
});
/* Privileged methods */
this.reset = function(form) {
/* Prevent calling reset twice when blurring. */
if (this.editing) {
/* Before reset hook, if it returns false abort reseting. */
if (false !== onreset.apply(form, [settings, self])) {
$(self).html(self.revert);
self.editing = false;
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
/* Show tooltip again. */
if (settings.tooltip) {
$(self).attr('title', settings.tooltip);
}
}
}
};
});
};
$.editable = {
types: {
defaults: {
element : function(settings, original) {
var input = $('<input type="hidden"></input>');
$(this).append(input);
return(input);
},
content : function(string, settings, original) {
$(':input:first', this).val(string);
},
reset : function(settings, original) {
original.reset(this);
},
buttons : function(settings, original) {
var form = this;
if (settings.submit) {
/* If given html string use that. */
if (settings.submit.match(/>$/)) {
var submit = $(settings.submit).click(function() {
if (submit.attr("type") != "submit") {
form.submit();
}
});
/* Otherwise use button with given string as text. */
} else {
var submit = $('<button type="submit" />');
submit.html(settings.submit);
}
$(this).append(submit);
}
if (settings.cancel) {
/* If given html string use that. */
if (settings.cancel.match(/>$/)) {
var cancel = $(settings.cancel);
/* otherwise use button with given string as text */
} else {
var cancel = $('<button type="cancel" />');
cancel.html(settings.cancel);
}
$(this).append(cancel);
$(cancel).click(function(event) {
if ($.isFunction($.editable.types[settings.type].reset)) {
var reset = $.editable.types[settings.type].reset;
} else {
var reset = $.editable.types['defaults'].reset;
}
reset.apply(form, [settings, original]);
return false;
});
}
}
},
text: {
element : function(settings, original) {
var input = $('<input />');
if (settings.width != 'none') { input.attr('width', settings.width); }
if (settings.height != 'none') { input.attr('height', settings.height); }
/* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
//input[0].setAttribute('autocomplete','off');
input.attr('autocomplete','off');
$(this).append(input);
return(input);
}
},
textarea: {
element : function(settings, original) {
var textarea = $('<textarea />');
if (settings.rows) {
textarea.attr('rows', settings.rows);
} else if (settings.height != "none") {
textarea.height(settings.height);
}
if (settings.cols) {
textarea.attr('cols', settings.cols);
} else if (settings.width != "none") {
textarea.width(settings.width);
}
$(this).append(textarea);
return(textarea);
}
},
select: {
element : function(settings, original) {
var select = $('<select />');
$(this).append(select);
return(select);
},
content : function(data, settings, original) {
/* If it is string assume it is json. */
if (String == data.constructor) {
eval ('var json = ' + data);
} else {
/* Otherwise assume it is a hash already. */
var json = data;
}
for (var key in json) {
if (!json.hasOwnProperty(key)) {
continue;
}
if ('selected' == key) {
continue;
}
var option = $('<option />').val(key).append(json[key]);
$('select', this).append(option);
}
/* Loop option again to set selected. IE needed this... */
$('select', this).children().each(function() {
if ($(this).val() == json['selected'] ||
$(this).text() == $.trim(original.revert)) {
$(this).attr('selected', 'selected');
}
});
/* Submit on change if no submit button defined. */
if (!settings.submit) {
var form = this;
$('select', this).change(function() {
form.submit();
});
}
}
}
},
/* Add new input type */
addInputType: function(name, input) {
$.editable.types[name] = input;
}
};
/* Publicly accessible defaults. */
$.fn.editable.defaults = {
name : 'value',
id : 'id',
type : 'text',
width : 'auto',
height : 'auto',
event : 'click.editable',
onblur : 'cancel',
loadtype : 'GET',
loadtext : 'Loading...',
placeholder: 'Click to edit',
loaddata : {},
submitdata : {},
ajaxoptions: {}
};
})(jQuery);
/* jQuery.qrcode 0.12.0 - http://larsjung.de/jquery-qrcode/ - uses //github.com/kazuhikoarase/qrcode-generator (MIT) */
(function (qrcode) {
'use strict';
var $ = jQuery;
// Wrapper for the original QR code generator.
function QRCode(text, level, version, quiet) {
var qr = qrcode(version, level);
qr.addData(text);
qr.make();
quiet = quiet || 0;
var qrModuleCount = qr.getModuleCount();
var quietModuleCount = qr.getModuleCount() + 2 * quiet;
function isDark(row, col) {
row -= quiet;
col -= quiet;
if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
return false;
}
return qr.isDark(row, col);
}
var addBlank = function (l, t, r, b) {
var prevIsDark = this.isDark;
var moduleSize = 1 / quietModuleCount;
this.isDark = function (row, col) {
var ml = col * moduleSize;
var mt = row * moduleSize;
var mr = ml + moduleSize;
var mb = mt + moduleSize;
return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
};
};
this.text = text;
this.level = level;
this.version = version;
this.moduleCount = quietModuleCount;
this.isDark = isDark;
this.addBlank = addBlank;
}
// Check if canvas is available in the browser (as Modernizr does)
var hasCanvas = (function () {
var elem = document.createElement('canvas');
return Boolean(elem.getContext && elem.getContext('2d'));
}());
var hasArcTo = Object.prototype.toString.call(window.opera) !== '[object Opera]';
// Returns a minimal QR code for the given text starting with version `minVersion`.
// Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
function createQRCode(text, level, minVersion, maxVersion, quiet) {
minVersion = Math.max(1, minVersion || 1);
maxVersion = Math.min(40, maxVersion || 40);
for (var version = minVersion; version <= maxVersion; version += 1) {
try {
return new QRCode(text, level, version, quiet);
} catch (err) {}
}
}
function drawBackgroundLabel(qr, context, settings) {
var size = settings.size;
var font = 'bold ' + (settings.mSize * size) + 'px ' + settings.fontname;
var ctx = $('<canvas/>')[0].getContext('2d');
ctx.font = font;
var w = ctx.measureText(settings.label).width;
var sh = settings.mSize;
var sw = w / size;
var sl = (1 - sw) * settings.mPosX;
var st = (1 - sh) * settings.mPosY;
var sr = sl + sw;
var sb = st + sh;
var pad = 0.01;
if (settings.mode === 1) {
// Strip
qr.addBlank(0, st - pad, size, sb + pad);
} else {
// Box
qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
}
context.fillStyle = settings.fontcolor;
context.font = font;
context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
}
function drawBackgroundImage(qr, context, settings) {
var size = settings.size;
var w = settings.image.naturalWidth || 1;
var h = settings.image.naturalHeight || 1;
var sh = settings.mSize;
var sw = sh * w / h;
var sl = (1 - sw) * settings.mPosX;
var st = (1 - sh) * settings.mPosY;
var sr = sl + sw;
var sb = st + sh;
var pad = 0.01;
if (settings.mode === 3) {
// Strip
qr.addBlank(0, st - pad, size, sb + pad);
} else {
// Box
qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
}
context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
}
function drawBackground(qr, context, settings) {
if ($(settings.background).is('img')) {
context.drawImage(settings.background, 0, 0, settings.size, settings.size);
} else if (settings.background) {
context.fillStyle = settings.background;
context.fillRect(settings.left, settings.top, settings.size, settings.size);
}
var mode = settings.mode;
if (mode === 1 || mode === 2) {
drawBackgroundLabel(qr, context, settings);
} else if (mode === 3 || mode === 4) {
drawBackgroundImage(qr, context, settings);
}
}
function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
if (qr.isDark(row, col)) {
context.rect(left, top, width, width);
}
}
function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
if (nw) {
ctx.moveTo(l + rad, t);
} else {
ctx.moveTo(l, t);
}
if (ne) {
ctx.lineTo(r - rad, t);
ctx.arcTo(r, t, r, b, rad);
} else {
ctx.lineTo(r, t);
}
if (se) {
ctx.lineTo(r, b - rad);
ctx.arcTo(r, b, l, b, rad);
} else {
ctx.lineTo(r, b);
}
if (sw) {
ctx.lineTo(l + rad, b);
ctx.arcTo(l, b, l, t, rad);
} else {
ctx.lineTo(l, b);
}
if (nw) {
ctx.lineTo(l, t + rad);
ctx.arcTo(l, t, r, t, rad);
} else {
ctx.lineTo(l, t);
}
}
function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
if (nw) {
ctx.moveTo(l + rad, t);
ctx.lineTo(l, t);
ctx.lineTo(l, t + rad);
ctx.arcTo(l, t, l + rad, t, rad);
}
if (ne) {
ctx.moveTo(r - rad, t);
ctx.lineTo(r, t);
ctx.lineTo(r, t + rad);
ctx.arcTo(r, t, r - rad, t, rad);
}
if (se) {
ctx.moveTo(r - rad, b);
ctx.lineTo(r, b);
ctx.lineTo(r, b - rad);
ctx.arcTo(r, b, r - rad, b, rad);
}
if (sw) {
ctx.moveTo(l + rad, b);
ctx.lineTo(l, b);
ctx.lineTo(l, b - rad);
ctx.arcTo(l, b, l + rad, b, rad);
}
}
function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
var isDark = qr.isDark;
var right = left + width;
var bottom = top + width;
var radius = settings.radius * width;
var rowT = row - 1;
var rowB = row + 1;
var colL = col - 1;
var colR = col + 1;
var center = isDark(row, col);
var northwest = isDark(rowT, colL);
var north = isDark(rowT, col);
var northeast = isDark(rowT, colR);
var east = isDark(row, colR);
var southeast = isDark(rowB, colR);
var south = isDark(rowB, col);
var southwest = isDark(rowB, colL);
var west = isDark(row, colL);
if (center) {
drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
} else {
drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
}
}
function drawModules(qr, context, settings) {
var moduleCount = qr.moduleCount;
var moduleSize = settings.size / moduleCount;
var fn = drawModuleDefault;
var row;
var col;
if (hasArcTo && settings.radius > 0 && settings.radius <= 0.5) {
fn = drawModuleRounded;
}
context.beginPath();
for (row = 0; row < moduleCount; row += 1) {
for (col = 0; col < moduleCount; col += 1) {
var l = settings.left + col * moduleSize;
var t = settings.top + row * moduleSize;
var w = moduleSize;
fn(qr, context, settings, l, t, w, row, col);
}
}
if ($(settings.fill).is('img')) {
context.strokeStyle = 'rgba(0,0,0,0.5)';
context.lineWidth = 2;
context.stroke();
var prev = context.globalCompositeOperation;
context.globalCompositeOperation = 'destination-out';
context.fill();
context.globalCompositeOperation = prev;
context.clip();
context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
context.restore();
} else {
context.fillStyle = settings.fill;
context.fill();
}
}
// Draws QR code to the given `canvas` and returns it.
function drawOnCanvas(canvas, settings) {
var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
if (!qr) {
return null;
}
var $canvas = $(canvas).data('qrcode', qr);
var context = $canvas[0].getContext('2d');
drawBackground(qr, context, settings);
drawModules(qr, context, settings);
return $canvas;
}
// Returns a `canvas` element representing the QR code for the given settings.
function createCanvas(settings) {
var $canvas = $('<canvas/>').attr('width', settings.size).attr('height', settings.size);
return drawOnCanvas($canvas, settings);
}
// Returns an `image` element representing the QR code for the given settings.
function createImage(settings) {
return $('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
}
// Returns a `div` element representing the QR code for the given settings.
function createDiv(settings) {
var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
if (!qr) {
return null;
}
// some shortcuts to improve compression
var settings_size = settings.size;
var settings_bgColor = settings.background;
var math_floor = Math.floor;
var moduleCount = qr.moduleCount;
var moduleSize = math_floor(settings_size / moduleCount);
var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
var row;
var col;
var containerCSS = {
position: 'relative',
left: 0,
top: 0,
padding: 0,
margin: 0,
width: settings_size,
height: settings_size
};
var darkCSS = {
position: 'absolute',
padding: 0,
margin: 0,
width: moduleSize,
height: moduleSize,
'background-color': settings.fill
};
var $div = $('<div/>').data('qrcode', qr).css(containerCSS);
if (settings_bgColor) {
$div.css('background-color', settings_bgColor);
}
for (row = 0; row < moduleCount; row += 1) {
for (col = 0; col < moduleCount; col += 1) {
if (qr.isDark(row, col)) {
$('<div/>')
.css(darkCSS)
.css({
left: offset + col * moduleSize,
top: offset + row * moduleSize
})
.appendTo($div);
}
}
}
return $div;
}
function createHTML(settings) {
if (hasCanvas && settings.render === 'canvas') {
return createCanvas(settings);
} else if (hasCanvas && settings.render === 'image') {
return createImage(settings);
}
return createDiv(settings);
}
// Plugin
// ======
// Default settings
// ----------------
var defaults = {
// render method: `'canvas'`, `'image'` or `'div'`
render: 'canvas',
// version range somewhere in 1 .. 40
minVersion: 1,
maxVersion: 40,
// error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
ecLevel: 'L',
// offset in pixel if drawn onto existing canvas
left: 0,
top: 0,
// size in pixel
size: 200,
// code color or image element
fill: '#000',
// background color or image element, `null` for transparent background
background: null,
// content
text: 'no text',
// corner radius relative to module width: 0.0 .. 0.5
radius: 0,
// quiet zone in modules
quiet: 0,
// modes
// 0: normal
// 1: label strip
// 2: label box
// 3: image strip
// 4: image box
mode: 0,
mSize: 0.1,
mPosX: 0.5,
mPosY: 0.5,
label: 'no label',
fontname: 'sans',
fontcolor: '#000',
image: null
};
// Register the plugin
// -------------------
$.fn.qrcode = function (options) {
var settings = $.extend({}, defaults, options);
return this.each(function () {
if (this.nodeName.toLowerCase() === 'canvas') {
drawOnCanvas(this, settings);
} else {
$(this).append(createHTML(settings));
}
});
};
}(function () {
// `qrcode` is the single public function defined by the `QR Code Generator`
//---------------------------------------------------------------------
//
// QR Code Generator for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word 'QR Code' is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
var qrcode = function() {
//---------------------------------------------------------------------
// qrcode
//---------------------------------------------------------------------
/**
* qrcode
* @param typeNumber 1 to 40
* @param errorCorrectLevel 'L','M','Q','H'
*/
var qrcode = function(typeNumber, errorCorrectLevel) {
var PAD0 = 0xEC;
var PAD1 = 0x11;
var _typeNumber = typeNumber;
var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];
var _modules = null;
var _moduleCount = 0;
var _dataCache = null;
var _dataList = new Array();
var _this = {};
var makeImpl = function(test, maskPattern) {
_moduleCount = _typeNumber * 4 + 17;
_modules = function(moduleCount) {
var modules = new Array(moduleCount);
for (var row = 0; row < moduleCount; row += 1) {
modules[row] = new Array(moduleCount);
for (var col = 0; col < moduleCount; col += 1) {
modules[row][col] = null;
}
}
return modules;
}(_moduleCount);
setupPositionProbePattern(0, 0);
setupPositionProbePattern(_moduleCount - 7, 0);
setupPositionProbePattern(0, _moduleCount - 7);
setupPositionAdjustPattern();
setupTimingPattern();
setupTypeInfo(test, maskPattern);
if (_typeNumber >= 7) {
setupTypeNumber(test);
}
if (_dataCache == null) {
_dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);
}
mapData(_dataCache, maskPattern);
};
var setupPositionProbePattern = function(row, col) {
for (var r = -1; r <= 7; r += 1) {
if (row + r <= -1 || _moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c += 1) {
if (col + c <= -1 || _moduleCount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
_modules[row + r][col + c] = true;
} else {
_modules[row + r][col + c] = false;
}
}
}
};
var getBestMaskPattern = function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i += 1) {
makeImpl(true, i);
var lostPoint = QRUtil.getLostPoint(_this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
};
var setupTimingPattern = function() {
for (var r = 8; r < _moduleCount - 8; r += 1) {
if (_modules[r][6] != null) {
continue;
}
_modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < _moduleCount - 8; c += 1) {
if (_modules[6][c] != null) {
continue;
}
_modules[6][c] = (c % 2 == 0);
}
};
var setupPositionAdjustPattern = function() {
var pos = QRUtil.getPatternPosition(_typeNumber);
for (var i = 0; i < pos.length; i += 1) {
for (var j = 0; j < pos.length; j += 1) {
var row = pos[i];
var col = pos[j];
if (_modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r += 1) {
for (var c = -2; c <= 2; c += 1) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
_modules[row + r][col + c] = true;
} else {
_modules[row + r][col + c] = false;
}
}
}
}
}
};
var setupTypeNumber = function(test) {
var bits = QRUtil.getBCHTypeNumber(_typeNumber);
for (var i = 0; i < 18; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
_modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
_modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
};
var setupTypeInfo = function(test, maskPattern) {
var data = (_errorCorrectLevel << 3) | maskPattern;
var bits = QRUtil.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
_modules[i][8] = mod;
} else if (i < 8) {
_modules[i + 1][8] = mod;
} else {
_modules[_moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
_modules[8][_moduleCount - i - 1] = mod;
} else if (i < 9) {
_modules[8][15 - i - 1 + 1] = mod;
} else {
_modules[8][15 - i - 1] = mod;
}
}
// fixed module
_modules[_moduleCount - 8][8] = (!test);
};
var mapData = function(data, maskPattern) {
var inc = -1;
var row = _moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
var maskFunc = QRUtil.getMaskFunction(maskPattern);
for (var col = _moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col -= 1;
while (true) {
for (var c = 0; c < 2; c += 1) {
if (_modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = maskFunc(row, col - c);
if (mask) {
dark = !dark;
}
_modules[row][col - c] = dark;
bitIndex -= 1;
if (bitIndex == -1) {
byteIndex += 1;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || _moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
var createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r += 1) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i += 1) {
dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
}
offset += dcCount;
var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i += 1) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i += 1) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i += 1) {
for (var r = 0; r < rsBlocks.length; r += 1) {
if (i < dcdata[r].length) {
data[index] = dcdata[r][i];
index += 1;
}
}
}
for (var i = 0; i < maxEcCount; i += 1) {
for (var r = 0; r < rsBlocks.length; r += 1) {
if (i < ecdata[r].length) {
data[index] = ecdata[r][i];
index += 1;
}
}
}
return data;
};
var createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = qrBitBuffer();
for (var i = 0; i < dataList.length; i += 1) {
var data = dataList[i];
buffer.put(data.getMode(), 4);
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i += 1) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error('code length overflow. ('
+ buffer.getLengthInBits()
+ '>'
+ totalDataCount * 8
+ ')');
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(PAD1, 8);
}
return createBytes(buffer, rsBlocks);
};
_this.addData = function(data) {
var newData = qr8BitByte(data);
_dataList.push(newData);
_dataCache = null;
};
_this.isDark = function(row, col) {
if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
throw new Error(row + ',' + col);
}
return _modules[row][col];
};
_this.getModuleCount = function() {
return _moduleCount;
};
_this.make = function() {
makeImpl(false, getBestMaskPattern() );
};
_this.createTableTag = function(cellSize, margin) {
cellSize = cellSize || 2;
margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
var qrHtml = '';
qrHtml += '<table style="';
qrHtml += ' border-width: 0px; border-style: none;';
qrHtml += ' border-collapse: collapse;';
qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
qrHtml += '">';
qrHtml += '<tbody>';
for (var r = 0; r < _this.getModuleCount(); r += 1) {
qrHtml += '<tr>';
for (var c = 0; c < _this.getModuleCount(); c += 1) {
qrHtml += '<td style="';
qrHtml += ' border-width: 0px; border-style: none;';
qrHtml += ' border-collapse: collapse;';
qrHtml += ' padding: 0px; margin: 0px;';
qrHtml += ' width: ' + cellSize + 'px;';
qrHtml += ' height: ' + cellSize + 'px;';
qrHtml += ' background-color: ';
qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
qrHtml += ';';
qrHtml += '"/>';
}
qrHtml += '</tr>';
}
qrHtml += '</tbody>';
qrHtml += '</table>';
return qrHtml;
};
_this.createImgTag = function(cellSize, margin) {
cellSize = cellSize || 2;
margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
var size = _this.getModuleCount() * cellSize + margin * 2;
var min = margin;
var max = size - margin;
return createImgTag(size, size, function(x, y) {
if (min <= x && x < max && min <= y && y < max) {
var c = Math.floor( (x - min) / cellSize);
var r = Math.floor( (y - min) / cellSize);
return _this.isDark(r, c)? 0 : 1;
} else {
return 1;
}
} );
};
return _this;
};
//---------------------------------------------------------------------
// qrcode.stringToBytes
//---------------------------------------------------------------------
qrcode.stringToBytes = function(s) {
var bytes = new Array();
for (var i = 0; i < s.length; i += 1) {
var c = s.charCodeAt(i);
bytes.push(c & 0xff);
}
return bytes;
};
//---------------------------------------------------------------------
// qrcode.createStringToBytes
//---------------------------------------------------------------------
/**
* @param unicodeData base64 string of byte array.
* [16bit Unicode],[16bit Bytes], ...
* @param numChars
*/
qrcode.createStringToBytes = function(unicodeData, numChars) {
// create conversion map.
var unicodeMap = function() {
var bin = base64DecodeInputStream(unicodeData);
var read = function() {
var b = bin.read();
if (b == -1) throw new Error();
return b;
};
var count = 0;
var unicodeMap = {};
while (true) {
var b0 = bin.read();
if (b0 == -1) break;
var b1 = read();
var b2 = read();
var b3 = read();
var k = String.fromCharCode( (b0 << 8) | b1);
var v = (b2 << 8) | b3;
unicodeMap[k] = v;
count += 1;
}
if (count != numChars) {
throw new Error(count + ' != ' + numChars);
}
return unicodeMap;
}();
var unknownChar = '?'.charCodeAt(0);
return function(s) {
var bytes = new Array();
for (var i = 0; i < s.length; i += 1) {
var c = s.charCodeAt(i);
if (c < 128) {
bytes.push(c);
} else {
var b = unicodeMap[s.charAt(i)];
if (typeof b == 'number') {
if ( (b & 0xff) == b) {
// 1byte
bytes.push(b);
} else {
// 2bytes
bytes.push(b >>> 8);
bytes.push(b & 0xff);
}
} else {
bytes.push(unknownChar);
}
}
}
return bytes;
};
};
//---------------------------------------------------------------------
// QRMode
//---------------------------------------------------------------------
var QRMode = {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};
//---------------------------------------------------------------------
// QRErrorCorrectLevel
//---------------------------------------------------------------------
var QRErrorCorrectLevel = {
L : 1,
M : 0,
Q : 3,
H : 2
};
//---------------------------------------------------------------------
// QRMaskPattern
//---------------------------------------------------------------------
var QRMaskPattern = {
PATTERN000 : 0,
PATTERN001 : 1,
PATTERN010 : 2,
PATTERN011 : 3,
PATTERN100 : 4,
PATTERN101 : 5,
PATTERN110 : 6,
PATTERN111 : 7
};
//---------------------------------------------------------------------
// QRUtil
//---------------------------------------------------------------------
var QRUtil = function() {
var PATTERN_POSITION_TABLE = [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
];
var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
var _this = {};
var getBCHDigit = function(data) {
var digit = 0;
while (data != 0) {
digit += 1;
data >>>= 1;
}
return digit;
};
_this.getBCHTypeInfo = function(data) {
var d = data << 10;
while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
}
return ( (data << 10) | d) ^ G15_MASK;
};
_this.getBCHTypeNumber = function(data) {
var d = data << 12;
while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
}
return (data << 12) | d;
};
_this.getPatternPosition = function(typeNumber) {
return PATTERN_POSITION_TABLE[typeNumber - 1];
};
_this.getMaskFunction = function(maskPattern) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000 :
return function(i, j) { return (i + j) % 2 == 0; };
case QRMaskPattern.PATTERN001 :
return function(i, j) { return i % 2 == 0; };
case QRMaskPattern.PATTERN010 :
return function(i, j) { return j % 3 == 0; };
case QRMaskPattern.PATTERN011 :
return function(i, j) { return (i + j) % 3 == 0; };
case QRMaskPattern.PATTERN100 :
return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
case QRMaskPattern.PATTERN101 :
return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
case QRMaskPattern.PATTERN110 :
return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
case QRMaskPattern.PATTERN111 :
return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
default :
throw new Error('bad maskPattern:' + maskPattern);
}
};
_this.getErrorCorrectPolynomial = function(errorCorrectLength) {
var a = qrPolynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i += 1) {
a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
}
return a;
};
_this.getLengthInBits = function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case QRMode.MODE_NUMBER : return 10;
case QRMode.MODE_ALPHA_NUM : return 9;
case QRMode.MODE_8BIT_BYTE : return 8;
case QRMode.MODE_KANJI : return 8;
default :
throw new Error('mode:' + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case QRMode.MODE_NUMBER : return 12;
case QRMode.MODE_ALPHA_NUM : return 11;
case QRMode.MODE_8BIT_BYTE : return 16;
case QRMode.MODE_KANJI : return 10;
default :
throw new Error('mode:' + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case QRMode.MODE_NUMBER : return 14;
case QRMode.MODE_ALPHA_NUM : return 13;
case QRMode.MODE_8BIT_BYTE : return 16;
case QRMode.MODE_KANJI : return 12;
default :
throw new Error('mode:' + mode);
}
} else {
throw new Error('type:' + type);
}
};
_this.getLostPoint = function(qrcode) {
var moduleCount = qrcode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row += 1) {
for (var col = 0; col < moduleCount; col += 1) {
var sameCount = 0;
var dark = qrcode.isDark(row, col);
for (var r = -1; r <= 1; r += 1) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c += 1) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrcode.isDark(row + r, col + c) ) {
sameCount += 1;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
};
// LEVEL2
for (var row = 0; row < moduleCount - 1; row += 1) {
for (var col = 0; col < moduleCount - 1; col += 1) {
var count = 0;
if (qrcode.isDark(row, col) ) count += 1;
if (qrcode.isDark(row + 1, col) ) count += 1;
if (qrcode.isDark(row, col + 1) ) count += 1;
if (qrcode.isDark(row + 1, col + 1) ) count += 1;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row += 1) {
for (var col = 0; col < moduleCount - 6; col += 1) {
if (qrcode.isDark(row, col)
&& !qrcode.isDark(row, col + 1)
&& qrcode.isDark(row, col + 2)
&& qrcode.isDark(row, col + 3)
&& qrcode.isDark(row, col + 4)
&& !qrcode.isDark(row, col + 5)
&& qrcode.isDark(row, col + 6) ) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col += 1) {
for (var row = 0; row < moduleCount - 6; row += 1) {
if (qrcode.isDark(row, col)
&& !qrcode.isDark(row + 1, col)
&& qrcode.isDark(row + 2, col)
&& qrcode.isDark(row + 3, col)
&& qrcode.isDark(row + 4, col)
&& !qrcode.isDark(row + 5, col)
&& qrcode.isDark(row + 6, col) ) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col += 1) {
for (var row = 0; row < moduleCount; row += 1) {
if (qrcode.isDark(row, col) ) {
darkCount += 1;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
};
return _this;
}();
//---------------------------------------------------------------------
// QRMath
//---------------------------------------------------------------------
var QRMath = function() {
var EXP_TABLE = new Array(256);
var LOG_TABLE = new Array(256);
// initialize tables
for (var i = 0; i < 8; i += 1) {
EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i += 1) {
EXP_TABLE[i] = EXP_TABLE[i - 4]
^ EXP_TABLE[i - 5]
^ EXP_TABLE[i - 6]
^ EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i += 1) {
LOG_TABLE[EXP_TABLE[i] ] = i;
}
var _this = {};
_this.glog = function(n) {
if (n < 1) {
throw new Error('glog(' + n + ')');
}
return LOG_TABLE[n];
};
_this.gexp = function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return EXP_TABLE[n];
};
return _this;
}();
//---------------------------------------------------------------------
// qrPolynomial
//---------------------------------------------------------------------
function qrPolynomial(num, shift) {
if (typeof num.length == 'undefined') {
throw new Error(num.length + '/' + shift);
}
var _num = function() {
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset += 1;
}
var _num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i += 1) {
_num[i] = num[i + offset];
}
return _num;
}();
var _this = {};
_this.getAt = function(index) {
return _num[index];
};
_this.getLength = function() {
return _num.length;
};
_this.multiply = function(e) {
var num = new Array(_this.getLength() + e.getLength() - 1);
for (var i = 0; i < _this.getLength(); i += 1) {
for (var j = 0; j < e.getLength(); j += 1) {
num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
}
}
return qrPolynomial(num, 0);
};
_this.mod = function(e) {
if (_this.getLength() - e.getLength() < 0) {
return _this;
}
var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
var num = new Array(_this.getLength() );
for (var i = 0; i < _this.getLength(); i += 1) {
num[i] = _this.getAt(i);
}
for (var i = 0; i < e.getLength(); i += 1) {
num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
}
// recursive call
return qrPolynomial(num, 0).mod(e);
};
return _this;
};
//---------------------------------------------------------------------
// QRRSBlock
//---------------------------------------------------------------------
var QRRSBlock = function() {
var RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12, 7, 37, 13],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
var qrRSBlock = function(totalCount, dataCount) {
var _this = {};
_this.totalCount = totalCount;
_this.dataCount = dataCount;
return _this;
};
var _this = {};
var getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch(errorCorrectLevel) {
case QRErrorCorrectLevel.L :
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case QRErrorCorrectLevel.M :
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case QRErrorCorrectLevel.Q :
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case QRErrorCorrectLevel.H :
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default :
return undefined;
}
};
_this.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);
if (typeof rsBlock == 'undefined') {
throw new Error('bad rs block @ typeNumber:' + typeNumber +
'/errorCorrectLevel:' + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i += 1) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j += 1) {
list.push(qrRSBlock(totalCount, dataCount) );
}
}
return list;
};
return _this;
}();
//---------------------------------------------------------------------
// qrBitBuffer
//---------------------------------------------------------------------
var qrBitBuffer = function() {
var _buffer = new Array();
var _length = 0;
var _this = {};
_this.getBuffer = function() {
return _buffer;
};
_this.getAt = function(index) {
var bufIndex = Math.floor(index / 8);
return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
};
_this.put = function(num, length) {
for (var i = 0; i < length; i += 1) {
_this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
};
_this.getLengthInBits = function() {
return _length;
};
_this.putBit = function(bit) {
var bufIndex = Math.floor(_length / 8);
if (_buffer.length <= bufIndex) {
_buffer.push(0);
}
if (bit) {
_buffer[bufIndex] |= (0x80 >>> (_length % 8) );
}
_length += 1;
};
return _this;
};
//---------------------------------------------------------------------
// qr8BitByte
//---------------------------------------------------------------------
var qr8BitByte = function(data) {
var _mode = QRMode.MODE_8BIT_BYTE;
var _data = data;
var _bytes = qrcode.stringToBytes(data);
var _this = {};
_this.getMode = function() {
return _mode;
};
_this.getLength = function(buffer) {
return _bytes.length;
};
_this.write = function(buffer) {
for (var i = 0; i < _bytes.length; i += 1) {
buffer.put(_bytes[i], 8);
}
};
return _this;
};
//=====================================================================
// GIF Support etc.
//
//---------------------------------------------------------------------
// byteArrayOutputStream
//---------------------------------------------------------------------
var byteArrayOutputStream = function() {
var _bytes = new Array();
var _this = {};
_this.writeByte = function(b) {
_bytes.push(b & 0xff);
};
_this.writeShort = function(i) {
_this.writeByte(i);
_this.writeByte(i >>> 8);
};
_this.writeBytes = function(b, off, len) {
off = off || 0;
len = len || b.length;
for (var i = 0; i < len; i += 1) {
_this.writeByte(b[i + off]);
}
};
_this.writeString = function(s) {
for (var i = 0; i < s.length; i += 1) {
_this.writeByte(s.charCodeAt(i) );
}
};
_this.toByteArray = function() {
return _bytes;
};
_this.toString = function() {
var s = '';
s += '[';
for (var i = 0; i < _bytes.length; i += 1) {
if (i > 0) {
s += ',';
}
s += _bytes[i];
}
s += ']';
return s;
};
return _this;
};
//---------------------------------------------------------------------
// base64EncodeOutputStream
//---------------------------------------------------------------------
var base64EncodeOutputStream = function() {
var _buffer = 0;
var _buflen = 0;
var _length = 0;
var _base64 = '';
var _this = {};
var writeEncoded = function(b) {
_base64 += String.fromCharCode(encode(b & 0x3f) );
};
var encode = function(n) {
if (n < 0) {
// error.
} else if (n < 26) {
return 0x41 + n;
} else if (n < 52) {
return 0x61 + (n - 26);
} else if (n < 62) {
return 0x30 + (n - 52);
} else if (n == 62) {
return 0x2b;
} else if (n == 63) {
return 0x2f;
}
throw new Error('n:' + n);
};
_this.writeByte = function(n) {
_buffer = (_buffer << 8) | (n & 0xff);
_buflen += 8;
_length += 1;
while (_buflen >= 6) {
writeEncoded(_buffer >>> (_buflen - 6) );
_buflen -= 6;
}
};
_this.flush = function() {
if (_buflen > 0) {
writeEncoded(_buffer << (6 - _buflen) );
_buffer = 0;
_buflen = 0;
}
if (_length % 3 != 0) {
// padding
var padlen = 3 - _length % 3;
for (var i = 0; i < padlen; i += 1) {
_base64 += '=';
}
}
};
_this.toString = function() {
return _base64;
};
return _this;
};
//---------------------------------------------------------------------
// base64DecodeInputStream
//---------------------------------------------------------------------
var base64DecodeInputStream = function(str) {
var _str = str;
var _pos = 0;
var _buffer = 0;
var _buflen = 0;
var _this = {};
_this.read = function() {
while (_buflen < 8) {
if (_pos >= _str.length) {
if (_buflen == 0) {
return -1;
}
throw new Error('unexpected end of file./' + _buflen);
}
var c = _str.charAt(_pos);
_pos += 1;
if (c == '=') {
_buflen = 0;
return -1;
} else if (c.match(/^\s$/) ) {
// ignore if whitespace.
continue;
}
_buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
_buflen += 6;
}
var n = (_buffer >>> (_buflen - 8) ) & 0xff;
_buflen -= 8;
return n;
};
var decode = function(c) {
if (0x41 <= c && c <= 0x5a) {
return c - 0x41;
} else if (0x61 <= c && c <= 0x7a) {
return c - 0x61 + 26;
} else if (0x30 <= c && c <= 0x39) {
return c - 0x30 + 52;
} else if (c == 0x2b) {
return 62;
} else if (c == 0x2f) {
return 63;
} else {
throw new Error('c:' + c);
}
};
return _this;
};
//---------------------------------------------------------------------
// gifImage (B/W)
//---------------------------------------------------------------------
var gifImage = function(width, height) {
var _width = width;
var _height = height;
var _data = new Array(width * height);
var _this = {};
_this.setPixel = function(x, y, pixel) {
_data[y * _width + x] = pixel;
};
_this.write = function(out) {
//---------------------------------
// GIF Signature
out.writeString('GIF87a');
//---------------------------------
// Screen Descriptor
out.writeShort(_width);
out.writeShort(_height);
out.writeByte(0x80); // 2bit
out.writeByte(0);
out.writeByte(0);
//---------------------------------
// Global Color Map
// black
out.writeByte(0x00);
out.writeByte(0x00);
out.writeByte(0x00);
// white
out.writeByte(0xff);
out.writeByte(0xff);
out.writeByte(0xff);
//---------------------------------
// Image Descriptor
out.writeString(',');
out.writeShort(0);
out.writeShort(0);
out.writeShort(_width);
out.writeShort(_height);
out.writeByte(0);
//---------------------------------
// Local Color Map
//---------------------------------
// Raster Data
var lzwMinCodeSize = 2;
var raster = getLZWRaster(lzwMinCodeSize);
out.writeByte(lzwMinCodeSize);
var offset = 0;
while (raster.length - offset > 255) {
out.writeByte(255);
out.writeBytes(raster, offset, 255);
offset += 255;
}
out.writeByte(raster.length - offset);
out.writeBytes(raster, offset, raster.length - offset);
out.writeByte(0x00);
//---------------------------------
// GIF Terminator
out.writeString(';');
};
var bitOutputStream = function(out) {
var _out = out;
var _bitLength = 0;
var _bitBuffer = 0;
var _this = {};
_this.write = function(data, length) {
if ( (data >>> length) != 0) {
throw new Error('length over');
}
while (_bitLength + length >= 8) {
_out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
length -= (8 - _bitLength);
data >>>= (8 - _bitLength);
_bitBuffer = 0;
_bitLength = 0;
}
_bitBuffer = (data << _bitLength) | _bitBuffer;
_bitLength = _bitLength + length;
};
_this.flush = function() {
if (_bitLength > 0) {
_out.writeByte(_bitBuffer);
}
};
return _this;
};
var getLZWRaster = function(lzwMinCodeSize) {
var clearCode = 1 << lzwMinCodeSize;
var endCode = (1 << lzwMinCodeSize) + 1;
var bitLength = lzwMinCodeSize + 1;
// Setup LZWTable
var table = lzwTable();
for (var i = 0; i < clearCode; i += 1) {
table.add(String.fromCharCode(i) );
}
table.add(String.fromCharCode(clearCode) );
table.add(String.fromCharCode(endCode) );
var byteOut = byteArrayOutputStream();
var bitOut = bitOutputStream(byteOut);
// clear code
bitOut.write(clearCode, bitLength);
var dataIndex = 0;
var s = String.fromCharCode(_data[dataIndex]);
dataIndex += 1;
while (dataIndex < _data.length) {
var c = String.fromCharCode(_data[dataIndex]);
dataIndex += 1;
if (table.contains(s + c) ) {
s = s + c;
} else {
bitOut.write(table.indexOf(s), bitLength);
if (table.size() < 0xfff) {
if (table.size() == (1 << bitLength) ) {
bitLength += 1;
}
table.add(s + c);
}
s = c;
}
}
bitOut.write(table.indexOf(s), bitLength);
// end code
bitOut.write(endCode, bitLength);
bitOut.flush();
return byteOut.toByteArray();
};
var lzwTable = function() {
var _map = {};
var _size = 0;
var _this = {};
_this.add = function(key) {
if (_this.contains(key) ) {
throw new Error('dup key:' + key);
}
_map[key] = _size;
_size += 1;
};
_this.size = function() {
return _size;
};
_this.indexOf = function(key) {
return _map[key];
};
_this.contains = function(key) {
return typeof _map[key] != 'undefined';
};
return _this;
};
return _this;
};
var createImgTag = function(width, height, getPixel, alt) {
var gif = gifImage(width, height);
for (var y = 0; y < height; y += 1) {
for (var x = 0; x < width; x += 1) {
gif.setPixel(x, y, getPixel(x, y) );
}
}
var b = byteArrayOutputStream();
gif.write(b);
var base64 = base64EncodeOutputStream();
var bytes = b.toByteArray();
for (var i = 0; i < bytes.length; i += 1) {
base64.writeByte(bytes[i]);
}
base64.flush();
var img = '';
img += '<img';
img += '\u0020src="';
img += 'data:image/gif;base64,';
img += base64;
img += '"';
img += '\u0020width="';
img += width;
img += '"';
img += '\u0020height="';
img += height;
img += '"';
if (alt) {
img += '\u0020alt="';
img += alt;
img += '"';
}
img += '/>';
return img;
};
//---------------------------------------------------------------------
// returns qrcode function.
return qrcode;
}();
(function (factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof exports === 'object') {
module.exports = factory();
}
}(function () {
return qrcode;
}));
//---------------------------------------------------------------------
//
// QR Code Generator for JavaScript UTF8 Support (optional)
//
// Copyright (c) 2011 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word 'QR Code' is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
!function(qrcode) {
//---------------------------------------------------------------------
// overwrite qrcode.stringToBytes
//---------------------------------------------------------------------
qrcode.stringToBytes = function(s) {
// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
function toUTF8Array(str) {
var utf8 = [];
for (var i=0; i < str.length; i++) {
var charcode = str.charCodeAt(i);
if (charcode < 0x80) utf8.push(charcode);
else if (charcode < 0x800) {
utf8.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
}
else if (charcode < 0xd800 || charcode >= 0xe000) {
utf8.push(0xe0 | (charcode >> 12),
0x80 | ((charcode>>6) & 0x3f),
0x80 | (charcode & 0x3f));
}
// surrogate pair
else {
i++;
// UTF-16 encodes 0x10000-0x10FFFF by
// subtracting 0x10000 and splitting the
// 20 bits of 0x0-0xFFFFF into two halves
charcode = 0x10000 + (((charcode & 0x3ff)<<10)
| (str.charCodeAt(i) & 0x3ff));
utf8.push(0xf0 | (charcode >>18),
0x80 | ((charcode>>12) & 0x3f),
0x80 | ((charcode>>6) & 0x3f),
0x80 | (charcode & 0x3f));
}
}
return utf8;
}
return toUTF8Array(s);
};
}(qrcode);
return qrcode;
}()));
(function( $ ) {
'use strict';
$.fn.tableToJSON = function(opts) {
// Set options
var defaults = {
ignoreColumns: [],
onlyColumns: null,
ignoreHiddenRows: true,
headings: null,
allowHTML: false
};
opts = $.extend(defaults, opts);
var notNull = function(value) {
return value !== undefined && value !== null;
};
var ignoredColumn = function(index) {
if( notNull(opts.onlyColumns) ) {
return $.inArray(index, opts.onlyColumns) === -1;
}
return $.inArray(index, opts.ignoreColumns) !== -1;
};
var arraysToHash = function(keys, values) {
var result = {}, index = 0;
$.each(values, function(i, value) {
// when ignoring columns, the header option still starts
// with the first defined column
if ( index < keys.length && notNull(value) ) {
result[ keys[index] ] = value;
index++;
}
});
return result;
};
var cellValues = function(cellIndex, cell) {
var value, result;
var override = $(cell).data('override');
if ( opts.allowHTML ) {
value = $.trim($(cell).html());
} else {
value = $.trim($(cell).text());
}
result = notNull(override) ? override : value;
return result;
};
var rowValues = function(row) {
var result = [];
$(row).children('td,th').each(function(cellIndex, cell) {
result.push( cellValues(cellIndex, cell) );
});
return result;
};
var getHeadings = function(table) {
var firstRow = table.find('tr:first').first();
return notNull(opts.headings) ? opts.headings : rowValues(firstRow);
};
var construct = function(table, headings) {
var i, j, len, len2, txt, $row, $cell,
tmpArray = [], cellIndex = 0, result = [];
table.children('tbody,*').children('tr').each(function(rowIndex, row) {
if( rowIndex > 0 || notNull(opts.headings) ) {
$row = $(row);
if( $row.is(':visible') || !opts.ignoreHiddenRows ) {
if (!tmpArray[rowIndex]) {
tmpArray[rowIndex] = [];
}
cellIndex = 0;
$row.children().each(function(){
$cell = $(this);
// process rowspans
if ($cell.filter('[rowspan]').length) {
len = parseInt( $cell.attr('rowspan'), 10) - 1;
txt = cellValues(cellIndex, $cell, []);
for (i = 1; i <= len; i++) {
if (!tmpArray[rowIndex + i]) { tmpArray[rowIndex + i] = []; }
tmpArray[rowIndex + i][cellIndex] = txt;
}
}
// process colspans
if ($cell.filter('[colspan]').length) {
len = parseInt( $cell.attr('colspan'), 10) - 1;
txt = cellValues(cellIndex, $cell, []);
for (i = 1; i <= len; i++) {
// cell has both col and row spans
if ($cell.filter('[rowspan]').length) {
len2 = parseInt( $cell.attr('rowspan'), 10);
for (j = 0; j < len2; j++) {
tmpArray[rowIndex + j][cellIndex + i] = txt;
}
} else {
tmpArray[rowIndex][cellIndex + i] = txt;
}
}
}
// skip column if already defined
while (tmpArray[rowIndex][cellIndex]) { cellIndex++; }
txt = tmpArray[rowIndex][cellIndex] || cellValues(cellIndex, $cell, []);
if (notNull(txt)) {
tmpArray[rowIndex][cellIndex] = txt;
}
cellIndex++;
});
}
}
});
$.each(tmpArray, function( i, row ){
if (notNull(row)) {
// remove ignoredColumns / add onlyColumns
var newRow = notNull(opts.onlyColumns) || opts.ignoreColumns.length ?
$.grep(row, function(v, index){ return !ignoredColumn(index); }) : row,
// remove ignoredColumns / add onlyColumns if headings is not defined
newHeadings = notNull(opts.headings) ? headings :
$.grep(headings, function(v, index){ return !ignoredColumn(index); });
txt = arraysToHash(newHeadings, newRow);
result[result.length] = txt;
}
});
return result;
};
// Run
var headings = getHeadings(this);
return construct(this, headings);
};
})( jQuery );
\ No newline at end of file
(function ( $ ) {
/**
* Holds google map object and related utility entities.
* @constructor
*/
function GMapContext(domElement, options) {
var _map = new google.maps.Map(domElement, options);
var _marker = new google.maps.Marker({
position: new google.maps.LatLng(54.19335, -3.92695),
map: _map,
title: "Drag Me",
draggable: options.draggable
});
return {
map: _map,
marker: _marker,
circle: null,
location: _marker.position,
radius: options.radius,
locationName: options.locationName,
addressComponents: {
formatted_address: null,
addressLine1: null,
addressLine2: null,
streetName: null,
streetNumber: null,
city: null,
state: null,
stateOrProvince: null
},
settings: options.settings,
domContainer: domElement,
geodecoder: new google.maps.Geocoder()
}
}
// Utility functions for Google Map Manipulations
var GmUtility = {
/**
* Draw a circle over the the map. Returns circle object.
* Also writes new circle object in gmapContext.
*
* @param center - LatLng of the center of the circle
* @param radius - radius in meters
* @param gmapContext - context
* @param options
*/
drawCircle: function(gmapContext, center, radius, options) {
if (gmapContext.circle != null) {
gmapContext.circle.setMap(null);
}
if (radius > 0) {
radius *= 1;
options = $.extend({
strokeColor: "#0000FF",
strokeOpacity: 0.35,
strokeWeight: 2,
fillColor: "#0000FF",
fillOpacity: 0.20
}, options);
options.map = gmapContext.map;
options.radius = radius;
options.center = center;
gmapContext.circle = new google.maps.Circle(options);
return gmapContext.circle;
}
return null;
},
/**
*
* @param gMapContext
* @param location
* @param callback
*/
setPosition: function(gMapContext, location, callback) {
gMapContext.location = location;
gMapContext.marker.setPosition(location);
gMapContext.map.panTo(location);
this.drawCircle(gMapContext, location, gMapContext.radius, {});
if (gMapContext.settings.enableReverseGeocode) {
gMapContext.geodecoder.geocode({latLng: gMapContext.location}, function(results, status){
if (status == google.maps.GeocoderStatus.OK && results.length > 0){
gMapContext.locationName = results[0].formatted_address;
gMapContext.addressComponents =
GmUtility.address_component_from_google_geocode(results[0].address_components);
}
if (callback) {
callback.call(this, gMapContext);
}
});
} else {
if (callback) {
callback.call(this, gMapContext);
}
}
},
locationFromLatLng: function(lnlg) {
return {latitude: lnlg.lat(), longitude: lnlg.lng()}
},
address_component_from_google_geocode: function(address_components) {
var result = {};
for (var i = address_components.length-1; i>=0; i--) {
var component = address_components[i];
// Postal code
if (component.types.indexOf('postal_code') >= 0) {
result.postalCode = component.short_name;
}
// Street number
else if (component.types.indexOf('street_number') >= 0) {
result.streetNumber = component.short_name;
}
// Street name
else if (component.types.indexOf('route') >= 0) {
result.streetName = component.short_name;
}
// City
else if (component.types.indexOf('sublocality') >= 0) {
result.city = component.short_name;
}
// State \ Province
else if (component.types.indexOf('administrative_area_level_1') >= 0) {
result.stateOrProvince = component.short_name;
}
// State \ Province
else if (component.types.indexOf('country') >= 0) {
result.country = component.short_name;
}
}
result.addressLine1 = [result.streetNumber, result.streetName].join(' ').trim();
result.addressLine2 = '';
return result;
}
};
function isPluginApplied(domObj) {
return getContextForElement(domObj) != undefined;
}
function getContextForElement(domObj) {
return $(domObj).data("locationpicker");
}
function updateInputValues(inputBinding, gmapContext){
if (!inputBinding) return;
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
if (inputBinding.latitudeInput) {
inputBinding.latitudeInput.val(currentLocation.latitude);
}
if (inputBinding.longitudeInput) {
inputBinding.longitudeInput.val(currentLocation.longitude);
}
if (inputBinding.radiusInput) {
inputBinding.radiusInput.val(gmapContext.radius);
}
if (inputBinding.locationNameInput) {
inputBinding.locationNameInput.val(gmapContext.locationName);
}
}
function setupInputListenersInput(inputBinding, gmapContext) {
if (inputBinding) {
if (inputBinding.radiusInput){
inputBinding.radiusInput.on("change", function() {
gmapContext.radius = $(this).val();
GmUtility.setPosition(gmapContext, gmapContext.location, function(context){
context.settings.onchanged.apply(gmapContext.domContainer,
[GmUtility.locationFromLatLng(context.location), context.radius, false]);
});
});
}
if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0));
google.maps.event.addListener(gmapContext.autocomplete, 'place_changed', function() {
var place = gmapContext.autocomplete.getPlace();
if (!place.geometry) {
gmapContext.settings.onlocationnotfound(place.name);
return;
}
GmUtility.setPosition(gmapContext, place.geometry.location, function(context) {
updateInputValues(inputBinding, context);
context.settings.onchanged.apply(gmapContext.domContainer,
[GmUtility.locationFromLatLng(context.location), context.radius, false]);
});
});
}
if (inputBinding.latitudeInput) {
inputBinding.latitudeInput.on("change", function() {
GmUtility.setPosition(gmapContext, new google.maps.LatLng($(this).val(), gmapContext.location.lng()), function(context){
context.settings.onchanged.apply(gmapContext.domContainer,
[GmUtility.locationFromLatLng(context.location), context.radius, false]);
});
});
}
if (inputBinding.longitudeInput) {
inputBinding.longitudeInput.on("change", function() {
GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), $(this).val()), function(context){
context.settings.onchanged.apply(gmapContext.domContainer,
[GmUtility.locationFromLatLng(context.location), context.radius, false]);
});
});
}
}
}
/**
* Initialization:
* $("#myMap").locationpicker(options);
* @param options
* @param params
* @returns {*}
*/
$.fn.locationpicker = function( options, params ) {
if (typeof options == 'string') { // Command provided
var _targetDomElement = this.get(0);
// Plug-in is not applied - nothing to do.
if (!isPluginApplied(_targetDomElement)) return;
var gmapContext = getContextForElement(_targetDomElement);
switch (options) {
case "location":
if (params == undefined) { // Getter
var location = GmUtility.locationFromLatLng(gmapContext.location);
location.radius = gmapContext.radius;
location.name = gmapContext.locationName;
return location;
} else { // Setter
if (params.radius) {
gmapContext.radius = params.radius;
}
GmUtility.setPosition(gmapContext, new google.maps.LatLng(params.latitude, params.longitude), function(gmapContext) {
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
});
}
break;
case "subscribe":
/**
* Provides interface for subscribing for GoogleMap events.
* See Google API documentation for details.
* Parameters:
* - event: string, name of the event
* - callback: function, callback function to be invoked
*/
if (params == undefined) { // Getter is not available
return null;
} else {
var event = params.event;
var callback = params.callback;
if (!event || ! callback) {
console.error("LocationPicker: Invalid arguments for method \"subscribe\"")
return null;
}
google.maps.event.addListener(gmapContext.map, event, callback);
}
break;
case "map":
/**
* Returns object which allows access actual google widget and marker paced on it.
* Structure: {
* map: Instance of the google map widget
* marker: marker placed on map
* }
*/
if (params == undefined) { // Getter is not available
var locationObj = GmUtility.locationFromLatLng(gmapContext.location);
locationObj.formattedAddress = gmapContext.locationName;
locationObj.addressComponents = gmapContext.addressComponents;
return {
map: gmapContext.map,
marker: gmapContext.marker,
location: locationObj
}
} else {
return null;
}
}
return null;
}
return this.each(function() {
var $target = $(this);
// If plug-in hasn't been applied before - initialize, otherwise - skip
if (isPluginApplied(this)) return;
// Plug-in initialization is required
// Defaults
var settings = $.extend({}, $.fn.locationpicker.defaults, options );
// Initialize
var gmapContext = new GMapContext(this, {
zoom: settings.zoom,
center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
disableDoubleClickZoom: false,
scrollwheel: settings.scrollwheel,
streetViewControl: false,
radius: settings.radius,
locationName: settings.locationName,
settings: settings,
draggable: settings.draggable
});
$target.data("locationpicker", gmapContext);
// Subscribe GMap events
google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context){
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
context.settings.onchanged.apply(gmapContext.domContainer, [currentLocation, context.radius, true]);
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
});
});
GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context){
updateInputValues(settings.inputBinding, gmapContext);
context.settings.oninitialized($target);
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
settings.onchanged.apply(gmapContext.domContainer, [currentLocation, context.radius, false]);
});
// Set up input bindings if needed
setupInputListenersInput(settings.inputBinding, gmapContext);
});
};
$.fn.locationpicker.defaults = {
location: {latitude: 40.7324319, longitude: -73.82480799999996},
locationName: "",
radius: 500,
zoom: 15,
scrollwheel: true,
inputBinding: {
latitudeInput: null,
longitudeInput: null,
radiusInput: null,
locationNameInput: null
},
enableAutocomplete: false,
enableReverseGeocode: true,
draggable: true,
onchanged: function(currentLocation, radius, isMarkerDropped) {},
onlocationnotfound: function(locationName) {},
oninitialized: function (component) {}
}
}( jQuery ));
{
"name": "locationpicker",
"title": "jQuery Location Picker",
"description": "This plug-in allows to easily find and select a location on the Google map. Along with a single point selection, it allows to choose an area by providing its center and the radius. All the data can be saved to any HTML input element automatically as well as be processed by Javascript (callback support). The other feature of the plug-in is automatic address resolver which allows to get address line from the selected latitude and longitude. The plug-in also supports searching by address typed into the bound input element which uses auto-complete feature from Google API to make the search process easier. In this case the marker will be automatically positioned on the map after successful address resolution.",
"keywords": [
"googlemap",
"gmapapi", "location",
"input",
"map",
"radius"
],
"version": "0.1.9",
"author": {
"name": "Dmitry Berezovsky",
"url": "http://logicify.com/"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/Logicify/jquery-locationpicker-plugin/blob/master/LICENSE"
}
],
"bugs": "https://github.com/Logicify/jquery-locationpicker-plugin/issues",
"homepage": "http://logicify.github.io/jquery-locationpicker-plugin/",
"docs": "http://logicify.github.io/jquery-locationpicker-plugin/",
"download": "https://github.com/Logicify/jquery-locationpicker-plugin/archive/master.zip",
"dependencies": {
"jquery": ">=1.5"
}
}
!function(a){a(["jquery"],function(a){return function(){function b(a,b,c){return o({type:u.error,iconClass:p().iconClasses.error,message:a,optionsOverride:c,title:b})}function c(b,c){return b||(b=p()),r=a("#"+b.containerId),r.length?r:(c&&(r=l(b)),r)}function d(a,b,c){return o({type:u.info,iconClass:p().iconClasses.info,message:a,optionsOverride:c,title:b})}function e(a){s=a}function f(a,b,c){return o({type:u.success,iconClass:p().iconClasses.success,message:a,optionsOverride:c,title:b})}function g(a,b,c){return o({type:u.warning,iconClass:p().iconClasses.warning,message:a,optionsOverride:c,title:b})}function h(a){var b=p();r||c(b),k(a,b)||j(b)}function i(b){var d=p();return r||c(d),b&&0===a(":focus",b).length?void q(b):void(r.children().length&&r.remove())}function j(b){for(var c=r.children(),d=c.length-1;d>=0;d--)k(a(c[d]),b)}function k(b,c){return b&&0===a(":focus",b).length?(b[c.hideMethod]({duration:c.hideDuration,easing:c.hideEasing,complete:function(){q(b)}}),!0):!1}function l(b){return r=a("<div/>").attr("id",b.containerId).addClass(b.positionClass).attr("aria-live","polite").attr("role","alert"),r.appendTo(a(b.target)),r}function m(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",target:"body",closeHtml:"<button>&times;</button>",newestOnTop:!0}}function n(a){s&&s(a)}function o(b){function d(b){return!a(":focus",j).length||b?j[g.hideMethod]({duration:g.hideDuration,easing:g.hideEasing,complete:function(){q(j),g.onHidden&&"hidden"!==o.state&&g.onHidden(),o.state="hidden",o.endTime=new Date,n(o)}}):void 0}function e(){(g.timeOut>0||g.extendedTimeOut>0)&&(i=setTimeout(d,g.extendedTimeOut))}function f(){clearTimeout(i),j.stop(!0,!0)[g.showMethod]({duration:g.showDuration,easing:g.showEasing})}var g=p(),h=b.iconClass||g.iconClass;"undefined"!=typeof b.optionsOverride&&(g=a.extend(g,b.optionsOverride),h=b.optionsOverride.iconClass||h),t++,r=c(g,!0);var i=null,j=a("<div/>"),k=a("<div/>"),l=a("<div/>"),m=a(g.closeHtml),o={toastId:t,state:"visible",startTime:new Date,options:g,map:b};return b.iconClass&&j.addClass(g.toastClass).addClass(h),b.title&&(k.append(b.title).addClass(g.titleClass),j.append(k)),b.message&&(l.append(b.message).addClass(g.messageClass),j.append(l)),g.closeButton&&(m.addClass("toast-close-button").attr("role","button"),j.prepend(m)),j.hide(),g.newestOnTop?r.prepend(j):r.append(j),j[g.showMethod]({duration:g.showDuration,easing:g.showEasing,complete:g.onShown}),g.timeOut>0&&(i=setTimeout(d,g.timeOut)),j.hover(f,e),!g.onclick&&g.tapToDismiss&&j.click(d),g.closeButton&&m&&m.click(function(a){a.stopPropagation?a.stopPropagation():void 0!==a.cancelBubble&&a.cancelBubble!==!0&&(a.cancelBubble=!0),d(!0)}),g.onclick&&j.click(function(){g.onclick(),d()}),n(o),g.debug&&console&&console.log(o),j}function p(){return a.extend({},m(),v.options)}function q(a){r||(r=c()),a.is(":visible")||(a.remove(),a=null,0===r.children().length&&r.remove())}var r,s,t=0,u={error:"error",info:"info",success:"success",warning:"warning"},v={clear:h,remove:i,error:b,getContainer:c,info:d,options:{},subscribe:e,success:f,version:"2.0.3",warning:g};return v}()})}("function"==typeof define&&define.amd?define:function(a,b){"undefined"!=typeof module&&module.exports?module.exports=b(require("jquery")):window.toastr=b(window.jQuery)});
\ No newline at end of file
/*
wysihtml5 v0.3.0_rc2
https://github.com/xing/wysihtml5
Author: Christopher Blum (https://github.com/tiff)
Copyright (C) 2012 XING AG
Licensed under the MIT license (MIT)
Rangy, a cross-browser JavaScript range and selection library
http://code.google.com/p/rangy/
Copyright 2011, Tim Down
Licensed under the MIT license.
Version: 1.2.2
Build date: 13 November 2011
*/
var wysihtml5={version:"0.3.0_rc2",commands:{},dom:{},quirks:{},toolbar:{},lang:{},selection:{},views:{},INVISIBLE_SPACE:"\ufeff",EMPTY_FUNCTION:function(){},ELEMENT_NODE:1,TEXT_NODE:3,BACKSPACE_KEY:8,ENTER_KEY:13,ESCAPE_KEY:27,SPACE_KEY:32,DELETE_KEY:46};
window.rangy=function(){function b(a,b){var c=typeof a[b];return c==k||!!(c==g&&a[b])||"unknown"==c}function c(a,b){return!!(typeof a[b]==g&&a[b])}function a(a,b){return typeof a[b]!=j}function d(a){return function(b,c){for(var d=c.length;d--;)if(!a(b,c[d]))return!1;return!0}}function e(a){return a&&m(a,r)&&x(a,p)}function f(a){window.alert("Rangy not supported in your browser. Reason: "+a);o.initialized=!0;o.supported=!1}function h(){if(!o.initialized){var a,d=!1,g=!1;b(document,"createRange")&&
(a=document.createRange(),m(a,n)&&x(a,q)&&(d=!0),a.detach());if((a=c(document,"body")?document.body:document.getElementsByTagName("body")[0])&&b(a,"createTextRange"))a=a.createTextRange(),e(a)&&(g=!0);!d&&!g&&f("Neither Range nor TextRange are implemented");o.initialized=!0;o.features={implementsDomRange:d,implementsTextRange:g};d=w.concat(z);g=0;for(a=d.length;g<a;++g)try{d[g](o)}catch(j){c(window,"console")&&b(window.console,"log")&&window.console.log("Init listener threw an exception. Continuing.",
j)}}}function i(a){this.name=a;this.supported=this.initialized=!1}var g="object",k="function",j="undefined",q="startContainer,startOffset,endContainer,endOffset,collapsed,commonAncestorContainer,START_TO_START,START_TO_END,END_TO_START,END_TO_END".split(","),n="setStart,setStartBefore,setStartAfter,setEnd,setEndBefore,setEndAfter,collapse,selectNode,selectNodeContents,compareBoundaryPoints,deleteContents,extractContents,cloneContents,insertNode,surroundContents,cloneRange,toString,detach".split(","),
p="boundingHeight,boundingLeft,boundingTop,boundingWidth,htmlText,text".split(","),r="collapse,compareEndPoints,duplicate,getBookmark,moveToBookmark,moveToElementText,parentElement,pasteHTML,select,setEndPoint,getBoundingClientRect".split(","),m=d(b),s=d(c),x=d(a),o={version:"1.2.2",initialized:!1,supported:!0,util:{isHostMethod:b,isHostObject:c,isHostProperty:a,areHostMethods:m,areHostObjects:s,areHostProperties:x,isTextRange:e},features:{},modules:{},config:{alertOnWarn:!1,preferTextRange:!1}};
o.fail=f;o.warn=function(a){a="Rangy warning: "+a;o.config.alertOnWarn?window.alert(a):typeof window.console!=j&&typeof window.console.log!=j&&window.console.log(a)};({}).hasOwnProperty?o.util.extend=function(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}:f("hasOwnProperty not supported");var z=[],w=[];o.init=h;o.addInitListener=function(a){o.initialized?a(o):z.push(a)};var y=[];o.addCreateMissingNativeApiListener=function(a){y.push(a)};o.createMissingNativeApi=function(a){a=a||window;h();
for(var b=0,c=y.length;b<c;++b)y[b](a)};i.prototype.fail=function(a){this.initialized=!0;this.supported=!1;throw Error("Module '"+this.name+"' failed to load: "+a);};i.prototype.warn=function(a){o.warn("Module "+this.name+": "+a)};i.prototype.createError=function(a){return Error("Error in Rangy "+this.name+" module: "+a)};o.createModule=function(a,b){var c=new i(a);o.modules[a]=c;w.push(function(a){b(a,c);c.initialized=!0;c.supported=!0})};o.requireModules=function(a){for(var b=0,c=a.length,d,g;b<
c;++b){g=a[b];d=o.modules[g];if(!d||!(d instanceof i))throw Error("Module '"+g+"' not found");if(!d.supported)throw Error("Module '"+g+"' not supported");}};var A=!1,s=function(){A||(A=!0,o.initialized||h())};if(typeof window==j)f("No window found");else if(typeof document==j)f("No document found");else return b(document,"addEventListener")&&document.addEventListener("DOMContentLoaded",s,!1),b(window,"addEventListener")?window.addEventListener("load",s,!1):b(window,"attachEvent")?window.attachEvent("onload",
s):f("Window does not have required addEventListener or attachEvent method"),o}();
rangy.createModule("DomUtil",function(b,c){function a(a){for(var b=0;a=a.previousSibling;)b++;return b}function d(a,b){var c=[],d;for(d=a;d;d=d.parentNode)c.push(d);for(d=b;d;d=d.parentNode)if(m(c,d))return d;return null}function e(a,b,c){for(c=c?a:a.parentNode;c;){a=c.parentNode;if(a===b)return c;c=a}return null}function f(a){a=a.nodeType;return 3==a||4==a||8==a}function h(a,b){var c=b.nextSibling,d=b.parentNode;c?d.insertBefore(a,c):d.appendChild(a);return a}function i(a){if(9==a.nodeType)return a;
if(typeof a.ownerDocument!=n)return a.ownerDocument;if(typeof a.document!=n)return a.document;if(a.parentNode)return i(a.parentNode);throw Error("getDocument: no document found for node");}function g(a){return!a?"[No node]":f(a)?'"'+a.data+'"':1==a.nodeType?"<"+a.nodeName+(a.id?' id="'+a.id+'"':"")+">["+a.childNodes.length+"]":a.nodeName}function k(a){this._next=this.root=a}function j(a,b){this.node=a;this.offset=b}function q(a){this.code=this[a];this.codeName=a;this.message="DOMException: "+this.codeName}
var n="undefined",p=b.util;p.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||c.fail("document missing a Node creation method");p.isHostMethod(document,"getElementsByTagName")||c.fail("document missing getElementsByTagName method");var r=document.createElement("div");p.areHostMethods(r,["insertBefore","appendChild","cloneNode"])||c.fail("Incomplete Element implementation");p.isHostProperty(r,"innerHTML")||c.fail("Element is missing innerHTML property");r=document.createTextNode("test");
p.areHostMethods(r,["splitText","deleteData","insertData","appendData","cloneNode"])||c.fail("Incomplete Text Node implementation");var m=function(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1};k.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next,b;if(this._current){b=a.firstChild;if(!b)for(b=null;a!==this.root&&!(b=a.nextSibling);)a=a.parentNode;this._next=b}return this._current},detach:function(){this._current=this._next=this.root=
null}};j.prototype={equals:function(a){return this.node===a.node&this.offset==a.offset},inspect:function(){return"[DomPosition("+g(this.node)+":"+this.offset+")]"}};q.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11};q.prototype.toString=function(){return this.message};b.dom={arrayContains:m,isHtmlNamespace:function(a){var b;return typeof a.namespaceURI==n||null===(b=a.namespaceURI)||"http://www.w3.org/1999/xhtml"==
b},parentElement:function(a){a=a.parentNode;return 1==a.nodeType?a:null},getNodeIndex:a,getNodeLength:function(a){var b;return f(a)?a.length:(b=a.childNodes)?b.length:0},getCommonAncestor:d,isAncestorOf:function(a,b,c){for(b=c?b:b.parentNode;b;){if(b===a)return!0;b=b.parentNode}return!1},getClosestAncestorIn:e,isCharacterDataNode:f,insertAfter:h,splitDataNode:function(a,b){var c=a.cloneNode(!1);c.deleteData(0,b);a.deleteData(b,a.length-b);h(c,a);return c},getDocument:i,getWindow:function(a){a=i(a);
if(typeof a.defaultView!=n)return a.defaultView;if(typeof a.parentWindow!=n)return a.parentWindow;throw Error("Cannot get a window object for node");},getIframeWindow:function(a){if(typeof a.contentWindow!=n)return a.contentWindow;if(typeof a.contentDocument!=n)return a.contentDocument.defaultView;throw Error("getIframeWindow: No Window object found for iframe element");},getIframeDocument:function(a){if(typeof a.contentDocument!=n)return a.contentDocument;if(typeof a.contentWindow!=n)return a.contentWindow.document;
throw Error("getIframeWindow: No Document object found for iframe element");},getBody:function(a){return p.isHostObject(a,"body")?a.body:a.getElementsByTagName("body")[0]},getRootContainer:function(a){for(var b;b=a.parentNode;)a=b;return a},comparePoints:function(b,c,g,j){var k;if(b==g)return c===j?0:c<j?-1:1;if(k=e(g,b,!0))return c<=a(k)?-1:1;if(k=e(b,g,!0))return a(k)<j?-1:1;c=d(b,g);b=b===c?c:e(b,c,!0);g=g===c?c:e(g,c,!0);if(b===g)throw Error("comparePoints got to case 4 and childA and childB are the same!");
for(c=c.firstChild;c;){if(c===b)return-1;if(c===g)return 1;c=c.nextSibling}throw Error("Should not be here!");},inspectNode:g,fragmentFromNodeChildren:function(a){for(var b=i(a).createDocumentFragment(),c;c=a.firstChild;)b.appendChild(c);return b},createIterator:function(a){return new k(a)},DomPosition:j};b.DOMException=q});
rangy.createModule("DomRange",function(b){function c(a,b){return 3!=a.nodeType&&(l.isAncestorOf(a,b.startContainer,!0)||l.isAncestorOf(a,b.endContainer,!0))}function a(a){return l.getDocument(a.startContainer)}function d(a,b,c){if(b=a._listeners[b])for(var d=0,g=b.length;d<g;++d)b[d].call(a,{target:a,args:c})}function e(a){return new u(a.parentNode,l.getNodeIndex(a))}function f(a){return new u(a.parentNode,l.getNodeIndex(a)+1)}function h(a,b,c){var d=11==a.nodeType?a.firstChild:a;l.isCharacterDataNode(b)?
c==b.length?l.insertAfter(a,b):b.parentNode.insertBefore(a,0==c?b:l.splitDataNode(b,c)):c>=b.childNodes.length?b.appendChild(a):b.insertBefore(a,b.childNodes[c]);return d}function i(b){for(var c,d,g=a(b.range).createDocumentFragment();d=b.next();){c=b.isPartiallySelectedSubtree();d=d.cloneNode(!c);c&&(c=b.getSubtreeIterator(),d.appendChild(i(c)),c.detach(!0));if(10==d.nodeType)throw new B("HIERARCHY_REQUEST_ERR");g.appendChild(d)}return g}function g(a,b,c){for(var d,e,c=c||{stop:!1};d=a.next();)if(a.isPartiallySelectedSubtree())if(!1===
b(d)){c.stop=!0;break}else{if(d=a.getSubtreeIterator(),g(d,b,c),d.detach(!0),c.stop)break}else for(d=l.createIterator(d);e=d.next();)if(!1===b(e)){c.stop=!0;return}}function k(a){for(var b;a.next();)a.isPartiallySelectedSubtree()?(b=a.getSubtreeIterator(),k(b),b.detach(!0)):a.remove()}function j(b){for(var c,d=a(b.range).createDocumentFragment(),g;c=b.next();){b.isPartiallySelectedSubtree()?(c=c.cloneNode(!1),g=b.getSubtreeIterator(),c.appendChild(j(g)),g.detach(!0)):b.remove();if(10==c.nodeType)throw new B("HIERARCHY_REQUEST_ERR");
d.appendChild(c)}return d}function q(a,b,c){var d=!(!b||!b.length),e,j=!!c;d&&(e=RegExp("^("+b.join("|")+")$"));var k=[];g(new p(a,!1),function(a){(!d||e.test(a.nodeType))&&(!j||c(a))&&k.push(a)});return k}function n(a){return"["+("undefined"==typeof a.getName?"Range":a.getName())+"("+l.inspectNode(a.startContainer)+":"+a.startOffset+", "+l.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function p(a,b){this.range=a;this.clonePartiallySelectedTextNodes=b;if(!a.collapsed){this.sc=a.startContainer;
this.so=a.startOffset;this.ec=a.endContainer;this.eo=a.endOffset;var c=a.commonAncestorContainer;this.sc===this.ec&&l.isCharacterDataNode(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc===c&&!l.isCharacterDataNode(this.sc)?this.sc.childNodes[this.so]:l.getClosestAncestorIn(this.sc,c,!0),this._last=this.ec===c&&!l.isCharacterDataNode(this.ec)?this.ec.childNodes[this.eo-1]:l.getClosestAncestorIn(this.ec,c,!0))}}function r(a){this.code=
this[a];this.codeName=a;this.message="RangeException: "+this.codeName}function m(a,b,c){this.nodes=q(a,b,c);this._next=this.nodes[0];this._position=0}function s(a){return function(b,c){for(var d,g=c?b:b.parentNode;g;){d=g.nodeType;if(l.arrayContains(a,d))return g;g=g.parentNode}return null}}function x(a,b){if($(a,b))throw new r("INVALID_NODE_TYPE_ERR");}function o(a){if(!a.startContainer)throw new B("INVALID_STATE_ERR");}function z(a,b){if(!l.arrayContains(b,a.nodeType))throw new r("INVALID_NODE_TYPE_ERR");
}function w(a,b){if(0>b||b>(l.isCharacterDataNode(a)?a.length:a.childNodes.length))throw new B("INDEX_SIZE_ERR");}function y(a,b){if(O(a,!0)!==O(b,!0))throw new B("WRONG_DOCUMENT_ERR");}function A(a){if(aa(a,!0))throw new B("NO_MODIFICATION_ALLOWED_ERR");}function t(a,b){if(!a)throw new B(b);}function v(a){o(a);if(!l.arrayContains(G,a.startContainer.nodeType)&&!O(a.startContainer,!0)||!l.arrayContains(G,a.endContainer.nodeType)&&!O(a.endContainer,!0)||!(a.startOffset<=(l.isCharacterDataNode(a.startContainer)?
a.startContainer.length:a.startContainer.childNodes.length))||!(a.endOffset<=(l.isCharacterDataNode(a.endContainer)?a.endContainer.length:a.endContainer.childNodes.length)))throw Error("Range error: Range is no longer valid after DOM mutation ("+a.inspect()+")");}function D(){}function K(a){a.START_TO_START=Q;a.START_TO_END=U;a.END_TO_END=ba;a.END_TO_START=V;a.NODE_BEFORE=W;a.NODE_AFTER=X;a.NODE_BEFORE_AND_AFTER=Y;a.NODE_INSIDE=R}function F(a){K(a);K(a.prototype)}function E(a,b){return function(){v(this);
var c=this.startContainer,d=this.startOffset,e=this.commonAncestorContainer,j=new p(this,!0);c!==e&&(c=l.getClosestAncestorIn(c,e,!0),d=f(c),c=d.node,d=d.offset);g(j,A);j.reset();e=a(j);j.detach();b(this,c,d,c,d);return e}}function I(a,d,g){function h(a,b){return function(c){o(this);z(c,L);z(M(c),G);c=(a?e:f)(c);(b?i:n)(this,c.node,c.offset)}}function i(a,b,c){var g=a.endContainer,e=a.endOffset;if(b!==a.startContainer||c!==a.startOffset){if(M(b)!=M(g)||1==l.comparePoints(b,c,g,e))g=b,e=c;d(a,b,c,
g,e)}}function n(a,b,c){var g=a.startContainer,e=a.startOffset;if(b!==a.endContainer||c!==a.endOffset){if(M(b)!=M(g)||-1==l.comparePoints(b,c,g,e))g=b,e=c;d(a,g,e,b,c)}}a.prototype=new D;b.util.extend(a.prototype,{setStart:function(a,b){o(this);x(a,!0);w(a,b);i(this,a,b)},setEnd:function(a,b){o(this);x(a,!0);w(a,b);n(this,a,b)},setStartBefore:h(!0,!0),setStartAfter:h(!1,!0),setEndBefore:h(!0,!1),setEndAfter:h(!1,!1),collapse:function(a){v(this);a?d(this,this.startContainer,this.startOffset,this.startContainer,
this.startOffset):d(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(a){o(this);x(a,!0);d(this,a,0,a,l.getNodeLength(a))},selectNode:function(a){o(this);x(a,!1);z(a,L);var b=e(a),a=f(a);d(this,b.node,b.offset,a.node,a.offset)},extractContents:E(j,d),deleteContents:E(k,d),canSurroundContents:function(){v(this);A(this.startContainer);A(this.endContainer);var a=new p(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);a.detach();return!b},
detach:function(){g(this)},splitBoundaries:function(){v(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,g=this.endOffset,e=a===c;l.isCharacterDataNode(c)&&0<g&&g<c.length&&l.splitDataNode(c,g);l.isCharacterDataNode(a)&&0<b&&b<a.length&&(a=l.splitDataNode(a,b),e?(g-=b,c=a):c==a.parentNode&&g>=l.getNodeIndex(a)&&g++,b=0);d(this,a,b,c,g)},normalizeBoundaries:function(){v(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,g=this.endOffset,e=function(a){var b=
a.nextSibling;b&&b.nodeType==a.nodeType&&(c=a,g=a.length,a.appendData(b.data),b.parentNode.removeChild(b))},j=function(d){var e=d.previousSibling;if(e&&e.nodeType==d.nodeType){a=d;var j=d.length;b=e.length;d.insertData(0,e.data);e.parentNode.removeChild(e);a==c?(g+=b,c=a):c==d.parentNode&&(e=l.getNodeIndex(d),g==e?(c=d,g=j):g>e&&g--)}},k=!0;l.isCharacterDataNode(c)?c.length==g&&e(c):(0<g&&(k=c.childNodes[g-1])&&l.isCharacterDataNode(k)&&e(k),k=!this.collapsed);k?l.isCharacterDataNode(a)?0==b&&j(a):
b<a.childNodes.length&&(e=a.childNodes[b])&&l.isCharacterDataNode(e)&&j(e):(a=c,b=g);d(this,a,b,c,g)},collapseToPoint:function(a,b){o(this);x(a,!0);w(a,b);(a!==this.startContainer||b!==this.startOffset||a!==this.endContainer||b!==this.endOffset)&&d(this,a,b,a,b)}});F(a)}function N(a){a.collapsed=a.startContainer===a.endContainer&&a.startOffset===a.endOffset;a.commonAncestorContainer=a.collapsed?a.startContainer:l.getCommonAncestor(a.startContainer,a.endContainer)}function J(a,b,c,g,e){var j=a.startContainer!==
b||a.startOffset!==c,k=a.endContainer!==g||a.endOffset!==e;a.startContainer=b;a.startOffset=c;a.endContainer=g;a.endOffset=e;N(a);d(a,"boundarychange",{startMoved:j,endMoved:k})}function C(a){this.startContainer=a;this.startOffset=0;this.endContainer=a;this.endOffset=0;this._listeners={boundarychange:[],detach:[]};N(this)}b.requireModules(["DomUtil"]);var l=b.dom,u=l.DomPosition,B=b.DOMException;p.prototype={_current:null,_next:null,_first:null,_last:null,isSingleCharacterDataNode:!1,reset:function(){this._current=
null;this._next=this._first},hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next;a&&(this._next=a!==this._last?a.nextSibling:null,l.isCharacterDataNode(a)&&this.clonePartiallySelectedTextNodes&&(a===this.ec&&(a=a.cloneNode(!0)).deleteData(this.eo,a.length-this.eo),this._current===this.sc&&(a=a.cloneNode(!0)).deleteData(0,this.so)));return a},remove:function(){var a=this._current,b,c;l.isCharacterDataNode(a)&&(a===this.sc||a===this.ec)?(b=a===this.sc?this.so:0,c=a===
this.ec?this.eo:a.length,b!=c&&a.deleteData(b,c-b)):a.parentNode&&a.parentNode.removeChild(a)},isPartiallySelectedSubtree:function(){return c(this._current,this.range)},getSubtreeIterator:function(){var b;if(this.isSingleCharacterDataNode)b=this.range.cloneRange(),b.collapse();else{b=new C(a(this.range));var c=this._current,d=c,g=0,e=c,j=l.getNodeLength(c);l.isAncestorOf(c,this.sc,!0)&&(d=this.sc,g=this.so);l.isAncestorOf(c,this.ec,!0)&&(e=this.ec,j=this.eo);J(b,d,g,e,j)}return new p(b,this.clonePartiallySelectedTextNodes)},
detach:function(a){a&&this.range.detach();this.range=this._current=this._next=this._first=this._last=this.sc=this.so=this.ec=this.eo=null}};r.prototype={BAD_BOUNDARYPOINTS_ERR:1,INVALID_NODE_TYPE_ERR:2};r.prototype.toString=function(){return this.message};m.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){this._current=this._next;this._next=this.nodes[++this._position];return this._current},detach:function(){this._current=this._next=this.nodes=null}};var L=[1,3,4,5,
7,8,10],G=[2,9,11],P=[1,3,4,5,7,8,10,11],H=[1,3,4,5,7,8],M=l.getRootContainer,O=s([9,11]),aa=s([5,6,10,12]),$=s([6,10,12]),Z=document.createElement("style"),S=!1;try{Z.innerHTML="<b>x</b>",S=3==Z.firstChild.nodeType}catch(ca){}b.features.htmlParsingConforms=S;var T="startContainer,startOffset,endContainer,endOffset,collapsed,commonAncestorContainer".split(","),Q=0,U=1,ba=2,V=3,W=0,X=1,Y=2,R=3;D.prototype={attachListener:function(a,b){this._listeners[a].push(b)},compareBoundaryPoints:function(a,b){v(this);
y(this.startContainer,b.startContainer);var c=a==V||a==Q?"start":"end",d=a==U||a==Q?"start":"end";return l.comparePoints(this[c+"Container"],this[c+"Offset"],b[d+"Container"],b[d+"Offset"])},insertNode:function(a){v(this);z(a,P);A(this.startContainer);if(l.isAncestorOf(a,this.startContainer,!0))throw new B("HIERARCHY_REQUEST_ERR");this.setStartBefore(h(a,this.startContainer,this.startOffset))},cloneContents:function(){v(this);var b,c;if(this.collapsed)return a(this).createDocumentFragment();if(this.startContainer===
this.endContainer&&l.isCharacterDataNode(this.startContainer))return b=this.startContainer.cloneNode(!0),b.data=b.data.slice(this.startOffset,this.endOffset),c=a(this).createDocumentFragment(),c.appendChild(b),c;c=new p(this,!0);b=i(c);c.detach();return b},canSurroundContents:function(){v(this);A(this.startContainer);A(this.endContainer);var a=new p(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);a.detach();return!b},surroundContents:function(a){z(a,H);if(!this.canSurroundContents())throw new r("BAD_BOUNDARYPOINTS_ERR");
var b=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);h(a,this.startContainer,this.startOffset);a.appendChild(b);this.selectNode(a)},cloneRange:function(){v(this);for(var b=new C(a(this)),c=T.length,d;c--;)d=T[c],b[d]=this[d];return b},toString:function(){v(this);var a=this.startContainer;if(a===this.endContainer&&l.isCharacterDataNode(a))return 3==a.nodeType||4==a.nodeType?a.data.slice(this.startOffset,this.endOffset):"";var b=[],a=new p(this,!0);g(a,function(a){(3==
a.nodeType||4==a.nodeType)&&b.push(a.data)});a.detach();return b.join("")},compareNode:function(a){v(this);var b=a.parentNode,c=l.getNodeIndex(a);if(!b)throw new B("NOT_FOUND_ERR");a=this.comparePoint(b,c);b=this.comparePoint(b,c+1);return 0>a?0<b?Y:W:0<b?X:R},comparePoint:function(a,b){v(this);t(a,"HIERARCHY_REQUEST_ERR");y(a,this.startContainer);return 0>l.comparePoints(a,b,this.startContainer,this.startOffset)?-1:0<l.comparePoints(a,b,this.endContainer,this.endOffset)?1:0},createContextualFragment:S?
function(a){var b=this.startContainer,c=l.getDocument(b);if(!b)throw new B("INVALID_STATE_ERR");var d=null;1==b.nodeType?d=b:l.isCharacterDataNode(b)&&(d=l.parentElement(b));d=null===d||"HTML"==d.nodeName&&l.isHtmlNamespace(l.getDocument(d).documentElement)&&l.isHtmlNamespace(d)?c.createElement("body"):d.cloneNode(!1);d.innerHTML=a;return l.fragmentFromNodeChildren(d)}:function(b){o(this);var c=a(this).createElement("body");c.innerHTML=b;return l.fragmentFromNodeChildren(c)},toHtml:function(){v(this);
var b=a(this).createElement("div");b.appendChild(this.cloneContents());return b.innerHTML},intersectsNode:function(b,c){v(this);t(b,"NOT_FOUND_ERR");if(l.getDocument(b)!==a(this))return!1;var d=b.parentNode,g=l.getNodeIndex(b);t(d,"NOT_FOUND_ERR");var e=l.comparePoints(d,g,this.endContainer,this.endOffset),d=l.comparePoints(d,g+1,this.startContainer,this.startOffset);return c?0>=e&&0<=d:0>e&&0<d},isPointInRange:function(a,b){v(this);t(a,"HIERARCHY_REQUEST_ERR");y(a,this.startContainer);return 0<=
l.comparePoints(a,b,this.startContainer,this.startOffset)&&0>=l.comparePoints(a,b,this.endContainer,this.endOffset)},intersectsRange:function(b,c){v(this);if(a(b)!=a(this))throw new B("WRONG_DOCUMENT_ERR");var d=l.comparePoints(this.startContainer,this.startOffset,b.endContainer,b.endOffset),g=l.comparePoints(this.endContainer,this.endOffset,b.startContainer,b.startOffset);return c?0>=d&&0<=g:0>d&&0<g},intersection:function(a){if(this.intersectsRange(a)){var b=l.comparePoints(this.startContainer,
this.startOffset,a.startContainer,a.startOffset),c=l.comparePoints(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();-1==b&&d.setStart(a.startContainer,a.startOffset);1==c&&d.setEnd(a.endContainer,a.endOffset);return d}return null},union:function(a){if(this.intersectsRange(a,!0)){var b=this.cloneRange();-1==l.comparePoints(a.startContainer,a.startOffset,this.startContainer,this.startOffset)&&b.setStart(a.startContainer,a.startOffset);1==l.comparePoints(a.endContainer,
a.endOffset,this.endContainer,this.endOffset)&&b.setEnd(a.endContainer,a.endOffset);return b}throw new r("Ranges do not intersect");},containsNode:function(a,b){return b?this.intersectsNode(a,!1):this.compareNode(a)==R},containsNodeContents:function(a){return 0<=this.comparePoint(a,0)&&0>=this.comparePoint(a,l.getNodeLength(a))},containsRange:function(a){return this.intersection(a).equals(a)},containsNodeText:function(a){var b=this.cloneRange();b.selectNode(a);var c=b.getNodes([3]);return 0<c.length?
(b.setStart(c[0],0),a=c.pop(),b.setEnd(a,a.length),a=this.containsRange(b),b.detach(),a):this.containsNodeContents(a)},createNodeIterator:function(a,b){v(this);return new m(this,a,b)},getNodes:function(a,b){v(this);return q(this,a,b)},getDocument:function(){return a(this)},collapseBefore:function(a){o(this);this.setEndBefore(a);this.collapse(!1)},collapseAfter:function(a){o(this);this.setStartAfter(a);this.collapse(!0)},getName:function(){return"DomRange"},equals:function(a){return C.rangesEqual(this,
a)},inspect:function(){return n(this)}};I(C,J,function(a){o(a);a.startContainer=a.startOffset=a.endContainer=a.endOffset=null;a.collapsed=a.commonAncestorContainer=null;d(a,"detach",null);a._listeners=null});b.rangePrototype=D.prototype;C.rangeProperties=T;C.RangeIterator=p;C.copyComparisonConstants=F;C.createPrototypeRange=I;C.inspect=n;C.getRangeDocument=a;C.rangesEqual=function(a,b){return a.startContainer===b.startContainer&&a.startOffset===b.startOffset&&a.endContainer===b.endContainer&&a.endOffset===
b.endOffset};b.DomRange=C;b.RangeException=r});
rangy.createModule("WrappedRange",function(b){function c(a,b,c,d){var h=a.duplicate();h.collapse(c);var i=h.parentElement();e.isAncestorOf(b,i,!0)||(i=b);if(!i.canHaveHTML)return new f(i.parentNode,e.getNodeIndex(i));var b=e.getDocument(i).createElement("span"),r,m=c?"StartToStart":"StartToEnd";do i.insertBefore(b,b.previousSibling),h.moveToElementText(b);while(0<(r=h.compareEndPoints(m,a))&&b.previousSibling);m=b.nextSibling;if(-1==r&&m&&e.isCharacterDataNode(m)){h.setEndPoint(c?"EndToStart":"EndToEnd",
a);if(/[\r\n]/.test(m.data)){i=h.duplicate();c=i.text.replace(/\r\n/g,"\r").length;for(c=i.moveStart("character",c);-1==i.compareEndPoints("StartToEnd",i);)c++,i.moveStart("character",1)}else c=h.text.length;i=new f(m,c)}else m=(d||!c)&&b.previousSibling,i=(c=(d||c)&&b.nextSibling)&&e.isCharacterDataNode(c)?new f(c,0):m&&e.isCharacterDataNode(m)?new f(m,m.length):new f(i,e.getNodeIndex(b));b.parentNode.removeChild(b);return i}function a(a,b){var c,d,f=a.offset,h=e.getDocument(a.node),i=h.body.createTextRange(),
m=e.isCharacterDataNode(a.node);m?(c=a.node,d=c.parentNode):(c=a.node.childNodes,c=f<c.length?c[f]:null,d=a.node);h=h.createElement("span");h.innerHTML="&#feff;";c?d.insertBefore(h,c):d.appendChild(h);i.moveToElementText(h);i.collapse(!b);d.removeChild(h);if(m)i[b?"moveStart":"moveEnd"]("character",f);return i}b.requireModules(["DomUtil","DomRange"]);var d,e=b.dom,f=e.DomPosition,h=b.DomRange;if(b.features.implementsDomRange&&(!b.features.implementsTextRange||!b.config.preferTextRange))(function(){function a(b){for(var c=
j.length,d;c--;)d=j[c],b[d]=b.nativeRange[d]}var c,j=h.rangeProperties,f;d=function(b){if(!b)throw Error("Range must be specified");this.nativeRange=b;a(this)};h.createPrototypeRange(d,function(a,b,c,d,g){var e=a.endContainer!==d||a.endOffset!=g;if(a.startContainer!==b||a.startOffset!=c||e)a.setEnd(d,g),a.setStart(b,c)},function(a){a.nativeRange.detach();a.detached=!0;for(var b=j.length,c;b--;)c=j[b],a[c]=null});c=d.prototype;c.selectNode=function(b){this.nativeRange.selectNode(b);a(this)};c.deleteContents=
function(){this.nativeRange.deleteContents();a(this)};c.extractContents=function(){var b=this.nativeRange.extractContents();a(this);return b};c.cloneContents=function(){return this.nativeRange.cloneContents()};c.surroundContents=function(b){this.nativeRange.surroundContents(b);a(this)};c.collapse=function(b){this.nativeRange.collapse(b);a(this)};c.cloneRange=function(){return new d(this.nativeRange.cloneRange())};c.refresh=function(){a(this)};c.toString=function(){return this.nativeRange.toString()};
var i=document.createTextNode("test");e.getBody(document).appendChild(i);var p=document.createRange();p.setStart(i,0);p.setEnd(i,0);try{p.setStart(i,1),c.setStart=function(b,c){this.nativeRange.setStart(b,c);a(this)},c.setEnd=function(b,c){this.nativeRange.setEnd(b,c);a(this)},f=function(b){return function(c){this.nativeRange[b](c);a(this)}}}catch(r){c.setStart=function(b,c){try{this.nativeRange.setStart(b,c)}catch(d){this.nativeRange.setEnd(b,c),this.nativeRange.setStart(b,c)}a(this)},c.setEnd=function(b,
c){try{this.nativeRange.setEnd(b,c)}catch(d){this.nativeRange.setStart(b,c),this.nativeRange.setEnd(b,c)}a(this)},f=function(b,c){return function(d){try{this.nativeRange[b](d)}catch(e){this.nativeRange[c](d),this.nativeRange[b](d)}a(this)}}}c.setStartBefore=f("setStartBefore","setEndBefore");c.setStartAfter=f("setStartAfter","setEndAfter");c.setEndBefore=f("setEndBefore","setStartBefore");c.setEndAfter=f("setEndAfter","setStartAfter");p.selectNodeContents(i);c.selectNodeContents=p.startContainer==
i&&p.endContainer==i&&0==p.startOffset&&p.endOffset==i.length?function(b){this.nativeRange.selectNodeContents(b);a(this)}:function(a){this.setStart(a,0);this.setEnd(a,h.getEndOffset(a))};p.selectNodeContents(i);p.setEnd(i,3);f=document.createRange();f.selectNodeContents(i);f.setEnd(i,4);f.setStart(i,2);c.compareBoundaryPoints=-1==p.compareBoundaryPoints(p.START_TO_END,f)&1==p.compareBoundaryPoints(p.END_TO_START,f)?function(a,b){b=b.nativeRange||b;a==b.START_TO_END?a=b.END_TO_START:a==b.END_TO_START&&
(a=b.START_TO_END);return this.nativeRange.compareBoundaryPoints(a,b)}:function(a,b){return this.nativeRange.compareBoundaryPoints(a,b.nativeRange||b)};b.util.isHostMethod(p,"createContextualFragment")&&(c.createContextualFragment=function(a){return this.nativeRange.createContextualFragment(a)});e.getBody(document).removeChild(i);p.detach();f.detach()})(),b.createNativeRange=function(a){return(a||document).createRange()};else if(b.features.implementsTextRange){d=function(a){this.textRange=a;this.refresh()};
d.prototype=new h(document);d.prototype.refresh=function(){var a,b,d=this.textRange;a=d.parentElement();var f=d.duplicate();f.collapse(!0);b=f.parentElement();f=d.duplicate();f.collapse(!1);d=f.parentElement();b=b==d?b:e.getCommonAncestor(b,d);b=b==a?b:e.getCommonAncestor(a,b);0==this.textRange.compareEndPoints("StartToEnd",this.textRange)?b=a=c(this.textRange,b,!0,!0):(a=c(this.textRange,b,!0,!1),b=c(this.textRange,b,!1,!1));this.setStart(a.node,a.offset);this.setEnd(b.node,b.offset)};h.copyComparisonConstants(d);
var i=function(){return this}();"undefined"==typeof i.Range&&(i.Range=d);b.createNativeRange=function(a){return(a||document).body.createTextRange()}}b.features.implementsTextRange&&(d.rangeToTextRange=function(b){if(b.collapsed)return a(new f(b.startContainer,b.startOffset),!0);var c=a(new f(b.startContainer,b.startOffset),!0),d=a(new f(b.endContainer,b.endOffset),!1),b=e.getDocument(b.startContainer).body.createTextRange();b.setEndPoint("StartToStart",c);b.setEndPoint("EndToEnd",d);return b});d.prototype.getName=
function(){return"WrappedRange"};b.WrappedRange=d;b.createRange=function(a){return new d(b.createNativeRange(a||document))};b.createRangyRange=function(a){return new h(a||document)};b.createIframeRange=function(a){return b.createRange(e.getIframeDocument(a))};b.createIframeRangyRange=function(a){return b.createRangyRange(e.getIframeDocument(a))};b.addCreateMissingNativeApiListener(function(a){a=a.document;if(typeof a.createRange=="undefined")a.createRange=function(){return b.createRange(this)};a=
a=null})});
rangy.createModule("WrappedSelection",function(b,c){function a(a){return(a||window).getSelection()}function d(a){return(a||window).document.selection}function e(a,b,c){var d=c?"end":"start",c=c?"start":"end";a.anchorNode=b[d+"Container"];a.anchorOffset=b[d+"Offset"];a.focusNode=b[c+"Container"];a.focusOffset=b[c+"Offset"]}function f(a){a.anchorNode=a.focusNode=null;a.anchorOffset=a.focusOffset=0;a.rangeCount=0;a.isCollapsed=!0;a._ranges.length=0}function h(a){var c;a instanceof x?(c=a._selectionNativeRange,c||
(c=b.createNativeRange(m.getDocument(a.startContainer)),c.setEnd(a.endContainer,a.endOffset),c.setStart(a.startContainer,a.startOffset),a._selectionNativeRange=c,a.attachListener("detach",function(){this._selectionNativeRange=null}))):a instanceof o?c=a.nativeRange:b.features.implementsDomRange&&a instanceof m.getWindow(a.startContainer).Range&&(c=a);return c}function i(a){var b=a.getNodes(),c;a:if(!b.length||1!=b[0].nodeType)c=!1;else{c=1;for(var d=b.length;c<d;++c)if(!m.isAncestorOf(b[0],b[c])){c=
!1;break a}c=!0}if(!c)throw Error("getSingleElementFromRange: range "+a.inspect()+" did not consist of a single element");return b[0]}function g(a,b){var c=new o(b);a._ranges=[c];e(a,c,!1);a.rangeCount=1;a.isCollapsed=c.collapsed}function k(a){a._ranges.length=0;if("None"==a.docSelection.type)f(a);else{var c=a.docSelection.createRange();if(c&&"undefined"!=typeof c.text)g(a,c);else{a.rangeCount=c.length;for(var d,j=m.getDocument(c.item(0)),k=0;k<a.rangeCount;++k)d=b.createRange(j),d.selectNode(c.item(k)),
a._ranges.push(d);a.isCollapsed=1==a.rangeCount&&a._ranges[0].collapsed;e(a,a._ranges[a.rangeCount-1],!1)}}}function j(a,b){for(var c=a.docSelection.createRange(),d=i(b),e=m.getDocument(c.item(0)),e=m.getBody(e).createControlRange(),g=0,j=c.length;g<j;++g)e.add(c.item(g));try{e.add(d)}catch(f){throw Error("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");}e.select();k(a)}function q(a,b,c){this.nativeSelection=a;this.docSelection=b;this._ranges=
[];this.win=c;this.refresh()}function n(a,b){for(var c=m.getDocument(b[0].startContainer),c=m.getBody(c).createControlRange(),d=0,e;d<rangeCount;++d){e=i(b[d]);try{c.add(e)}catch(g){throw Error("setRanges(): Element within the one of the specified Ranges could not be added to control selection (does it have layout?)");}}c.select();k(a)}function p(a,b){if(a.anchorNode&&m.getDocument(a.anchorNode)!==m.getDocument(b))throw new z("WRONG_DOCUMENT_ERR");}function r(a){var b=[],c=new w(a.anchorNode,a.anchorOffset),
d=new w(a.focusNode,a.focusOffset),e="function"==typeof a.getName?a.getName():"Selection";if("undefined"!=typeof a.rangeCount)for(var g=0,j=a.rangeCount;g<j;++g)b[g]=x.inspect(a.getRangeAt(g));return"["+e+"(Ranges: "+b.join(", ")+")(anchor: "+c.inspect()+", focus: "+d.inspect()+"]"}b.requireModules(["DomUtil","DomRange","WrappedRange"]);b.config.checkSelectionRanges=!0;var m=b.dom,s=b.util,x=b.DomRange,o=b.WrappedRange,z=b.DOMException,w=m.DomPosition,y,A,t=b.util.isHostMethod(window,"getSelection"),
v=b.util.isHostObject(document,"selection"),D=v&&(!t||b.config.preferTextRange);D?(y=d,b.isSelectionValid=function(a){var a=(a||window).document,b=a.selection;return"None"!=b.type||m.getDocument(b.createRange().parentElement())==a}):t?(y=a,b.isSelectionValid=function(){return!0}):c.fail("Neither document.selection or window.getSelection() detected.");b.getNativeSelection=y;var t=y(),K=b.createNativeRange(document),F=m.getBody(document),E=s.areHostObjects(t,s.areHostProperties(t,["anchorOffset","focusOffset"]));
b.features.selectionHasAnchorAndFocus=E;var I=s.isHostMethod(t,"extend");b.features.selectionHasExtend=I;var N="number"==typeof t.rangeCount;b.features.selectionHasRangeCount=N;var J=!1,C=!0;s.areHostMethods(t,["addRange","getRangeAt","removeAllRanges"])&&"number"==typeof t.rangeCount&&b.features.implementsDomRange&&function(){var a=document.createElement("iframe");F.appendChild(a);var b=m.getIframeDocument(a);b.open();b.write("<html><head></head><body>12</body></html>");b.close();var c=m.getIframeWindow(a).getSelection(),
d=b.documentElement.lastChild.firstChild,b=b.createRange();b.setStart(d,1);b.collapse(true);c.addRange(b);C=c.rangeCount==1;c.removeAllRanges();var e=b.cloneRange();b.setStart(d,0);e.setEnd(d,2);c.addRange(b);c.addRange(e);J=c.rangeCount==2;b.detach();e.detach();F.removeChild(a)}();b.features.selectionSupportsMultipleRanges=J;b.features.collapsedNonEditableSelectionsSupported=C;var l=!1,u;F&&s.isHostMethod(F,"createControlRange")&&(u=F.createControlRange(),s.areHostProperties(u,["item","add"])&&(l=
!0));b.features.implementsControlRange=l;A=E?function(a){return a.anchorNode===a.focusNode&&a.anchorOffset===a.focusOffset}:function(a){return a.rangeCount?a.getRangeAt(a.rangeCount-1).collapsed:false};var B;s.isHostMethod(t,"getRangeAt")?B=function(a,b){try{return a.getRangeAt(b)}catch(c){return null}}:E&&(B=function(a){var c=m.getDocument(a.anchorNode),c=b.createRange(c);c.setStart(a.anchorNode,a.anchorOffset);c.setEnd(a.focusNode,a.focusOffset);if(c.collapsed!==this.isCollapsed){c.setStart(a.focusNode,
a.focusOffset);c.setEnd(a.anchorNode,a.anchorOffset)}return c});b.getSelection=function(a){var a=a||window,b=a._rangySelection,c=y(a),e=v?d(a):null;if(b){b.nativeSelection=c;b.docSelection=e;b.refresh(a)}else{b=new q(c,e,a);a._rangySelection=b}return b};b.getIframeSelection=function(a){return b.getSelection(m.getIframeWindow(a))};u=q.prototype;if(!D&&E&&s.areHostMethods(t,["removeAllRanges","addRange"])){u.removeAllRanges=function(){this.nativeSelection.removeAllRanges();f(this)};var L=function(a,
c){var d=x.getRangeDocument(c),d=b.createRange(d);d.collapseToPoint(c.endContainer,c.endOffset);a.nativeSelection.addRange(h(d));a.nativeSelection.extend(c.startContainer,c.startOffset);a.refresh()};u.addRange=N?function(a,c){if(l&&v&&this.docSelection.type=="Control")j(this,a);else if(c&&I)L(this,a);else{var d;if(J)d=this.rangeCount;else{this.removeAllRanges();d=0}this.nativeSelection.addRange(h(a));this.rangeCount=this.nativeSelection.rangeCount;if(this.rangeCount==d+1){if(b.config.checkSelectionRanges)(d=
B(this.nativeSelection,this.rangeCount-1))&&!x.rangesEqual(d,a)&&(a=new o(d));this._ranges[this.rangeCount-1]=a;e(this,a,H(this.nativeSelection));this.isCollapsed=A(this)}else this.refresh()}}:function(a,b){if(b&&I)L(this,a);else{this.nativeSelection.addRange(h(a));this.refresh()}};u.setRanges=function(a){if(l&&a.length>1)n(this,a);else{this.removeAllRanges();for(var b=0,c=a.length;b<c;++b)this.addRange(a[b])}}}else if(s.isHostMethod(t,"empty")&&s.isHostMethod(K,"select")&&l&&D)u.removeAllRanges=
function(){try{this.docSelection.empty();if(this.docSelection.type!="None"){var a;if(this.anchorNode)a=m.getDocument(this.anchorNode);else if(this.docSelection.type=="Control"){var b=this.docSelection.createRange();b.length&&(a=m.getDocument(b.item(0)).body.createTextRange())}if(a){a.body.createTextRange().select();this.docSelection.empty()}}}catch(c){}f(this)},u.addRange=function(a){if(this.docSelection.type=="Control")j(this,a);else{o.rangeToTextRange(a).select();this._ranges[0]=a;this.rangeCount=
1;this.isCollapsed=this._ranges[0].collapsed;e(this,a,false)}},u.setRanges=function(a){this.removeAllRanges();var b=a.length;b>1?n(this,a):b&&this.addRange(a[0])};else return c.fail("No means of selecting a Range or TextRange was found"),!1;u.getRangeAt=function(a){if(a<0||a>=this.rangeCount)throw new z("INDEX_SIZE_ERR");return this._ranges[a]};var G;if(D)G=function(a){var c;if(b.isSelectionValid(a.win))c=a.docSelection.createRange();else{c=m.getBody(a.win.document).createTextRange();c.collapse(true)}a.docSelection.type==
"Control"?k(a):c&&typeof c.text!="undefined"?g(a,c):f(a)};else if(s.isHostMethod(t,"getRangeAt")&&"number"==typeof t.rangeCount)G=function(a){if(l&&v&&a.docSelection.type=="Control")k(a);else{a._ranges.length=a.rangeCount=a.nativeSelection.rangeCount;if(a.rangeCount){for(var c=0,d=a.rangeCount;c<d;++c)a._ranges[c]=new b.WrappedRange(a.nativeSelection.getRangeAt(c));e(a,a._ranges[a.rangeCount-1],H(a.nativeSelection));a.isCollapsed=A(a)}else f(a)}};else if(E&&"boolean"==typeof t.isCollapsed&&"boolean"==
typeof K.collapsed&&b.features.implementsDomRange)G=function(a){var b;b=a.nativeSelection;if(b.anchorNode){b=B(b,0);a._ranges=[b];a.rangeCount=1;b=a.nativeSelection;a.anchorNode=b.anchorNode;a.anchorOffset=b.anchorOffset;a.focusNode=b.focusNode;a.focusOffset=b.focusOffset;a.isCollapsed=A(a)}else f(a)};else return c.fail("No means of obtaining a Range or TextRange from the user's selection was found"),!1;u.refresh=function(a){var b=a?this._ranges.slice(0):null;G(this);if(a){a=b.length;if(a!=this._ranges.length)return false;
for(;a--;)if(!x.rangesEqual(b[a],this._ranges[a]))return false;return true}};var P=function(a,b){var c=a.getAllRanges(),d=false;a.removeAllRanges();for(var e=0,g=c.length;e<g;++e)d||b!==c[e]?a.addRange(c[e]):d=true;a.rangeCount||f(a)};u.removeRange=l?function(a){if(this.docSelection.type=="Control"){for(var b=this.docSelection.createRange(),a=i(a),c=m.getDocument(b.item(0)),c=m.getBody(c).createControlRange(),d,e=false,g=0,j=b.length;g<j;++g){d=b.item(g);d!==a||e?c.add(b.item(g)):e=true}c.select();
k(this)}else P(this,a)}:function(a){P(this,a)};var H;!D&&E&&b.features.implementsDomRange?(H=function(a){var b=false;a.anchorNode&&(b=m.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset)==1);return b},u.isBackwards=function(){return H(this)}):H=u.isBackwards=function(){return false};u.toString=function(){for(var a=[],b=0,c=this.rangeCount;b<c;++b)a[b]=""+this._ranges[b];return a.join("")};u.collapse=function(a,c){p(this,a);var d=b.createRange(m.getDocument(a));d.collapseToPoint(a,
c);this.removeAllRanges();this.addRange(d);this.isCollapsed=true};u.collapseToStart=function(){if(this.rangeCount){var a=this._ranges[0];this.collapse(a.startContainer,a.startOffset)}else throw new z("INVALID_STATE_ERR");};u.collapseToEnd=function(){if(this.rangeCount){var a=this._ranges[this.rangeCount-1];this.collapse(a.endContainer,a.endOffset)}else throw new z("INVALID_STATE_ERR");};u.selectAllChildren=function(a){p(this,a);var c=b.createRange(m.getDocument(a));c.selectNodeContents(a);this.removeAllRanges();
this.addRange(c)};u.deleteFromDocument=function(){if(l&&v&&this.docSelection.type=="Control"){for(var a=this.docSelection.createRange(),b;a.length;){b=a.item(0);a.remove(b);b.parentNode.removeChild(b)}this.refresh()}else if(this.rangeCount){a=this.getAllRanges();this.removeAllRanges();b=0;for(var c=a.length;b<c;++b)a[b].deleteContents();this.addRange(a[c-1])}};u.getAllRanges=function(){return this._ranges.slice(0)};u.setSingleRange=function(a){this.setRanges([a])};u.containsNode=function(a,b){for(var c=
0,d=this._ranges.length;c<d;++c)if(this._ranges[c].containsNode(a,b))return true;return false};u.toHtml=function(){var a="";if(this.rangeCount){for(var a=x.getRangeDocument(this._ranges[0]).createElement("div"),b=0,c=this._ranges.length;b<c;++b)a.appendChild(this._ranges[b].cloneContents());a=a.innerHTML}return a};u.getName=function(){return"WrappedSelection"};u.inspect=function(){return r(this)};u.detach=function(){this.win=this.anchorNode=this.focusNode=this.win._rangySelection=null};q.inspect=
r;b.Selection=q;b.selectionPrototype=u;b.addCreateMissingNativeApiListener(function(a){if(typeof a.getSelection=="undefined")a.getSelection=function(){return b.getSelection(this)};a=null})});var Base=function(){};
Base.extend=function(b,c){var a=Base.prototype.extend;Base._prototyping=!0;var d=new this;a.call(d,b);d.base=function(){};delete Base._prototyping;var e=d.constructor,f=d.constructor=function(){if(!Base._prototyping)if(this._constructing||this.constructor==f)this._constructing=!0,e.apply(this,arguments),delete this._constructing;else if(null!=arguments[0])return(arguments[0].extend||a).call(arguments[0],d)};f.ancestor=this;f.extend=this.extend;f.forEach=this.forEach;f.implement=this.implement;f.prototype=
d;f.toString=this.toString;f.valueOf=function(a){return"object"==a?f:e.valueOf()};a.call(f,c);"function"==typeof f.init&&f.init();return f};
Base.prototype={extend:function(b,c){if(1<arguments.length){var a=this[b];if(a&&"function"==typeof c&&(!a.valueOf||a.valueOf()!=c.valueOf())&&/\bbase\b/.test(c)){var d=c.valueOf(),c=function(){var b=this.base||Base.prototype.base;this.base=a;var c=d.apply(this,arguments);this.base=b;return c};c.valueOf=function(a){return"object"==a?c:d};c.toString=Base.toString}this[b]=c}else if(b){var e=Base.prototype.extend;!Base._prototyping&&"function"!=typeof this&&(e=this.extend||e);for(var f={toSource:null},
h=["constructor","toString","valueOf"],i=Base._prototyping?0:1;g=h[i++];)b[g]!=f[g]&&e.call(this,g,b[g]);for(var g in b)f[g]||e.call(this,g,b[g])}return this}};
Base=Base.extend({constructor:function(b){this.extend(b)}},{ancestor:Object,version:"1.1",forEach:function(b,c,a){for(var d in b)void 0===this.prototype[d]&&c.call(a,b[d],d,b)},implement:function(){for(var b=0;b<arguments.length;b++)if("function"==typeof arguments[b])arguments[b](this.prototype);else this.prototype.extend(arguments[b]);return this},toString:function(){return""+this.valueOf()}});
wysihtml5.browser=function(){var b=navigator.userAgent,c=document.createElement("div"),a=-1!==b.indexOf("MSIE")&&-1===b.indexOf("Opera"),d=-1!==b.indexOf("Gecko")&&-1===b.indexOf("KHTML"),e=-1!==b.indexOf("AppleWebKit/"),f=-1!==b.indexOf("Chrome/"),h=-1!==b.indexOf("Opera/");return{USER_AGENT:b,supported:function(){var a=this.USER_AGENT.toLowerCase(),b="contentEditable"in c,d=document.execCommand&&document.queryCommandSupported&&document.queryCommandState,e=document.querySelector&&document.querySelectorAll,
a=this.isIos()&&5>(/ipad|iphone|ipod/.test(a)&&a.match(/ os (\d+).+? like mac os x/)||[,0])[1]||-1!==a.indexOf("opera mobi")||-1!==a.indexOf("hpwos/");return b&&d&&e&&!a},isTouchDevice:function(){return this.supportsEvent("touchmove")},isIos:function(){var a=this.USER_AGENT.toLowerCase();return-1!==a.indexOf("webkit")&&-1!==a.indexOf("mobile")},supportsSandboxedIframes:function(){return a},throwsMixedContentWarningWhenIframeSrcIsEmpty:function(){return!("querySelector"in document)},displaysCaretInEmptyContentEditableCorrectly:function(){return!d},
hasCurrentStyleProperty:function(){return"currentStyle"in c},insertsLineBreaksOnReturn:function(){return d},supportsPlaceholderAttributeOn:function(a){return"placeholder"in a},supportsEvent:function(a){var b;if(!(b="on"+a in c))c.setAttribute("on"+a,"return;"),b="function"===typeof c["on"+a];return b},supportsEventsInIframeCorrectly:function(){return!h},firesOnDropOnlyWhenOnDragOverIsCancelled:function(){return e||d},supportsDataTransfer:function(){try{return e&&(window.Clipboard||window.DataTransfer).prototype.getData}catch(a){return!1}},
supportsHTML5Tags:function(a){a=a.createElement("div");a.innerHTML="<article>foo</article>";return"<article>foo</article>"===a.innerHTML.toLowerCase()},supportsCommand:function(){var b={formatBlock:a,insertUnorderedList:a||h,insertOrderedList:a||h},c={insertHTML:d};return function(a,d){if(!b[d]){try{return a.queryCommandSupported(d)}catch(e){}try{return a.queryCommandEnabled(d)}catch(f){return!!c[d]}}return!1}}(),doesAutoLinkingInContentEditable:function(){return a},canDisableAutoLinking:function(){return this.supportsCommand(document,
"AutoUrlDetect")},clearsContentEditableCorrectly:function(){return d||h||e},supportsGetAttributeCorrectly:function(){return"1"!=document.createElement("td").getAttribute("rowspan")},canSelectImagesInContentEditable:function(){return d||a||h},clearsListsInContentEditableCorrectly:function(){return d||a||e},autoScrollsToCaret:function(){return!e},autoClosesUnclosedTags:function(){var a=c.cloneNode(!1),b;a.innerHTML="<p><div></div>";a=a.innerHTML.toLowerCase();b="<p></p><div></div>"===a||"<p><div></div></p>"===
a;this.autoClosesUnclosedTags=function(){return b};return b},supportsNativeGetElementsByClassName:function(){return-1!==(""+document.getElementsByClassName).indexOf("[native code]")},supportsSelectionModify:function(){return"getSelection"in window&&"modify"in window.getSelection()},supportsClassList:function(){return"classList"in c},needsSpaceAfterLineBreak:function(){return h},supportsSpeechApiOn:function(a){return 11<=(b.match(/Chrome\/(\d+)/)||[,0])[1]&&("onwebkitspeechchange"in a||"speech"in a)},
crashesWhenDefineProperty:function(b){return a&&("XMLHttpRequest"===b||"XDomainRequest"===b)},doesAsyncFocus:function(){return a},hasProblemsSettingCaretAfterImg:function(){return a},hasUndoInContextMenu:function(){return d||f||h}}}();
wysihtml5.lang.array=function(b){return{contains:function(c){if(b.indexOf)return-1!==b.indexOf(c);for(var a=0,d=b.length;a<d;a++)if(b[a]===c)return!0;return!1},without:function(c){for(var c=wysihtml5.lang.array(c),a=[],d=0,e=b.length;d<e;d++)c.contains(b[d])||a.push(b[d]);return a},get:function(){for(var c=0,a=b.length,d=[];c<a;c++)d.push(b[c]);return d}}};
wysihtml5.lang.Dispatcher=Base.extend({observe:function(b,c){this.events=this.events||{};this.events[b]=this.events[b]||[];this.events[b].push(c);return this},on:function(){return this.observe.apply(this,wysihtml5.lang.array(arguments).get())},fire:function(b,c){this.events=this.events||{};for(var a=this.events[b]||[],d=0;d<a.length;d++)a[d].call(this,c);return this},stopObserving:function(b,c){this.events=this.events||{};var a=0,d,e;if(b){d=this.events[b]||[];for(e=[];a<d.length;a++)d[a]!==c&&c&&
e.push(d[a]);this.events[b]=e}else this.events={};return this}});wysihtml5.lang.object=function(b){return{merge:function(c){for(var a in c)b[a]=c[a];return this},get:function(){return b},clone:function(){var c={},a;for(a in b)c[a]=b[a];return c},isArray:function(){return"[object Array]"===Object.prototype.toString.call(b)}}};
(function(){var b=/^\s+/,c=/\s+$/;wysihtml5.lang.string=function(a){a=""+a;return{trim:function(){return a.replace(b,"").replace(c,"")},interpolate:function(b){for(var c in b)a=this.replace("#{"+c+"}").by(b[c]);return a},replace:function(b){return{by:function(c){return a.split(b).join(c)}}}}}})();
(function(b){function c(a){return a.replace(e,function(a,b){var c=(b.match(f)||[])[1]||"",d=i[c],b=b.replace(f,"");b.split(d).length>b.split(c).length&&(b+=c,c="");var e=d=b;b.length>h&&(e=e.substr(0,h)+"...");"www."===d.substr(0,4)&&(d="http://"+d);return'<a href="'+d+'">'+e+"</a>"+c})}function a(g){if(!d.contains(g.nodeName))if(g.nodeType===b.TEXT_NODE&&g.data.match(e)){var f=g.parentNode,j;j=f.ownerDocument;var h=j._wysihtml5_tempElement;h||(h=j._wysihtml5_tempElement=j.createElement("div"));j=
h;j.innerHTML="<span></span>"+c(g.data);for(j.removeChild(j.firstChild);j.firstChild;)f.insertBefore(j.firstChild,g);f.removeChild(g)}else{f=b.lang.array(g.childNodes).get();j=f.length;for(h=0;h<j;h++)a(f[h]);return g}}var d=b.lang.array("CODE,PRE,A,SCRIPT,HEAD,TITLE,STYLE".split(",")),e=/((https?:\/\/|www\.)[^\s<]{3,})/gi,f=/([^\w\/\-](,?))$/i,h=100,i={")":"(","]":"[","}":"{"};b.dom.autoLink=function(b){var c;a:{c=b;for(var e;c.parentNode;){c=c.parentNode;e=c.nodeName;if(d.contains(e)){c=!0;break a}if("body"===
e)break}c=!1}if(c)return b;b===b.ownerDocument.documentElement&&(b=b.ownerDocument.body);return a(b)};b.dom.autoLink.URL_REG_EXP=e})(wysihtml5);
(function(b){var c=b.browser.supportsClassList(),a=b.dom;a.addClass=function(b,e){if(c)return b.classList.add(e);a.hasClass(b,e)||(b.className+=" "+e)};a.removeClass=function(a,b){if(c)return a.classList.remove(b);a.className=a.className.replace(RegExp("(^|\\s+)"+b+"(\\s+|$)")," ")};a.hasClass=function(a,b){if(c)return a.classList.contains(b);var f=a.className;return 0<f.length&&(f==b||RegExp("(^|\\s)"+b+"(\\s|$)").test(f))}})(wysihtml5);
wysihtml5.dom.contains=function(){var b=document.documentElement;if(b.contains)return function(b,a){a.nodeType!==wysihtml5.ELEMENT_NODE&&(a=a.parentNode);return b!==a&&b.contains(a)};if(b.compareDocumentPosition)return function(b,a){return!!(b.compareDocumentPosition(a)&16)}}();
wysihtml5.dom.convertToList=function(){function b(b,a){var d=b.createElement("li");a.appendChild(d);return d}return function(c,a){if("UL"===c.nodeName||"OL"===c.nodeName||"MENU"===c.nodeName)return c;for(var d=c.ownerDocument,e=d.createElement(a),f=wysihtml5.lang.array(c.childNodes).get(),h=f.length,i,g,k,j,q=0;q<h;q++)j=j||b(d,e),i=f[q],g="block"===wysihtml5.dom.getStyle("display").from(i),k="BR"===i.nodeName,g?(j=j.firstChild?b(d,e):j,j.appendChild(i),j=null):k?j=j.firstChild?null:j:j.appendChild(i);
c.parentNode.replaceChild(e,c);return e}}();wysihtml5.dom.copyAttributes=function(b){return{from:function(c){return{to:function(a){for(var d,e=0,f=b.length;e<f;e++)d=b[e],c[d]&&(a[d]=c[d]);return{andTo:arguments.callee}}}}}};
(function(b){var c=["-webkit-box-sizing","-moz-box-sizing","-ms-box-sizing","box-sizing"],a=function(a){var e;a:for(var f=0,h=c.length;f<h;f++)if("border-box"===b.getStyle(c[f]).from(a)){e=c[f];break a}return e?parseInt(b.getStyle("width").from(a),10)<a.offsetWidth:!1};b.copyStyles=function(d){return{from:function(e){a(e)&&(d=wysihtml5.lang.array(d).without(c));for(var f="",h=d.length,i=0,g;i<h;i++)g=d[i],f+=g+":"+b.getStyle(g).from(e)+";";return{to:function(a){b.setStyles(f).on(a);return{andTo:arguments.callee}}}}}}})(wysihtml5.dom);
(function(b){b.dom.delegate=function(c,a,d,e){return b.dom.observe(c,d,function(d){for(var h=d.target,i=b.lang.array(c.querySelectorAll(a));h&&h!==c;){if(i.contains(h)){e.call(h,d);break}h=h.parentNode}})}})(wysihtml5);
wysihtml5.dom.getAsDom=function(){var b="abbr,article,aside,audio,bdi,canvas,command,datalist,details,figcaption,figure,footer,header,hgroup,keygen,mark,meter,nav,output,progress,rp,rt,ruby,svg,section,source,summary,time,track,video,wbr".split(",");return function(c,a){var a=a||document,d;if("object"===typeof c&&c.nodeType)d=a.createElement("div"),d.appendChild(c);else if(wysihtml5.browser.supportsHTML5Tags(a))d=a.createElement("div"),d.innerHTML=c;else{d=a;if(!d._wysihtml5_supportsHTML5Tags){for(var e=
0,f=b.length;e<f;e++)d.createElement(b[e]);d._wysihtml5_supportsHTML5Tags=!0}d=a;e=d.createElement("div");e.style.display="none";d.body.appendChild(e);try{e.innerHTML=c}catch(h){}d.body.removeChild(e);d=e}return d}}();
wysihtml5.dom.getParentElement=function(){function b(b,a){return!a||!a.length?!0:"string"===typeof a?b===a:wysihtml5.lang.array(a).contains(b)}return function(c,a,d){d=d||50;if(a.className||a.classRegExp){a:{for(var e=a.nodeName,f=a.className,a=a.classRegExp;d--&&c&&"BODY"!==c.nodeName;){var h;if(h=c.nodeType===wysihtml5.ELEMENT_NODE)if(h=b(c.nodeName,e)){h=f;var i=(c.className||"").match(a)||[];h=!h?!!i.length:i[i.length-1]===h}if(h)break a;c=c.parentNode}c=null}return c}a:{e=a.nodeName;for(f=d;f--&&
c&&"BODY"!==c.nodeName;){if(b(c.nodeName,e))break a;c=c.parentNode}c=null}return c}}();
wysihtml5.dom.getStyle=function(){function b(b){return b.replace(a,function(a){return a.charAt(1).toUpperCase()})}var c={"float":"styleFloat"in document.createElement("div").style?"styleFloat":"cssFloat"},a=/\-[a-z]/g;return function(a){return{from:function(e){if(e.nodeType===wysihtml5.ELEMENT_NODE){var f=e.ownerDocument,h=c[a]||b(a),i=e.style,g=e.currentStyle,k=i[h];if(k)return k;if(g)try{return g[h]}catch(j){}var h=f.defaultView||f.parentWindow,f=("height"===a||"width"===a)&&"TEXTAREA"===e.nodeName,
q;if(h.getComputedStyle)return f&&(q=i.overflow,i.overflow="hidden"),e=h.getComputedStyle(e,null).getPropertyValue(a),f&&(i.overflow=q||""),e}}}}}();wysihtml5.dom.hasElementWithTagName=function(){var b={},c=1;return function(a,d){var e=(a._wysihtml5_identifier||(a._wysihtml5_identifier=c++))+":"+d,f=b[e];f||(f=b[e]=a.getElementsByTagName(d));return 0<f.length}}();
(function(b){var c={},a=1;b.dom.hasElementWithClassName=function(d,e){if(!b.browser.supportsNativeGetElementsByClassName())return!!d.querySelector("."+e);var f=(d._wysihtml5_identifier||(d._wysihtml5_identifier=a++))+":"+e,h=c[f];h||(h=c[f]=d.getElementsByClassName(e));return 0<h.length}})(wysihtml5);wysihtml5.dom.insert=function(b){return{after:function(c){c.parentNode.insertBefore(b,c.nextSibling)},before:function(c){c.parentNode.insertBefore(b,c)},into:function(c){c.appendChild(b)}}};
wysihtml5.dom.insertCSS=function(b){b=b.join("\n");return{into:function(c){var a=c.head||c.getElementsByTagName("head")[0],d=c.createElement("style");d.type="text/css";d.styleSheet?d.styleSheet.cssText=b:d.appendChild(c.createTextNode(b));a&&a.appendChild(d)}}};
wysihtml5.dom.observe=function(b,c,a){for(var c="string"===typeof c?[c]:c,d,e,f=0,h=c.length;f<h;f++)e=c[f],b.addEventListener?b.addEventListener(e,a,!1):(d=function(c){"target"in c||(c.target=c.srcElement);c.preventDefault=c.preventDefault||function(){this.returnValue=false};c.stopPropagation=c.stopPropagation||function(){this.cancelBubble=true};a.call(b,c)},b.attachEvent("on"+e,d));return{stop:function(){for(var e,g=0,f=c.length;g<f;g++)e=c[g],b.removeEventListener?b.removeEventListener(e,a,!1):
b.detachEvent("on"+e,d)}}};
wysihtml5.dom.parse=function(){function b(c,e){var g=c.childNodes,f=g.length,k;k=a[c.nodeType];var h=0;k=k&&k(c);if(!k)return null;for(h=0;h<f;h++)(newChild=b(g[h],e))&&k.appendChild(newChild);return e&&1>=k.childNodes.length&&k.nodeName.toLowerCase()===d&&!k.attributes.length?k.firstChild:k}function c(a,b){var b=b.toLowerCase(),c;if(c="IMG"==a.nodeName)if(c="src"==b){var d;try{d=a.complete&&!a.mozMatchesSelector(":-moz-broken")}catch(e){a.complete&&"complete"===a.readyState&&(d=!0)}c=!0===d}return c?
a.src:i&&"outerHTML"in a?-1!=a.outerHTML.toLowerCase().indexOf(" "+b+"=")?a.getAttribute(b):null:a.getAttribute(b)}var a={1:function(a){var b,f,i=h.tags;f=a.nodeName.toLowerCase();b=a.scopeName;if(a._wysihtml5)return null;a._wysihtml5=1;if("wysihtml5-temp"===a.className)return null;b&&"HTML"!=b&&(f=b+":"+f);"outerHTML"in a&&!wysihtml5.browser.autoClosesUnclosedTags()&&"P"===a.nodeName&&"</p>"!==a.outerHTML.slice(-4).toLowerCase()&&(f="div");if(f in i){b=i[f];if(!b||b.remove)return null;b="string"===
typeof b?{rename_tag:b}:b}else if(a.firstChild)b={rename_tag:d};else return null;f=a.ownerDocument.createElement(b.rename_tag||f);var i={},r=b.set_class,m=b.add_class,s=b.set_attributes,x=b.check_attributes,o=h.classes,z=0,w=[];b=[];var y=[],A=[],t;s&&(i=wysihtml5.lang.object(s).clone());if(x)for(t in x)if(s=g[x[t]])s=s(c(a,t)),"string"===typeof s&&(i[t]=s);r&&w.push(r);if(m)for(t in m)if(s=k[m[t]])r=s(c(a,t)),"string"===typeof r&&w.push(r);o["_wysihtml5-temp-placeholder"]=1;(A=a.getAttribute("class"))&&
(w=w.concat(A.split(e)));for(m=w.length;z<m;z++)a=w[z],o[a]&&b.push(a);for(o=b.length;o--;)a=b[o],wysihtml5.lang.array(y).contains(a)||y.unshift(a);y.length&&(i["class"]=y.join(" "));for(t in i)try{f.setAttribute(t,i[t])}catch(v){}i.src&&("undefined"!==typeof i.width&&f.setAttribute("width",i.width),"undefined"!==typeof i.height&&f.setAttribute("height",i.height));return f},3:function(a){return a.ownerDocument.createTextNode(a.data)}},d="span",e=/\s+/,f={tags:{},classes:{}},h={},i=!wysihtml5.browser.supportsGetAttributeCorrectly(),
g={url:function(){var a=/^https?:\/\//i;return function(b){return!b||!b.match(a)?null:b.replace(a,function(a){return a.toLowerCase()})}}(),alt:function(){var a=/[^ a-z0-9_\-]/gi;return function(b){return!b?"":b.replace(a,"")}}(),numbers:function(){var a=/\D/g;return function(b){return(b=(b||"").replace(a,""))||null}}()},k={align_img:function(){var a={left:"wysiwyg-float-left",right:"wysiwyg-float-right"};return function(b){return a[(""+b).toLowerCase()]}}(),align_text:function(){var a={left:"wysiwyg-text-align-left",
right:"wysiwyg-text-align-right",center:"wysiwyg-text-align-center",justify:"wysiwyg-text-align-justify"};return function(b){return a[(""+b).toLowerCase()]}}(),clear_br:function(){var a={left:"wysiwyg-clear-left",right:"wysiwyg-clear-right",both:"wysiwyg-clear-both",all:"wysiwyg-clear-both"};return function(b){return a[(""+b).toLowerCase()]}}(),size_font:function(){var a={1:"wysiwyg-font-size-xx-small",2:"wysiwyg-font-size-small",3:"wysiwyg-font-size-medium",4:"wysiwyg-font-size-large",5:"wysiwyg-font-size-x-large",
6:"wysiwyg-font-size-xx-large",7:"wysiwyg-font-size-xx-large","-":"wysiwyg-font-size-smaller","+":"wysiwyg-font-size-larger"};return function(b){return a[(""+b).charAt(0)]}}()};return function(a,c,d,e){wysihtml5.lang.object(h).merge(f).merge(c).get();for(var d=d||a.ownerDocument||document,c=d.createDocumentFragment(),g="string"===typeof a,a=g?wysihtml5.dom.getAsDom(a,d):a;a.firstChild;)d=a.firstChild,a.removeChild(d),(d=b(d,e))&&c.appendChild(d);a.innerHTML="";a.appendChild(c);return g?wysihtml5.quirks.getCorrectInnerHTML(a):
a}}();wysihtml5.dom.removeEmptyTextNodes=function(b){for(var c=wysihtml5.lang.array(b.childNodes).get(),a=c.length,d=0;d<a;d++)b=c[d],b.nodeType===wysihtml5.TEXT_NODE&&""===b.data&&b.parentNode.removeChild(b)};wysihtml5.dom.renameElement=function(b,c){for(var a=b.ownerDocument.createElement(c),d;d=b.firstChild;)a.appendChild(d);wysihtml5.dom.copyAttributes(["align","className"]).from(b).to(a);b.parentNode.replaceChild(a,b);return a};
wysihtml5.dom.replaceWithChildNodes=function(b){if(b.parentNode)if(b.firstChild){for(var c=b.ownerDocument.createDocumentFragment();b.firstChild;)c.appendChild(b.firstChild);b.parentNode.replaceChild(c,b)}else b.parentNode.removeChild(b)};
(function(b){function c(a){var b=a.ownerDocument.createElement("br");a.appendChild(b)}b.resolveList=function(a){if(!("MENU"!==a.nodeName&&"UL"!==a.nodeName&&"OL"!==a.nodeName)){var d=a.ownerDocument.createDocumentFragment(),e=a.previousSibling,f,h,i;for(e&&"block"!==b.getStyle("display").from(e)&&c(d);i=a.firstChild;){for(f=i.lastChild;e=i.firstChild;)h=(h=e===f)&&"block"!==b.getStyle("display").from(e)&&"BR"!==e.nodeName,d.appendChild(e),h&&c(d);i.parentNode.removeChild(i)}a.parentNode.replaceChild(d,
a)}}})(wysihtml5.dom);
(function(b){var c=document,a="parent,top,opener,frameElement,frames,localStorage,globalStorage,sessionStorage,indexedDB".split(","),d="open,close,openDialog,showModalDialog,alert,confirm,prompt,openDatabase,postMessage,XMLHttpRequest,XDomainRequest".split(","),e=["referrer","write","open","close"];b.dom.Sandbox=Base.extend({constructor:function(a,c){this.callback=a||b.EMPTY_FUNCTION;this.config=b.lang.object({}).merge(c).get();this.iframe=this._createIframe()},insertInto:function(a){"string"===typeof a&&
(a=c.getElementById(a));a.appendChild(this.iframe)},getIframe:function(){return this.iframe},getWindow:function(){this._readyError()},getDocument:function(){this._readyError()},destroy:function(){var a=this.getIframe();a.parentNode.removeChild(a)},_readyError:function(){throw Error("wysihtml5.Sandbox: Sandbox iframe isn't loaded yet");},_createIframe:function(){var a=this,d=c.createElement("iframe");d.className="wysihtml5-sandbox";b.dom.setAttributes({security:"restricted",allowtransparency:"true",
frameborder:0,width:0,height:0,marginwidth:0,marginheight:0}).on(d);b.browser.throwsMixedContentWarningWhenIframeSrcIsEmpty()&&(d.src="javascript:'<html></html>'");d.onload=function(){d.onreadystatechange=d.onload=null;a._onLoadIframe(d)};d.onreadystatechange=function(){if(/loaded|complete/.test(d.readyState)){d.onreadystatechange=d.onload=null;a._onLoadIframe(d)}};return d},_onLoadIframe:function(f){if(b.dom.contains(c.documentElement,f)){var h=this,i=f.contentWindow,g=f.contentWindow.document,k=
this._getHtml({charset:c.characterSet||c.charset||"utf-8",stylesheets:this.config.stylesheets});g.open("text/html","replace");g.write(k);g.close();this.getWindow=function(){return f.contentWindow};this.getDocument=function(){return f.contentWindow.document};i.onerror=function(a,b,c){throw Error("wysihtml5.Sandbox: "+a,b,c);};if(!b.browser.supportsSandboxedIframes()){var j,k=0;for(j=a.length;k<j;k++)this._unset(i,a[k]);k=0;for(j=d.length;k<j;k++)this._unset(i,d[k],b.EMPTY_FUNCTION);k=0;for(j=e.length;k<
j;k++)this._unset(g,e[k]);this._unset(g,"cookie","",!0)}this.loaded=!0;setTimeout(function(){h.callback(h)},0)}},_getHtml:function(a){var c=a.stylesheets,d="",e=0,k;if(c="string"===typeof c?[c]:c)for(k=c.length;e<k;e++)d+='<link rel="stylesheet" href="'+c[e]+'">';a.stylesheets=d;return b.lang.string('<!DOCTYPE html><html><head><meta charset="#{charset}">#{stylesheets}</head><body></body></html>').interpolate(a)},_unset:function(a,c,d,e){try{a[c]=d}catch(k){}try{a.__defineGetter__(c,function(){return d})}catch(j){}if(e)try{a.__defineSetter__(c,
function(){})}catch(q){}if(!b.browser.crashesWhenDefineProperty(c))try{var n={get:function(){return d}};e&&(n.set=function(){});Object.defineProperty(a,c,n)}catch(p){}}})})(wysihtml5);(function(){var b={className:"class"};wysihtml5.dom.setAttributes=function(c){return{on:function(a){for(var d in c)a.setAttribute(b[d]||d,c[d])}}}})();
wysihtml5.dom.setStyles=function(b){return{on:function(c){c=c.style;if("string"===typeof b)c.cssText+=";"+b;else for(var a in b)"float"===a?(c.cssFloat=b[a],c.styleFloat=b[a]):c[a]=b[a]}}};
(function(b){b.simulatePlaceholder=function(c,a,d){var e=function(){a.hasPlaceholderSet()&&a.clear();b.removeClass(a.element,"placeholder")},f=function(){a.isEmpty()&&(a.setValue(d),b.addClass(a.element,"placeholder"))};c.observe("set_placeholder",f).observe("unset_placeholder",e).observe("focus:composer",e).observe("paste:composer",e).observe("blur:composer",f);f()}})(wysihtml5.dom);
(function(b){var c=document.documentElement;"textContent"in c?(b.setTextContent=function(a,b){a.textContent=b},b.getTextContent=function(a){return a.textContent}):"innerText"in c?(b.setTextContent=function(a,b){a.innerText=b},b.getTextContent=function(a){return a.innerText}):(b.setTextContent=function(a,b){a.nodeValue=b},b.getTextContent=function(a){return a.nodeValue})})(wysihtml5.dom);
wysihtml5.quirks.cleanPastedHTML=function(){var b={"a u":wysihtml5.dom.replaceWithChildNodes};return function(c,a,d){var a=a||b,d=d||c.ownerDocument||document,e="string"===typeof c,f,h,i,g=0,c=e?wysihtml5.dom.getAsDom(c,d):c;for(i in a){f=c.querySelectorAll(i);d=a[i];for(h=f.length;g<h;g++)d(f[g])}return e?c.innerHTML:c}}();
(function(b){var c=b.dom;b.quirks.ensureProperClearing=function(){var a=function(){var a=this;setTimeout(function(){var b=a.innerHTML.toLowerCase();if("<p>&nbsp;</p>"==b||"<p>&nbsp;</p><p>&nbsp;</p>"==b)a.innerHTML=""},0)};return function(b){c.observe(b.element,["cut","keydown"],a)}}();b.quirks.ensureProperClearingOfLists=function(){var a=["OL","UL","MENU"];return function(d){c.observe(d.element,"keydown",function(e){if(e.keyCode===b.BACKSPACE_KEY){var f=d.selection.getSelectedNode(),e=d.element;
e.firstChild&&b.lang.array(a).contains(e.firstChild.nodeName)&&(f=c.getParentElement(f,{nodeName:a}))&&f==e.firstChild&&1>=f.childNodes.length&&(f.firstChild?""===f.firstChild.innerHTML:1)&&f.parentNode.removeChild(f)}})}}()})(wysihtml5);
(function(b){b.quirks.getCorrectInnerHTML=function(c){var a=c.innerHTML;if(-1===a.indexOf("%7E"))return a;var c=c.querySelectorAll("[href*='~'], [src*='~']"),d,e,f,h;h=0;for(f=c.length;h<f;h++)d=c[h].href||c[h].src,e=b.lang.string(d).replace("~").by("%7E"),a=b.lang.string(a).replace(e).by(d);return a}})(wysihtml5);
(function(b){var c=b.dom,a="LI,P,H1,H2,H3,H4,H5,H6".split(","),d=["UL","OL","MENU"];b.quirks.insertLineBreakOnReturn=function(e){function f(a){if(a=c.getParentElement(a,{nodeName:["P","DIV"]},2)){var d=document.createTextNode(b.INVISIBLE_SPACE);c.insert(d).before(a);c.replaceWithChildNodes(a);e.selection.selectNode(d)}}c.observe(e.element.ownerDocument,"keydown",function(h){var i=h.keyCode;if(!(h.shiftKey||i!==b.ENTER_KEY&&i!==b.BACKSPACE_KEY)){var g=e.selection.getSelectedNode();(g=c.getParentElement(g,
{nodeName:a},4))?"LI"===g.nodeName&&(i===b.ENTER_KEY||i===b.BACKSPACE_KEY)?setTimeout(function(){var a=e.selection.getSelectedNode(),b;a&&((b=c.getParentElement(a,{nodeName:d},2))||f(a))},0):g.nodeName.match(/H[1-6]/)&&i===b.ENTER_KEY&&setTimeout(function(){f(e.selection.getSelectedNode())},0):i===b.ENTER_KEY&&!b.browser.insertsLineBreaksOnReturn()&&(e.commands.exec("insertLineBreak"),h.preventDefault())}})}})(wysihtml5);
(function(b){b.quirks.redraw=function(c){b.dom.addClass(c,"wysihtml5-quirks-redraw");b.dom.removeClass(c,"wysihtml5-quirks-redraw");try{var a=c.ownerDocument;a.execCommand("italic",!1,null);a.execCommand("italic",!1,null)}catch(d){}}})(wysihtml5);
(function(b){var c=b.dom;b.Selection=Base.extend({constructor:function(a){window.rangy.init();this.editor=a;this.composer=a.composer;this.doc=this.composer.doc},getBookmark:function(){var a=this.getRange();return a&&a.cloneRange()},setBookmark:function(a){a&&this.setSelection(a)},setBefore:function(a){var b=rangy.createRange(this.doc);b.setStartBefore(a);b.setEndBefore(a);return this.setSelection(b)},setAfter:function(a){var b=rangy.createRange(this.doc);b.setStartAfter(a);b.setEndAfter(a);return this.setSelection(b)},
selectNode:function(a){var d=rangy.createRange(this.doc),e=a.nodeType===b.ELEMENT_NODE,f="canHaveHTML"in a?a.canHaveHTML:"IMG"!==a.nodeName,h=e?a.innerHTML:a.data,h=""===h||h===b.INVISIBLE_SPACE,i=c.getStyle("display").from(a),i="block"===i||"list-item"===i;if(h&&e&&f)try{a.innerHTML=b.INVISIBLE_SPACE}catch(g){}f?d.selectNodeContents(a):d.selectNode(a);f&&h&&e?d.collapse(i):f&&h&&(d.setStartAfter(a),d.setEndAfter(a));this.setSelection(d)},getSelectedNode:function(a){if(a&&this.doc.selection&&"Control"===
this.doc.selection.type&&(a=this.doc.selection.createRange())&&a.length)return a.item(0);a=this.getSelection(this.doc);return a.focusNode===a.anchorNode?a.focusNode:(a=this.getRange(this.doc))?a.commonAncestorContainer:this.doc.body},executeAndRestore:function(a,c){var e=this.doc.body,f=c&&e.scrollTop,h=c&&e.scrollLeft,i='<span class="_wysihtml5-temp-placeholder">'+b.INVISIBLE_SPACE+"</span>",g=this.getRange(this.doc);if(g){i=g.createContextualFragment(i);g.insertNode(i);try{a(g.startContainer,g.endContainer)}catch(k){setTimeout(function(){throw k;
},0)}(caretPlaceholder=this.doc.querySelector("._wysihtml5-temp-placeholder"))?(g=rangy.createRange(this.doc),g.selectNode(caretPlaceholder),g.deleteContents(),this.setSelection(g)):e.focus();c&&(e.scrollTop=f,e.scrollLeft=h);try{caretPlaceholder.parentNode.removeChild(caretPlaceholder)}catch(j){}}else a(e,e)},executeAndRestoreSimple:function(a){var b,c,f=this.getRange(),h=this.doc.body,i;if(f){b=f.getNodes([3]);h=b[0]||f.startContainer;i=b[b.length-1]||f.endContainer;b=h===f.startContainer?f.startOffset:
0;c=i===f.endContainer?f.endOffset:i.length;try{a(f.startContainer,f.endContainer)}catch(g){setTimeout(function(){throw g;},0)}a=rangy.createRange(this.doc);try{a.setStart(h,b)}catch(k){}try{a.setEnd(i,c)}catch(j){}try{this.setSelection(a)}catch(q){}}else a(h,h)},insertHTML:function(a){var a=rangy.createRange(this.doc).createContextualFragment(a),b=a.lastChild;this.insertNode(a);b&&this.setAfter(b)},insertNode:function(a){var b=this.getRange();b&&b.insertNode(a)},surround:function(a){var b=this.getRange();
if(b)try{b.surroundContents(a),this.selectNode(a)}catch(c){a.appendChild(b.extractContents()),b.insertNode(a)}},scrollIntoView:function(){var a=this.doc,c=a.documentElement.scrollHeight>a.documentElement.offsetHeight,e;if(!(e=a._wysihtml5ScrollIntoViewElement))e=a.createElement("span"),e.innerHTML=b.INVISIBLE_SPACE;e=a._wysihtml5ScrollIntoViewElement=e;if(c){this.insertNode(e);var c=e,f=0;if(c.parentNode){do f+=c.offsetTop||0,c=c.offsetParent;while(c)}c=f;e.parentNode.removeChild(e);c>a.body.scrollTop&&
(a.body.scrollTop=c)}},selectLine:function(){b.browser.supportsSelectionModify()?this._selectLine_W3C():this.doc.selection&&this._selectLine_MSIE()},_selectLine_W3C:function(){var a=this.doc.defaultView.getSelection();a.modify("extend","left","lineboundary");a.modify("extend","right","lineboundary")},_selectLine_MSIE:function(){var a=this.doc.selection.createRange(),b=a.boundingTop,c=this.doc.body.scrollWidth,f;if(a.moveToPoint){0===b&&(f=this.doc.createElement("span"),this.insertNode(f),b=f.offsetTop,
f.parentNode.removeChild(f));b+=1;for(f=-10;f<c;f+=2)try{a.moveToPoint(f,b);break}catch(h){}for(f=this.doc.selection.createRange();0<=c;c--)try{f.moveToPoint(c,b);break}catch(i){}a.setEndPoint("EndToEnd",f);a.select()}},getText:function(){var a=this.getSelection();return a?a.toString():""},getNodes:function(a,b){var c=this.getRange();return c?c.getNodes([a],b):[]},getRange:function(){var a=this.getSelection();return a&&a.rangeCount&&a.getRangeAt(0)},getSelection:function(){return rangy.getSelection(this.doc.defaultView||
this.doc.parentWindow)},setSelection:function(a){return rangy.getSelection(this.doc.defaultView||this.doc.parentWindow).setSingleRange(a)}})})(wysihtml5);
(function(b,c){function a(a,b){return c.dom.isCharacterDataNode(a)?0==b?!!a.previousSibling:b==a.length?!!a.nextSibling:!0:0<b&&b<a.childNodes.length}function d(a,b,e){var f;c.dom.isCharacterDataNode(b)&&(0==e?(e=c.dom.getNodeIndex(b),b=b.parentNode):e==b.length?(e=c.dom.getNodeIndex(b)+1,b=b.parentNode):f=c.dom.splitDataNode(b,e));if(!f){f=b.cloneNode(!1);f.id&&f.removeAttribute("id");for(var h;h=b.childNodes[e];)f.appendChild(h);c.dom.insertAfter(f,b)}return b==a?f:d(a,f.parentNode,c.dom.getNodeIndex(f))}
function e(a){this.firstTextNode=(this.isElementMerge=a.nodeType==b.ELEMENT_NODE)?a.lastChild:a;this.textNodes=[this.firstTextNode]}function f(a,b,c,d){this.tagNames=a||[h];this.cssClass=b||"";this.similarClassRegExp=c;this.normalize=d;this.applyToAnyTagName=!1}var h="span",i=/\s+/g;e.prototype={doMerge:function(){for(var a=[],b,c,d=0,e=this.textNodes.length;d<e;++d)b=this.textNodes[d],c=b.parentNode,a[d]=b.data,d&&(c.removeChild(b),c.hasChildNodes()||c.parentNode.removeChild(c));return this.firstTextNode.data=
a=a.join("")},getLength:function(){for(var a=this.textNodes.length,b=0;a--;)b+=this.textNodes[a].length;return b},toString:function(){for(var a=[],b=0,c=this.textNodes.length;b<c;++b)a[b]="'"+this.textNodes[b].data+"'";return"[Merge("+a.join(",")+")]"}};f.prototype={getAncestorWithClass:function(a){for(var d;a;){if(this.cssClass)if(d=this.cssClass,a.className){var e=a.className.match(this.similarClassRegExp)||[];d=e[e.length-1]===d}else d=!1;else d=!0;if(a.nodeType==b.ELEMENT_NODE&&c.dom.arrayContains(this.tagNames,
a.tagName.toLowerCase())&&d)return a;a=a.parentNode}return!1},postApply:function(a,b){for(var c=a[0],d=a[a.length-1],f=[],h,i=c,m=d,s=0,x=d.length,o,z,w=0,y=a.length;w<y;++w)if(o=a[w],z=this.getAdjacentMergeableTextNode(o.parentNode,!1)){if(h||(h=new e(z),f.push(h)),h.textNodes.push(o),o===c&&(i=h.firstTextNode,s=i.length),o===d)m=h.firstTextNode,x=h.getLength()}else h=null;if(c=this.getAdjacentMergeableTextNode(d.parentNode,!0))h||(h=new e(d),f.push(h)),h.textNodes.push(c);if(f.length){w=0;for(y=
f.length;w<y;++w)f[w].doMerge();b.setStart(i,s);b.setEnd(m,x)}},getAdjacentMergeableTextNode:function(a,c){var d=a.nodeType==b.TEXT_NODE,e=d?a.parentNode:a,f=c?"nextSibling":"previousSibling";if(d){if((d=a[f])&&d.nodeType==b.TEXT_NODE)return d}else if((d=e[f])&&this.areElementsMergeable(a,d))return d[c?"firstChild":"lastChild"];return null},areElementsMergeable:function(a,b){var d;if(d=c.dom.arrayContains(this.tagNames,(a.tagName||"").toLowerCase()))if(d=c.dom.arrayContains(this.tagNames,(b.tagName||
"").toLowerCase()))if(d=a.className.replace(i," ")==b.className.replace(i," "))a:if(a.attributes.length!=b.attributes.length)d=!1;else{d=0;for(var e=a.attributes.length,f,h;d<e;++d)if(f=a.attributes[d],h=f.name,"class"!=h&&(h=b.attributes.getNamedItem(h),f.specified!=h.specified||f.specified&&f.nodeValue!==h.nodeValue)){d=!1;break a}d=!0}return d},createContainer:function(a){a=a.createElement(this.tagNames[0]);this.cssClass&&(a.className=this.cssClass);return a},applyToTextNode:function(a){var b=
a.parentNode;1==b.childNodes.length&&c.dom.arrayContains(this.tagNames,b.tagName.toLowerCase())?this.cssClass&&(a=this.cssClass,b.className?(b.className&&(b.className=b.className.replace(this.similarClassRegExp,"")),b.className+=" "+a):b.className=a):(b=this.createContainer(c.dom.getDocument(a)),a.parentNode.insertBefore(b,a),b.appendChild(a))},isRemovable:function(a){return c.dom.arrayContains(this.tagNames,a.tagName.toLowerCase())&&b.lang.string(a.className).trim()==this.cssClass},undoToTextNode:function(b,
c,e){c.containsNode(e)||(b=c.cloneRange(),b.selectNode(e),b.isPointInRange(c.endContainer,c.endOffset)&&a(c.endContainer,c.endOffset)&&(d(e,c.endContainer,c.endOffset),c.setEndAfter(e)),b.isPointInRange(c.startContainer,c.startOffset)&&a(c.startContainer,c.startOffset)&&(e=d(e,c.startContainer,c.startOffset)));this.similarClassRegExp&&e.className&&(e.className=e.className.replace(this.similarClassRegExp,""));if(this.isRemovable(e)){c=e;for(e=c.parentNode;c.firstChild;)e.insertBefore(c.firstChild,
c);e.removeChild(c)}},applyToRange:function(a){var c=a.getNodes([b.TEXT_NODE]);if(!c.length)try{var d=this.createContainer(a.endContainer.ownerDocument);a.surroundContents(d);this.selectNode(a,d);return}catch(e){}a.splitBoundaries();c=a.getNodes([b.TEXT_NODE]);if(c.length){for(var f=0,h=c.length;f<h;++f)d=c[f],this.getAncestorWithClass(d)||this.applyToTextNode(d);a.setStart(c[0],0);d=c[c.length-1];a.setEnd(d,d.length);this.normalize&&this.postApply(c,a)}},undoToRange:function(a){var c=a.getNodes([b.TEXT_NODE]),
d,e;c.length?(a.splitBoundaries(),c=a.getNodes([b.TEXT_NODE])):(c=a.endContainer.ownerDocument.createTextNode(b.INVISIBLE_SPACE),a.insertNode(c),a.selectNode(c),c=[c]);for(var f=0,h=c.length;f<h;++f)d=c[f],(e=this.getAncestorWithClass(d))&&this.undoToTextNode(d,a,e);1==h?this.selectNode(a,c[0]):(a.setStart(c[0],0),d=c[c.length-1],a.setEnd(d,d.length),this.normalize&&this.postApply(c,a))},selectNode:function(a,c){var d=c.nodeType===b.ELEMENT_NODE,e="canHaveHTML"in c?c.canHaveHTML:!0,f=d?c.innerHTML:
c.data;if((f=""===f||f===b.INVISIBLE_SPACE)&&d&&e)try{c.innerHTML=b.INVISIBLE_SPACE}catch(h){}a.selectNodeContents(c);f&&d?a.collapse(!1):f&&(a.setStartAfter(c),a.setEndAfter(c))},getTextSelectedByRange:function(a,b){var c=b.cloneRange();c.selectNodeContents(a);var d=c.intersection(b),d=d?d.toString():"";c.detach();return d},isAppliedToRange:function(a){var c=[],d,e=a.getNodes([b.TEXT_NODE]);if(!e.length)return(d=this.getAncestorWithClass(a.startContainer))?[d]:!1;for(var f=0,h=e.length,i;f<h;++f){i=
this.getTextSelectedByRange(e[f],a);d=this.getAncestorWithClass(e[f]);if(""!=i&&!d)return!1;c.push(d)}return c},toggleRange:function(a){this.isAppliedToRange(a)?this.undoToRange(a):this.applyToRange(a)}};b.selection.HTMLApplier=f})(wysihtml5,rangy);
wysihtml5.Commands=Base.extend({constructor:function(b){this.editor=b;this.composer=b.composer;this.doc=this.composer.doc},support:function(b){return wysihtml5.browser.supportsCommand(this.doc,b)},exec:function(b,c){var a=wysihtml5.commands[b],d=a&&a.exec;this.editor.fire("beforecommand:composer");if(d)return d.call(a,this.composer,b,c);try{return this.doc.execCommand(b,!1,c)}catch(e){}this.editor.fire("aftercommand:composer")},state:function(b,c){var a=wysihtml5.commands[b],d=a&&a.state;if(d)return d.call(a,
this.composer,b,c);try{return this.doc.queryCommandState(b)}catch(e){return!1}},value:function(b){var c=wysihtml5.commands[b],a=c&&c.value;if(a)return a.call(c,this.composer,b);try{return this.doc.queryCommandValue(b)}catch(d){return null}}});(function(b){b.commands.bold={exec:function(c,a){return b.commands.formatInline.exec(c,a,"b")},state:function(c,a){return b.commands.formatInline.state(c,a,"b")},value:function(){}}})(wysihtml5);
(function(b){function c(c,h){var i=c.doc,g="_wysihtml5-temp-"+ +new Date,k=0,j,q,n;b.commands.formatInline.exec(c,a,d,g,/non-matching-class/g);j=i.querySelectorAll(d+"."+g);for(g=j.length;k<g;k++)for(n in q=j[k],q.removeAttribute("class"),h)q.setAttribute(n,h[n]);k=q;1===g&&(n=e.getTextContent(q),g=!!q.querySelector("*"),n=""===n||n===b.INVISIBLE_SPACE,!g&&n&&(e.setTextContent(q,q.href),i=i.createTextNode(" "),c.selection.setAfter(q),c.selection.insertNode(i),k=i));c.selection.setAfter(k)}var a,d=
"A",e=b.dom;b.commands.createLink={exec:function(a,b,d){var g=this.state(a,b);g?a.selection.executeAndRestore(function(){for(var a=g.length,b=0,c,d,f;b<a;b++)c=g[b],d=e.getParentElement(c,{nodeName:"code"}),f=e.getTextContent(c),f.match(e.autoLink.URL_REG_EXP)&&!d?e.renameElement(c,"code"):e.replaceWithChildNodes(c)}):(d="object"===typeof d?d:{href:d},c(a,d))},state:function(a,c){return b.commands.formatInline.state(a,c,"A")},value:function(){return a}}})(wysihtml5);
(function(b){var c=/wysiwyg-font-size-[a-z]+/g;b.commands.fontSize={exec:function(a,d,e){return b.commands.formatInline.exec(a,d,"span","wysiwyg-font-size-"+e,c)},state:function(a,d,e){return b.commands.formatInline.state(a,d,"span","wysiwyg-font-size-"+e,c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-color-[a-z]+/g;b.commands.foreColor={exec:function(a,d,e){return b.commands.formatInline.exec(a,d,"span","wysiwyg-color-"+e,c)},state:function(a,d,e){return b.commands.formatInline.state(a,d,"span","wysiwyg-color-"+e,c)},value:function(){}}})(wysihtml5);
(function(b){function c(a){for(a=a.previousSibling;a&&a.nodeType===b.TEXT_NODE&&!b.lang.string(a.data).trim();)a=a.previousSibling;return a}function a(a){for(a=a.nextSibling;a&&a.nodeType===b.TEXT_NODE&&!b.lang.string(a.data).trim();)a=a.nextSibling;return a}function d(a){return"BR"===a.nodeName||"block"===h.getStyle("display").from(a)?!0:!1}function e(a,c,d,e){if(e)var f=h.observe(a,"DOMNodeInserted",function(a){var a=a.target,c;a.nodeType===b.ELEMENT_NODE&&(c=h.getStyle("display").from(a),"inline"!==
c.substr(0,6)&&(a.className+=" "+e))});a.execCommand(c,!1,d);f&&f.stop()}function f(b,d){b.selection.selectLine();b.selection.surround(d);var e=a(d),f=c(d);e&&"BR"===e.nodeName&&e.parentNode.removeChild(e);f&&"BR"===f.nodeName&&f.parentNode.removeChild(f);(e=d.lastChild)&&"BR"===e.nodeName&&e.parentNode.removeChild(e);b.selection.selectNode(d)}var h=b.dom,i="H1,H2,H3,H4,H5,H6,P,BLOCKQUOTE,DIV".split(",");b.commands.formatBlock={exec:function(g,k,j,q,n){var p=g.doc,r=this.state(g,k,j,q,n),m,j="string"===
typeof j?j.toUpperCase():j;if(r)g.selection.executeAndRestoreSimple(function(){n&&(r.className=r.className.replace(n,""));var e=!!b.lang.string(r.className).trim();if(!e&&r.nodeName===(j||"DIV")){var e=r,f=e.ownerDocument,g=a(e),i=c(e);g&&!d(g)&&e.parentNode.insertBefore(f.createElement("br"),g);i&&!d(i)&&e.parentNode.insertBefore(f.createElement("br"),e);h.replaceWithChildNodes(r)}else e&&h.renameElement(r,"DIV")});else{if(null===j||b.lang.array(i).contains(j))if(m=g.selection.getSelectedNode(),
r=h.getParentElement(m,{nodeName:i})){g.selection.executeAndRestoreSimple(function(){j&&(r=h.renameElement(r,j));if(q){var a=r;a.className?(a.className=a.className.replace(n,""),a.className+=" "+q):a.className=q}});return}g.commands.support(k)?e(p,k,j||"DIV",q):(r=p.createElement(j||"DIV"),q&&(r.className=q),f(g,r))}},state:function(a,b,c,d,e){c="string"===typeof c?c.toUpperCase():c;a=a.selection.getSelectedNode();return h.getParentElement(a,{nodeName:c,className:d,classRegExp:e})},value:function(){}}})(wysihtml5);
(function(b){function c(c,f,h){var i=c+":"+f;if(!d[i]){var g=d,k=b.selection.HTMLApplier,j=a[c],c=j?[c.toLowerCase(),j.toLowerCase()]:[c.toLowerCase()];g[i]=new k(c,f,h,!0)}return d[i]}var a={strong:"b",em:"i",b:"strong",i:"em"},d={};b.commands.formatInline={exec:function(a,b,d,i,g){b=a.selection.getRange();if(!b)return!1;c(d,i,g).toggleRange(b);a.selection.setSelection(b)},state:function(d,f,h,i,g){var f=d.doc,k=a[h]||h;if(!b.dom.hasElementWithTagName(f,h)&&!b.dom.hasElementWithTagName(f,k)||i&&
!b.dom.hasElementWithClassName(f,i))return!1;d=d.selection.getRange();return!d?!1:c(h,i,g).isAppliedToRange(d)},value:function(){}}})(wysihtml5);(function(b){b.commands.insertHTML={exec:function(b,a,d){b.commands.support(a)?b.doc.execCommand(a,!1,d):b.selection.insertHTML(d)},state:function(){return!1},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertImage={exec:function(c,a,d){var d="object"===typeof d?d:{src:d},e=c.doc,a=this.state(c),f;if(a)c.selection.setBefore(a),d=a.parentNode,d.removeChild(a),b.dom.removeEmptyTextNodes(d),"A"===d.nodeName&&!d.firstChild&&(c.selection.setAfter(d),d.parentNode.removeChild(d)),b.quirks.redraw(c.element);else{a=e.createElement("IMG");for(f in d)a[f]=d[f];c.selection.insertNode(a);b.browser.hasProblemsSettingCaretAfterImg()?(d=e.createTextNode(b.INVISIBLE_SPACE),c.selection.insertNode(d),
c.selection.setAfter(d)):c.selection.setAfter(a)}},state:function(c){var a;if(!b.dom.hasElementWithTagName(c.doc,"IMG"))return!1;a=c.selection.getSelectedNode();if(!a)return!1;if("IMG"===a.nodeName)return a;if(a.nodeType!==b.ELEMENT_NODE)return!1;a=c.selection.getText();if(a=b.lang.string(a).trim())return!1;c=c.selection.getNodes(b.ELEMENT_NODE,function(a){return"IMG"===a.nodeName});return 1!==c.length?!1:c[0]},value:function(b){return(b=this.state(b))&&b.src}}})(wysihtml5);
(function(b){var c="<br>"+(b.browser.needsSpaceAfterLineBreak()?" ":"");b.commands.insertLineBreak={exec:function(a,d){a.commands.support(d)?(a.doc.execCommand(d,!1,null),b.browser.autoScrollsToCaret()||a.selection.scrollIntoView()):a.commands.exec("insertHTML",c)},state:function(){return!1},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertOrderedList={exec:function(c,a){var d=c.doc,e,f,h;c.commands.support(a)?d.execCommand(a,!1,null):(e=c.selection.getSelectedNode(),(h=b.dom.getParentElement(e,{nodeName:["UL","OL"]},4))?c.selection.executeAndRestoreSimple(function(){"OL"===h.nodeName?b.dom.resolveList(h):("UL"===h.nodeName||"MENU"===h.nodeName)&&b.dom.renameElement(h,"ol")}):(f=d.createElement("span"),c.selection.surround(f),d=""===f.innerHTML||f.innerHTML===b.INVISIBLE_SPACE,c.selection.executeAndRestoreSimple(function(){h=
b.dom.convertToList(f,"ol")}),d&&c.selection.selectNode(h.querySelector("li"))))},state:function(b,a){try{return b.doc.queryCommandState(a)}catch(d){return!1}},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertUnorderedList={exec:function(c,a){var d=c.doc,e,f,h;c.commands.support(a)?d.execCommand(a,!1,null):(e=c.selection.getSelectedNode(),(h=b.dom.getParentElement(e,{nodeName:["UL","OL"]}))?c.selection.executeAndRestoreSimple(function(){"UL"===h.nodeName?b.dom.resolveList(h):("OL"===h.nodeName||"MENU"===h.nodeName)&&b.dom.renameElement(h,"ul")}):(f=d.createElement("span"),c.selection.surround(f),d=""===f.innerHTML||f.innerHTML===b.INVISIBLE_SPACE,c.selection.executeAndRestoreSimple(function(){h=
b.dom.convertToList(f,"ul")}),d&&c.selection.selectNode(h.querySelector("li"))))},state:function(b,a){try{return b.doc.queryCommandState(a)}catch(d){return!1}},value:function(){}}})(wysihtml5);(function(b){b.commands.italic={exec:function(c,a){return b.commands.formatInline.exec(c,a,"i")},state:function(c,a){return b.commands.formatInline.state(c,a,"i")},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyCenter={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-center",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-center",c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyLeft={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-left",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-left",c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyRight={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-right",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-right",c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-decoration-underline/g;b.commands.underline={exec:function(a,d){return b.commands.formatInline.exec(a,d,"span","wysiwyg-text-decoration-underline",c)},state:function(a,d){return b.commands.formatInline.state(a,d,"span","wysiwyg-text-decoration-underline",c)},value:function(){}}})(wysihtml5);
(function(b){var c='<span id="_wysihtml5-undo" class="_wysihtml5-temp">'+b.INVISIBLE_SPACE+"</span>",a='<span id="_wysihtml5-redo" class="_wysihtml5-temp">'+b.INVISIBLE_SPACE+"</span>",d=b.dom;b.UndoManager=b.lang.Dispatcher.extend({constructor:function(a){this.editor=a;this.composer=a.composer;this.element=this.composer.element;this.history=[this.composer.getValue()];this.position=1;this.composer.commands.support("insertHTML")&&this._observe()},_observe:function(){var e=this,f=this.composer.sandbox.getDocument(),
h;d.observe(this.element,"keydown",function(a){if(!(a.altKey||!a.ctrlKey&&!a.metaKey)){var b=a.keyCode,c=90===b&&a.shiftKey||89===b;90===b&&!a.shiftKey?(e.undo(),a.preventDefault()):c&&(e.redo(),a.preventDefault())}});d.observe(this.element,"keydown",function(a){a=a.keyCode;a!==h&&(h=a,(8===a||46===a)&&e.transact())});if(b.browser.hasUndoInContextMenu()){var i,g,k=function(){for(var a;a=f.querySelector("._wysihtml5-temp");)a.parentNode.removeChild(a);clearInterval(i)};d.observe(this.element,"contextmenu",
function(){k();e.composer.selection.executeAndRestoreSimple(function(){e.element.lastChild&&e.composer.selection.setAfter(e.element.lastChild);f.execCommand("insertHTML",!1,c);f.execCommand("insertHTML",!1,a);f.execCommand("undo",!1,null)});i=setInterval(function(){f.getElementById("_wysihtml5-redo")?(k(),e.redo()):f.getElementById("_wysihtml5-undo")||(k(),e.undo())},400);g||(g=!0,d.observe(document,"mousedown",k),d.observe(f,["mousedown","paste","cut","copy"],k))})}this.editor.observe("newword:composer",
function(){e.transact()}).observe("beforecommand:composer",function(){e.transact()})},transact:function(){var a=this.history[this.position-1],b=this.composer.getValue();if(b!=a){if(40<(this.history.length=this.position))this.history.shift(),this.position--;this.position++;this.history.push(b)}},undo:function(){this.transact();1>=this.position||(this.set(this.history[--this.position-1]),this.editor.fire("undo:composer"))},redo:function(){this.position>=this.history.length||(this.set(this.history[++this.position-
1]),this.editor.fire("redo:composer"))},set:function(a){this.composer.setValue(a);this.editor.focus(!0)}})})(wysihtml5);
wysihtml5.views.View=Base.extend({constructor:function(b,c,a){this.parent=b;this.element=c;this.config=a;this._observeViewChange()},_observeViewChange:function(){var b=this;this.parent.observe("beforeload",function(){b.parent.observe("change_view",function(c){c===b.name?(b.parent.currentView=b,b.show(),setTimeout(function(){b.focus()},0)):b.hide()})})},focus:function(){if(this.element.ownerDocument.querySelector(":focus")!==this.element)try{this.element.focus()}catch(b){}},hide:function(){this.element.style.display=
"none"},show:function(){this.element.style.display=""},disable:function(){this.element.setAttribute("disabled","disabled")},enable:function(){this.element.removeAttribute("disabled")}});
(function(b){var c=b.dom,a=b.browser;b.views.Composer=b.views.View.extend({name:"composer",CARET_HACK:"<br>",constructor:function(a,b,c){this.base(a,b,c);this.textarea=this.parent.textarea;this._initSandbox()},clear:function(){this.element.innerHTML=a.displaysCaretInEmptyContentEditableCorrectly()?"":this.CARET_HACK},getValue:function(a){var c=this.isEmpty()?"":b.quirks.getCorrectInnerHTML(this.element);a&&(c=this.parent.parse(c));return c=b.lang.string(c).replace(b.INVISIBLE_SPACE).by("")},setValue:function(a,
b){b&&(a=this.parent.parse(a));this.element.innerHTML=a},show:function(){this.iframe.style.display=this._displayStyle||"";this.disable();this.enable()},hide:function(){this._displayStyle=c.getStyle("display").from(this.iframe);"none"===this._displayStyle&&(this._displayStyle=null);this.iframe.style.display="none"},disable:function(){this.element.removeAttribute("contentEditable");this.base()},enable:function(){this.element.setAttribute("contentEditable","true");this.base()},focus:function(a){b.browser.doesAsyncFocus()&&
this.hasPlaceholderSet()&&this.clear();this.base();var c=this.element.lastChild;a&&c&&("BR"===c.nodeName?this.selection.setBefore(this.element.lastChild):this.selection.setAfter(this.element.lastChild))},getTextContent:function(){return c.getTextContent(this.element)},hasPlaceholderSet:function(){return this.getTextContent()==this.textarea.element.getAttribute("placeholder")},isEmpty:function(){var a=this.element.innerHTML;return""===a||a===this.CARET_HACK||this.hasPlaceholderSet()||""===this.getTextContent()&&
!this.element.querySelector("blockquote, ul, ol, img, embed, object, table, iframe, svg, video, audio, button, input, select, textarea")},_initSandbox:function(){var a=this;this.sandbox=new c.Sandbox(function(){a._create()},{stylesheets:this.config.stylesheets});this.iframe=this.sandbox.getIframe();var b=document.createElement("input");b.type="hidden";b.name="_wysihtml5_mode";b.value=1;var f=this.textarea.element;c.insert(this.iframe).after(f);c.insert(b).after(f)},_create:function(){var d=this;this.doc=
this.sandbox.getDocument();this.element=this.doc.body;this.textarea=this.parent.textarea;this.element.innerHTML=this.textarea.getValue(!0);this.enable();this.selection=new b.Selection(this.parent);this.commands=new b.Commands(this.parent);c.copyAttributes("className,spellcheck,title,lang,dir,accessKey".split(",")).from(this.textarea.element).to(this.element);c.addClass(this.element,this.config.composerClassName);this.config.style&&this.style();this.observe();var e=this.config.name;e&&(c.addClass(this.element,
e),c.addClass(this.iframe,e));(e="string"===typeof this.config.placeholder?this.config.placeholder:this.textarea.element.getAttribute("placeholder"))&&c.simulatePlaceholder(this.parent,this,e);this.commands.exec("styleWithCSS",!1);this._initAutoLinking();this._initObjectResizing();this._initUndoManager();(this.textarea.element.hasAttribute("autofocus")||document.querySelector(":focus")==this.textarea.element)&&setTimeout(function(){d.focus()},100);b.quirks.insertLineBreakOnReturn(this);a.clearsContentEditableCorrectly()||
b.quirks.ensureProperClearing(this);a.clearsListsInContentEditableCorrectly()||b.quirks.ensureProperClearingOfLists(this);this.initSync&&this.config.sync&&this.initSync();this.textarea.hide();this.parent.fire("beforeload").fire("load")},_initAutoLinking:function(){var d=this,e=a.canDisableAutoLinking(),f=a.doesAutoLinkingInContentEditable();e&&this.commands.exec("autoUrlDetect",!1);if(this.config.autoLink){(!f||f&&e)&&this.parent.observe("newword:composer",function(){d.selection.executeAndRestore(function(a,
b){c.autoLink(b.parentNode)})});var h=this.sandbox.getDocument().getElementsByTagName("a"),i=c.autoLink.URL_REG_EXP,g=function(a){a=b.lang.string(c.getTextContent(a)).trim();"www."===a.substr(0,4)&&(a="http://"+a);return a};c.observe(this.element,"keydown",function(a){if(h.length){var a=d.selection.getSelectedNode(a.target.ownerDocument),b=c.getParentElement(a,{nodeName:"A"},4),e;b&&(e=g(b),setTimeout(function(){var a=g(b);a!==e&&a.match(i)&&b.setAttribute("href",a)},0))}})}},_initObjectResizing:function(){var d=
["width","height"],e=d.length,f=this.element;this.commands.exec("enableObjectResizing",this.config.allowObjectResizing);this.config.allowObjectResizing?a.supportsEvent("resizeend")&&c.observe(f,"resizeend",function(a){for(var a=a.target||a.srcElement,c=a.style,g=0,k;g<e;g++)k=d[g],c[k]&&(a.setAttribute(k,parseInt(c[k],10)),c[k]="");b.quirks.redraw(f)}):a.supportsEvent("resizestart")&&c.observe(f,"resizestart",function(a){a.preventDefault()})},_initUndoManager:function(){new b.UndoManager(this.parent)}})})(wysihtml5);
(function(b){var c=b.dom,a=document,d=window,e=a.createElement("div"),f="background-color,color,cursor,font-family,font-size,font-style,font-variant,font-weight,line-height,letter-spacing,text-align,text-decoration,text-indent,text-rendering,word-break,word-wrap,word-spacing".split(","),h="background-color,border-collapse,border-bottom-color,border-bottom-style,border-bottom-width,border-left-color,border-left-style,border-left-width,border-right-color,border-right-style,border-right-width,border-top-color,border-top-style,border-top-width,clear,display,float,margin-bottom,margin-left,margin-right,margin-top,outline-color,outline-offset,outline-width,outline-style,padding-left,padding-right,padding-top,padding-bottom,position,top,left,right,bottom,z-index,vertical-align,text-align,-webkit-box-sizing,-moz-box-sizing,-ms-box-sizing,box-sizing,-webkit-box-shadow,-moz-box-shadow,-ms-box-shadow,box-shadow,-webkit-border-top-right-radius,-moz-border-radius-topright,border-top-right-radius,-webkit-border-bottom-right-radius,-moz-border-radius-bottomright,border-bottom-right-radius,-webkit-border-bottom-left-radius,-moz-border-radius-bottomleft,border-bottom-left-radius,-webkit-border-top-left-radius,-moz-border-radius-topleft,border-top-left-radius,width,height".split(","),
i="width,height,top,left,right,bottom".split(","),g=["html { height: 100%; }","body { min-height: 100%; padding: 0; margin: 0; margin-top: -1px; padding-top: 1px; }","._wysihtml5-temp { display: none; }",b.browser.isGecko?"body.placeholder { color: graytext !important; }":"body.placeholder { color: #a9a9a9 !important; }","body[disabled] { background-color: #eee !important; color: #999 !important; cursor: default !important; }","img:-moz-broken { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }"],
k=function(b){if(b.setActive)try{b.setActive()}catch(e){}else{var f=b.style,g=a.documentElement.scrollTop||a.body.scrollTop,h=a.documentElement.scrollLeft||a.body.scrollLeft,f={position:f.position,top:f.top,left:f.left,WebkitUserSelect:f.WebkitUserSelect};c.setStyles({position:"absolute",top:"-99999px",left:"-99999px",WebkitUserSelect:"none"}).on(b);b.focus();c.setStyles(f).on(b);d.scrollTo&&d.scrollTo(h,g)}};b.views.Composer.prototype.style=function(){var j=this,q=a.querySelector(":focus"),n=this.textarea.element,
p=n.hasAttribute("placeholder"),r=p&&n.getAttribute("placeholder");this.focusStylesHost=this.focusStylesHost||e.cloneNode(!1);this.blurStylesHost=this.blurStylesHost||e.cloneNode(!1);p&&n.removeAttribute("placeholder");n===q&&n.blur();c.copyStyles(h).from(n).to(this.iframe).andTo(this.blurStylesHost);c.copyStyles(f).from(n).to(this.element).andTo(this.blurStylesHost);c.insertCSS(g).into(this.element.ownerDocument);k(n);c.copyStyles(h).from(n).to(this.focusStylesHost);c.copyStyles(f).from(n).to(this.focusStylesHost);
var m=b.lang.array(h).without(["display"]);q?q.focus():n.blur();p&&n.setAttribute("placeholder",r);b.browser.hasCurrentStyleProperty()||c.observe(d,"resize",function(){var a=c.getStyle("display").from(n);n.style.display="";c.copyStyles(i).from(n).to(j.iframe).andTo(j.focusStylesHost).andTo(j.blurStylesHost);n.style.display=a});this.parent.observe("focus:composer",function(){c.copyStyles(m).from(j.focusStylesHost).to(j.iframe);c.copyStyles(f).from(j.focusStylesHost).to(j.element)});this.parent.observe("blur:composer",
function(){c.copyStyles(m).from(j.blurStylesHost).to(j.iframe);c.copyStyles(f).from(j.blurStylesHost).to(j.element)});return this}})(wysihtml5);
(function(b){var c=b.dom,a=b.browser,d={66:"bold",73:"italic",85:"underline"};b.views.Composer.prototype.observe=function(){var e=this,f=this.getValue(),h=this.sandbox.getIframe(),i=this.element,g=a.supportsEventsInIframeCorrectly()?i:this.sandbox.getWindow(),k=a.supportsEvent("drop")?["drop","paste"]:["dragdrop","paste"];c.observe(h,"DOMNodeRemoved",function(){clearInterval(j);e.parent.fire("destroy:composer")});var j=setInterval(function(){c.contains(document.documentElement,h)||(clearInterval(j),
e.parent.fire("destroy:composer"))},250);c.observe(g,"focus",function(){e.parent.fire("focus").fire("focus:composer");setTimeout(function(){f=e.getValue()},0)});c.observe(g,"blur",function(){f!==e.getValue()&&e.parent.fire("change").fire("change:composer");e.parent.fire("blur").fire("blur:composer")});b.browser.isIos()&&c.observe(i,"blur",function(){var a=i.ownerDocument.createElement("input"),b=document.documentElement.scrollTop||document.body.scrollTop,c=document.documentElement.scrollLeft||document.body.scrollLeft;
try{e.selection.insertNode(a)}catch(d){i.appendChild(a)}a.focus();a.parentNode.removeChild(a);window.scrollTo(c,b)});c.observe(i,"dragenter",function(){e.parent.fire("unset_placeholder")});a.firesOnDropOnlyWhenOnDragOverIsCancelled()&&c.observe(i,["dragover","dragenter"],function(a){a.preventDefault()});c.observe(i,k,function(b){var c=b.dataTransfer,d;c&&a.supportsDataTransfer()&&(d=c.getData("text/html")||c.getData("text/plain"));d?(i.focus(),e.commands.exec("insertHTML",d),e.parent.fire("paste").fire("paste:composer"),
b.stopPropagation(),b.preventDefault()):setTimeout(function(){e.parent.fire("paste").fire("paste:composer")},0)});c.observe(i,"keyup",function(a){a=a.keyCode;(a===b.SPACE_KEY||a===b.ENTER_KEY)&&e.parent.fire("newword:composer")});this.parent.observe("paste:composer",function(){setTimeout(function(){e.parent.fire("newword:composer")},0)});a.canSelectImagesInContentEditable()||c.observe(i,"mousedown",function(a){var b=a.target;"IMG"===b.nodeName&&(e.selection.selectNode(b),a.preventDefault())});c.observe(i,
"keydown",function(a){var b=d[a.keyCode];if((a.ctrlKey||a.metaKey)&&b)e.commands.exec(b),a.preventDefault()});c.observe(i,"keydown",function(a){var c=e.selection.getSelectedNode(!0),d=a.keyCode;if(c&&"IMG"===c.nodeName&&(d===b.BACKSPACE_KEY||d===b.DELETE_KEY))d=c.parentNode,d.removeChild(c),"A"===d.nodeName&&!d.firstChild&&d.parentNode.removeChild(d),setTimeout(function(){b.quirks.redraw(i)},0),a.preventDefault()});var q={IMG:"Image: ",A:"Link: "};c.observe(i,"mouseover",function(a){var a=a.target,
b=a.nodeName;"A"!==b&&"IMG"!==b||(b=q[b]+(a.getAttribute("href")||a.getAttribute("src")),a.setAttribute("title",b))})}})(wysihtml5);
(function(b){b.views.Synchronizer=Base.extend({constructor:function(b,a,d){this.editor=b;this.textarea=a;this.composer=d;this._observe()},fromComposerToTextarea:function(c){this.textarea.setValue(b.lang.string(this.composer.getValue()).trim(),c)},fromTextareaToComposer:function(b){var a=this.textarea.getValue();a?this.composer.setValue(a,b):(this.composer.clear(),this.editor.fire("set_placeholder"))},sync:function(b){"textarea"===this.editor.currentView.name?this.fromTextareaToComposer(b):this.fromComposerToTextarea(b)},
_observe:function(){var c,a=this,d=this.textarea.element.form,e=function(){c=setInterval(function(){a.fromComposerToTextarea()},400)},f=function(){clearInterval(c);c=null};e();d&&(b.dom.observe(d,"submit",function(){a.sync(!0)}),b.dom.observe(d,"reset",function(){setTimeout(function(){a.fromTextareaToComposer()},0)}));this.editor.observe("change_view",function(b){if(b==="composer"&&!c){a.fromTextareaToComposer(true);e()}else if(b==="textarea"){a.fromComposerToTextarea(true);f()}});this.editor.observe("destroy:composer",
f)}})})(wysihtml5);
wysihtml5.views.Textarea=wysihtml5.views.View.extend({name:"textarea",constructor:function(b,c,a){this.base(b,c,a);this._observe()},clear:function(){this.element.value=""},getValue:function(b){var c=this.isEmpty()?"":this.element.value;b&&(c=this.parent.parse(c));return c},setValue:function(b,c){c&&(b=this.parent.parse(b));this.element.value=b},hasPlaceholderSet:function(){var b=wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),c=this.element.getAttribute("placeholder")||null,a=this.element.value;
return b&&!a||a===c},isEmpty:function(){return!wysihtml5.lang.string(this.element.value).trim()||this.hasPlaceholderSet()},_observe:function(){var b=this.element,c=this.parent,a={focusin:"focus",focusout:"blur"},d=wysihtml5.browser.supportsEvent("focusin")?["focusin","focusout","change"]:["focus","blur","change"];c.observe("beforeload",function(){wysihtml5.dom.observe(b,d,function(b){b=a[b.type]||b.type;c.fire(b).fire(b+":textarea")});wysihtml5.dom.observe(b,["paste","drop"],function(){setTimeout(function(){c.fire("paste").fire("paste:textarea")},
0)})})}});
(function(b){var c=b.dom;b.toolbar.Dialog=b.lang.Dispatcher.extend({constructor:function(a,b){this.link=a;this.container=b},_observe:function(){if(!this._observed){var a=this,d=function(b){var c=a._serialize();c==a.elementToChange?a.fire("edit",c):a.fire("save",c);a.hide();b.preventDefault();b.stopPropagation()};c.observe(a.link,"click",function(){c.hasClass(a.link,"wysihtml5-command-dialog-opened")&&setTimeout(function(){a.hide()},0)});c.observe(this.container,"keydown",function(c){var e=c.keyCode;
e===b.ENTER_KEY&&d(c);e===b.ESCAPE_KEY&&a.hide()});c.delegate(this.container,"[data-wysihtml5-dialog-action=save]","click",d);c.delegate(this.container,"[data-wysihtml5-dialog-action=cancel]","click",function(b){a.fire("cancel");a.hide();b.preventDefault();b.stopPropagation()});for(var e=this.container.querySelectorAll("input, select, textarea"),f=0,h=e.length,i=function(){clearInterval(a.interval)};f<h;f++)c.observe(e[f],"change",i);this._observed=!0}},_serialize:function(){for(var a=this.elementToChange||
{},b=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),c=b.length,f=0;f<c;f++)a[b[f].getAttribute("data-wysihtml5-dialog-field")]=b[f].value;return a},_interpolate:function(a){for(var b,c,f=document.querySelector(":focus"),h=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),i=h.length,g=0;g<i;g++)b=h[g],b!==f&&!(a&&"hidden"===b.type)&&(c=b.getAttribute("data-wysihtml5-dialog-field"),c=this.elementToChange?this.elementToChange[c]||"":b.defaultValue,b.value=c)},show:function(a){var b=
this,e=this.container.querySelector("input, select, textarea");this.elementToChange=a;this._observe();this._interpolate();a&&(this.interval=setInterval(function(){b._interpolate(!0)},500));c.addClass(this.link,"wysihtml5-command-dialog-opened");this.container.style.display="";this.fire("show");if(e&&!a)try{e.focus()}catch(f){}},hide:function(){clearInterval(this.interval);this.elementToChange=null;c.removeClass(this.link,"wysihtml5-command-dialog-opened");this.container.style.display="none";this.fire("hide")}})})(wysihtml5);
(function(b){var c=b.dom,a={position:"relative"},d={left:0,margin:0,opacity:0,overflow:"hidden",padding:0,position:"absolute",top:0,zIndex:1},e={cursor:"inherit",fontSize:"50px",height:"50px",marginTop:"-25px",outline:0,padding:0,position:"absolute",right:"-4px",top:"50%"},f={"x-webkit-speech":"",speech:""};b.toolbar.Speech=function(h,i){var g=document.createElement("input");if(b.browser.supportsSpeechApiOn(g)){var k=document.createElement("div");b.lang.object(d).merge({width:i.offsetWidth+"px",height:i.offsetHeight+
"px"});c.insert(g).into(k);c.insert(k).into(i);c.setStyles(e).on(g);c.setAttributes(f).on(g);c.setStyles(d).on(k);c.setStyles(a).on(i);c.observe(g,"onwebkitspeechchange"in g?"webkitspeechchange":"speechchange",function(){h.execCommand("insertText",g.value);g.value=""});c.observe(g,"click",function(a){c.hasClass(i,"wysihtml5-command-disabled")&&a.preventDefault();a.stopPropagation()})}else i.style.display="none"}})(wysihtml5);
(function(b){var c=b.dom;b.toolbar.Toolbar=Base.extend({constructor:function(a,c){this.editor=a;this.container="string"===typeof c?document.getElementById(c):c;this.composer=a.composer;this._getLinks("command");this._getLinks("action");this._observe();this.show();for(var e=this.container.querySelectorAll("[data-wysihtml5-command=insertSpeech]"),f=e.length,h=0;h<f;h++)new b.toolbar.Speech(this,e[h])},_getLinks:function(a){for(var c=this[a+"Links"]=b.lang.array(this.container.querySelectorAll("[data-wysihtml5-"+
a+"]")).get(),e=c.length,f=0,h=this[a+"Mapping"]={},i,g,k,j;f<e;f++)i=c[f],g=i.getAttribute("data-wysihtml5-"+a),k=i.getAttribute("data-wysihtml5-"+a+"-value"),j=this._getDialog(i,g),h[g+":"+k]={link:i,name:g,value:k,dialog:j,state:!1}},_getDialog:function(a,c){var e=this,f=this.container.querySelector("[data-wysihtml5-dialog='"+c+"']"),h,i;f&&(h=new b.toolbar.Dialog(a,f),h.observe("show",function(){i=e.composer.selection.getBookmark();e.editor.fire("show:dialog",{command:c,dialogContainer:f,commandLink:a})}),
h.observe("save",function(b){i&&e.composer.selection.setBookmark(i);e._execCommand(c,b);e.editor.fire("save:dialog",{command:c,dialogContainer:f,commandLink:a})}),h.observe("cancel",function(){e.editor.focus(!1);e.editor.fire("cancel:dialog",{command:c,dialogContainer:f,commandLink:a})}));return h},execCommand:function(a,b){if(!this.commandsDisabled){var c=this.commandMapping[a+":"+b];c&&c.dialog&&!c.state?c.dialog.show():this._execCommand(a,b)}},_execCommand:function(a,b){this.editor.focus(!1);this.composer.commands.exec(a,
b);this._updateLinkStates()},execAction:function(a){var b=this.editor;switch(a){case "change_view":b.currentView===b.textarea?b.fire("change_view","composer"):b.fire("change_view","textarea")}},_observe:function(){for(var a=this,b=this.editor,e=this.container,f=this.commandLinks.concat(this.actionLinks),h=f.length,i=0;i<h;i++)c.setAttributes({href:"javascript:;",unselectable:"on"}).on(f[i]);c.delegate(e,"[data-wysihtml5-command]","mousedown",function(a){a.preventDefault()});c.delegate(e,"[data-wysihtml5-command]",
"click",function(b){var c=this.getAttribute("data-wysihtml5-command"),d=this.getAttribute("data-wysihtml5-command-value");a.execCommand(c,d);b.preventDefault()});c.delegate(e,"[data-wysihtml5-action]","click",function(b){var c=this.getAttribute("data-wysihtml5-action");a.execAction(c);b.preventDefault()});b.observe("focus:composer",function(){a.bookmark=null;clearInterval(a.interval);a.interval=setInterval(function(){a._updateLinkStates()},500)});b.observe("blur:composer",function(){clearInterval(a.interval)});
b.observe("destroy:composer",function(){clearInterval(a.interval)});b.observe("change_view",function(b){setTimeout(function(){a.commandsDisabled="composer"!==b;a._updateLinkStates();a.commandsDisabled?c.addClass(e,"wysihtml5-commands-disabled"):c.removeClass(e,"wysihtml5-commands-disabled")},0)})},_updateLinkStates:function(){var a=this.commandMapping,d,e,f;for(d in a)if(f=a[d],this.commandsDisabled?(e=!1,c.removeClass(f.link,"wysihtml5-command-active"),f.dialog&&f.dialog.hide()):(e=this.composer.commands.state(f.name,
f.value),b.lang.object(e).isArray()&&(e=1===e.length?e[0]:!0),c.removeClass(f.link,"wysihtml5-command-disabled")),f.state!==e)(f.state=e)?(c.addClass(f.link,"wysihtml5-command-active"),f.dialog&&("object"===typeof e?f.dialog.show(e):f.dialog.hide())):(c.removeClass(f.link,"wysihtml5-command-active"),f.dialog&&f.dialog.hide())},show:function(){this.container.style.display=""},hide:function(){this.container.style.display="none"}})})(wysihtml5);
(function(b){var c={name:void 0,style:!0,toolbar:void 0,autoLink:!0,parserRules:{tags:{br:{},span:{},div:{},p:{}},classes:{}},parser:b.dom.parse,composerClassName:"wysihtml5-editor",bodyClassName:"wysihtml5-supported",stylesheets:[],placeholderText:void 0,allowObjectResizing:!0,supportTouchDevices:!0};b.Editor=b.lang.Dispatcher.extend({constructor:function(a,d){this.textareaElement="string"===typeof a?document.getElementById(a):a;this.config=b.lang.object({}).merge(c).merge(d).get();this.currentView=
this.textarea=new b.views.Textarea(this,this.textareaElement,this.config);this._isCompatible=b.browser.supported();if(!this._isCompatible||!this.config.supportTouchDevices&&b.browser.isTouchDevice()){var e=this;setTimeout(function(){e.fire("beforeload").fire("load")},0)}else{b.dom.addClass(document.body,this.config.bodyClassName);this.currentView=this.composer=new b.views.Composer(this,this.textareaElement,this.config);"function"===typeof this.config.parser&&this._initParser();this.observe("beforeload",
function(){this.synchronizer=new b.views.Synchronizer(this,this.textarea,this.composer);this.config.toolbar&&(this.toolbar=new b.toolbar.Toolbar(this,this.config.toolbar))});try{console.log("Heya! This page is using wysihtml5 for rich text editing. Check out https://github.com/xing/wysihtml5")}catch(f){}}},isCompatible:function(){return this._isCompatible},clear:function(){this.currentView.clear();return this},getValue:function(a){return this.currentView.getValue(a)},setValue:function(a,b){if(!a)return this.clear();
this.currentView.setValue(a,b);return this},focus:function(a){this.currentView.focus(a);return this},disable:function(){this.currentView.disable();return this},enable:function(){this.currentView.enable();return this},isEmpty:function(){return this.currentView.isEmpty()},hasPlaceholderSet:function(){return this.currentView.hasPlaceholderSet()},parse:function(a){var c=this.config.parser(a,this.config.parserRules,this.composer.sandbox.getDocument(),!0);"object"===typeof a&&b.quirks.redraw(a);return c},
_initParser:function(){this.observe("paste:composer",function(){var a=this;a.composer.selection.executeAndRestore(function(){b.quirks.cleanPastedHTML(a.composer.element);a.parse(a.composer.element)},!0)});this.observe("paste:textarea",function(){this.textarea.setValue(this.parse(this.textarea.getValue()))})}})})(wysihtml5);
/**
* Full HTML5 compatibility rule set
* These rules define which tags and css classes are supported and which tags should be specially treated.
*
* Examples based on this rule set:
*
* <a href="http://foobar.com">foo</a>
* ... becomes ...
* <a href="http://foobar.com" target="_blank" rel="nofollow">foo</a>
*
* <img align="left" src="http://foobar.com/image.png">
* ... becomes ...
* <img class="wysiwyg-float-left" src="http://foobar.com/image.png" alt="">
*
* <div>foo<script>alert(document.cookie)</script></div>
* ... becomes ...
* <div>foo</div>
*
* <marquee>foo</marquee>
* ... becomes ...
* <span>foo</marquee>
*
* foo <br clear="both"> bar
* ... becomes ...
* foo <br class="wysiwyg-clear-both"> bar
*
* <div>hello <iframe src="http://google.com"></iframe></div>
* ... becomes ...
* <div>hello </div>
*
* <center>hello</center>
* ... becomes ...
* <div class="wysiwyg-text-align-center">hello</div>
*/
var wysihtml5ParserRules = {
/**
* CSS Class white-list
* Following css classes won't be removed when parsed by the wysihtml5 html parser
*/
"classes": {
"wysiwyg-clear-both": 1,
"wysiwyg-clear-left": 1,
"wysiwyg-clear-right": 1,
"wysiwyg-color-aqua": 1,
"wysiwyg-color-black": 1,
"wysiwyg-color-blue": 1,
"wysiwyg-color-fuchsia": 1,
"wysiwyg-color-gray": 1,
"wysiwyg-color-green": 1,
"wysiwyg-color-lime": 1,
"wysiwyg-color-maroon": 1,
"wysiwyg-color-navy": 1,
"wysiwyg-color-olive": 1,
"wysiwyg-color-purple": 1,
"wysiwyg-color-red": 1,
"wysiwyg-color-silver": 1,
"wysiwyg-color-teal": 1,
"wysiwyg-color-white": 1,
"wysiwyg-color-yellow": 1,
"wysiwyg-float-left": 1,
"wysiwyg-float-right": 1,
"wysiwyg-font-size-large": 1,
"wysiwyg-font-size-larger": 1,
"wysiwyg-font-size-medium": 1,
"wysiwyg-font-size-small": 1,
"wysiwyg-font-size-smaller": 1,
"wysiwyg-font-size-x-large": 1,
"wysiwyg-font-size-x-small": 1,
"wysiwyg-font-size-xx-large": 1,
"wysiwyg-font-size-xx-small": 1,
"wysiwyg-text-align-center": 1,
"wysiwyg-text-align-justify": 1,
"wysiwyg-text-align-left": 1,
"wysiwyg-text-align-right": 1
},
/**
* Tag list
*
* Following options are available:
*
* - add_class: converts and deletes the given HTML4 attribute (align, clear, ...) via the given method to a css class
* The following methods are implemented in wysihtml5.dom.parse:
* - align_text: converts align attribute values (right/left/center/justify) to their corresponding css class "wysiwyg-text-align-*")
<p align="center">foo</p> ... becomes ... <p> class="wysiwyg-text-align-center">foo</p>
* - clear_br: converts clear attribute values left/right/all/both to their corresponding css class "wysiwyg-clear-*"
* <br clear="all"> ... becomes ... <br class="wysiwyg-clear-both">
* - align_img: converts align attribute values (right/left) on <img> to their corresponding css class "wysiwyg-float-*"
*
* - remove: removes the element and it's content
*
* - rename_tag: renames the element to the given tag
*
* - set_class: adds the given class to the element (note: make sure that the class is in the "classes" white list above)
*
* - set_attributes: sets/overrides the given attributes
*
* - check_attributes: checks the given HTML attribute via the given method
* - url: checks whether the given string is an url, deletes the attribute if not
* - alt: strips unwanted characters. if the attribute is not set, then it gets set (to ensure valid and compatible HTML)
* - numbers: ensures that the attribute only contains numeric characters
*/
"tags": {
"tr": {
"add_class": {
"align": "align_text"
}
},
"strike": {
"remove": 1
},
"form": {
"rename_tag": "div"
},
"rt": {
"rename_tag": "span"
},
"code": {},
"acronym": {
"rename_tag": "span"
},
"br": {
"add_class": {
"clear": "clear_br"
}
},
"details": {
"rename_tag": "div"
},
"h4": {
"add_class": {
"align": "align_text"
}
},
"em": {},
"title": {
"remove": 1
},
"multicol": {
"rename_tag": "div"
},
"figure": {
"rename_tag": "div"
},
"xmp": {
"rename_tag": "span"
},
"small": {
"rename_tag": "span",
"set_class": "wysiwyg-font-size-smaller"
},
"area": {
"remove": 1
},
"time": {
"rename_tag": "span"
},
"dir": {
"rename_tag": "ul"
},
"bdi": {
"rename_tag": "span"
},
"command": {
"remove": 1
},
"ul": {},
"progress": {
"rename_tag": "span"
},
"dfn": {
"rename_tag": "span"
},
"iframe": {
"remove": 1
},
"figcaption": {
"rename_tag": "div"
},
"a": {
"check_attributes": {
"href": "url"
},
"set_attributes": {
"rel": "nofollow",
"target": "_blank"
}
},
"img": {
"check_attributes": {
"width": "numbers",
"alt": "alt",
"src": "url",
"height": "numbers"
},
"add_class": {
"align": "align_img"
}
},
"rb": {
"rename_tag": "span"
},
"footer": {
"rename_tag": "div"
},
"noframes": {
"remove": 1
},
"abbr": {
"rename_tag": "span"
},
"u": {},
"bgsound": {
"remove": 1
},
"sup": {
"rename_tag": "span"
},
"address": {
"rename_tag": "div"
},
"basefont": {
"remove": 1
},
"nav": {
"rename_tag": "div"
},
"h1": {
"add_class": {
"align": "align_text"
}
},
"head": {
"remove": 1
},
"tbody": {
"add_class": {
"align": "align_text"
}
},
"dd": {
"rename_tag": "div"
},
"s": {
"rename_tag": "span"
},
"li": {},
"td": {
"check_attributes": {
"rowspan": "numbers",
"colspan": "numbers"
},
"add_class": {
"align": "align_text"
}
},
"object": {
"remove": 1
},
"div": {
"add_class": {
"align": "align_text"
}
},
"option": {
"rename_tag": "span"
},
"select": {
"rename_tag": "span"
},
"i": {},
"track": {
"remove": 1
},
"wbr": {
"remove": 1
},
"fieldset": {
"rename_tag": "div"
},
"big": {
"rename_tag": "span",
"set_class": "wysiwyg-font-size-larger"
},
"button": {
"rename_tag": "span"
},
"noscript": {
"remove": 1
},
"svg": {
"remove": 1
},
"input": {
"remove": 1
},
"table": {},
"keygen": {
"remove": 1
},
"h5": {
"add_class": {
"align": "align_text"
}
},
"meta": {
"remove": 1
},
"map": {
"rename_tag": "div"
},
"isindex": {
"remove": 1
},
"mark": {
"rename_tag": "span"
},
"caption": {
"add_class": {
"align": "align_text"
}
},
"tfoot": {
"add_class": {
"align": "align_text"
}
},
"base": {
"remove": 1
},
"video": {
"remove": 1
},
"strong": {},
"canvas": {
"remove": 1
},
"output": {
"rename_tag": "span"
},
"marquee": {
"rename_tag": "span"
},
"b": {},
"q": {
"check_attributes": {
"cite": "url"
}
},
"applet": {
"remove": 1
},
"span": {},
"rp": {
"rename_tag": "span"
},
"spacer": {
"remove": 1
},
"source": {
"remove": 1
},
"aside": {
"rename_tag": "div"
},
"frame": {
"remove": 1
},
"section": {
"rename_tag": "div"
},
"body": {
"rename_tag": "div"
},
"ol": {},
"nobr": {
"rename_tag": "span"
},
"html": {
"rename_tag": "div"
},
"summary": {
"rename_tag": "span"
},
"var": {
"rename_tag": "span"
},
"del": {
"remove": 1
},
"blockquote": {
"check_attributes": {
"cite": "url"
}
},
"style": {
"remove": 1
},
"device": {
"remove": 1
},
"meter": {
"rename_tag": "span"
},
"h3": {
"add_class": {
"align": "align_text"
}
},
"textarea": {
"rename_tag": "span"
},
"embed": {
"remove": 1
},
"hgroup": {
"rename_tag": "div"
},
"font": {
"rename_tag": "span",
"add_class": {
"size": "size_font"
}
},
"tt": {
"rename_tag": "span"
},
"noembed": {
"remove": 1
},
"thead": {
"add_class": {
"align": "align_text"
}
},
"blink": {
"rename_tag": "span"
},
"plaintext": {
"rename_tag": "span"
},
"xml": {
"remove": 1
},
"h6": {
"add_class": {
"align": "align_text"
}
},
"param": {
"remove": 1
},
"th": {
"check_attributes": {
"rowspan": "numbers",
"colspan": "numbers"
},
"add_class": {
"align": "align_text"
}
},
"legend": {
"rename_tag": "span"
},
"hr": {},
"label": {
"rename_tag": "span"
},
"dl": {
"rename_tag": "div"
},
"kbd": {
"rename_tag": "span"
},
"listing": {
"rename_tag": "div"
},
"dt": {
"rename_tag": "span"
},
"nextid": {
"remove": 1
},
"pre": {},
"center": {
"rename_tag": "div",
"set_class": "wysiwyg-text-align-center"
},
"audio": {
"remove": 1
},
"datalist": {
"rename_tag": "span"
},
"samp": {
"rename_tag": "span"
},
"col": {
"remove": 1
},
"article": {
"rename_tag": "div"
},
"cite": {},
"link": {
"remove": 1
},
"script": {
"remove": 1
},
"bdo": {
"rename_tag": "span"
},
"menu": {
"rename_tag": "ul"
},
"colgroup": {
"remove": 1
},
"ruby": {
"rename_tag": "span"
},
"h2": {
"add_class": {
"align": "align_text"
}
},
"ins": {
"rename_tag": "span"
},
"p": {
"add_class": {
"align": "align_text"
}
},
"sub": {
"rename_tag": "span"
},
"comment": {
"remove": 1
},
"frameset": {
"remove": 1
},
"optgroup": {
"rename_tag": "span"
},
"header": {
"rename_tag": "div"
}
}
};
\ No newline at end of file
/*!
angular-xeditable - 0.1.8
Edit-in-place for angular.js
Build date: 2014-01-10
*/
/**
* Angular-xeditable module
*
*/
angular.module('xeditable', [])
/**
* Default options.
*
* @namespace editable-options
*/
//todo: maybe better have editableDefaults, not options...
.value('editableOptions', {
/**
* Theme. Possible values `bs3`, `bs2`, `default`.
*
* @var {string} theme
* @memberOf editable-options
*/
theme: 'default',
/**
* Whether to show buttons for single editalbe element.
* Possible values `right` (default), `no`.
*
* @var {string} buttons
* @memberOf editable-options
*/
buttons: 'right',
/**
* Default value for `blur` attribute of single editable element.
* Can be `cancel|submit|ignore`.
*
* @var {string} blurElem
* @memberOf editable-options
*/
blurElem: 'cancel',
/**
* Default value for `blur` attribute of editable form.
* Can be `cancel|submit|ignore`.
*
* @var {string} blurForm
* @memberOf editable-options
*/
blurForm: 'ignore',
/**
* How input elements get activated. Possible values: `focus|select|none`.
*
* @var {string} activate
* @memberOf editable-options
*/
activate: 'focus'
});
/*
Angular-ui bootstrap datepicker
http://angular-ui.github.io/bootstrap/#/datepicker
*/
angular.module('xeditable').directive('editableBsdate', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableBsdate',
inputTpl: '<input type="text">'
});
}]);
/*
Angular-ui bootstrap editable timepicker
http://angular-ui.github.io/bootstrap/#/timepicker
*/
angular.module('xeditable').directive('editableBstime', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableBstime',
inputTpl: '<timepicker></timepicker>',
render: function() {
this.parent.render.call(this);
// timepicker can't update model when ng-model set directly to it
// see: https://github.com/angular-ui/bootstrap/issues/1141
// so we wrap it into DIV
var div = angular.element('<div class="well well-small" style="display:inline-block;"></div>');
// move ng-model to wrapping div
div.attr('ng-model', this.inputEl.attr('ng-model'));
this.inputEl.removeAttr('ng-model');
// move ng-change to wrapping div
if(this.attrs.eNgChange) {
div.attr('ng-change', this.inputEl.attr('ng-change'));
this.inputEl.removeAttr('ng-change');
}
// wrap
this.inputEl.wrap(div);
}
});
}]);
//checkbox
angular.module('xeditable').directive('editableCheckbox', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableCheckbox',
inputTpl: '<input type="checkbox">',
render: function() {
this.parent.render.call(this);
if(this.attrs.eTitle) {
this.inputEl.wrap('<label></label>');
this.inputEl.after(angular.element('<span></span>').text(this.attrs.eTitle));
}
},
autosubmit: function() {
var self = this;
self.inputEl.bind('change', function() {
setTimeout(function() {
self.scope.$apply(function() {
self.scope.$form.$submit();
});
}, 500);
});
}
});
}]);
// checklist
angular.module('xeditable').directive('editableChecklist', [
'editableDirectiveFactory',
'editableNgOptionsParser',
function(editableDirectiveFactory, editableNgOptionsParser) {
return editableDirectiveFactory({
directiveName: 'editableChecklist',
inputTpl: '<span></span>',
useCopy: true,
render: function() {
this.parent.render.call(this);
var parsed = editableNgOptionsParser(this.attrs.eNgOptions);
var html = '<label ng-repeat="'+parsed.ngRepeat+'">'+
'<input type="checkbox" checklist-model="$parent.$data" checklist-value="'+parsed.locals.valueFn+'">'+
'<span ng-bind="'+parsed.locals.displayFn+'"></span></label>';
this.inputEl.removeAttr('ng-model');
this.inputEl.removeAttr('ng-options');
this.inputEl.html(html);
}
});
}]);
/*
Input types: text|email|tel|number|url|search|color|date|datetime|time|month|week
*/
(function() {
var types = 'text|email|tel|number|url|search|color|date|datetime|time|month|week'.split('|');
//todo: datalist
// generate directives
angular.forEach(types, function(type) {
var directiveName = 'editable'+type.charAt(0).toUpperCase() + type.slice(1);
angular.module('xeditable').directive(directiveName, ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: directiveName,
inputTpl: '<input type="'+type+'">'
});
}]);
});
//`range` is bit specific
angular.module('xeditable').directive('editableRange', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableRange',
inputTpl: '<input type="range" id="range" name="range">',
render: function() {
this.parent.render.call(this);
this.inputEl.after('<output>{{$data}}</output>');
}
});
}]);
}());
// radiolist
angular.module('xeditable').directive('editableRadiolist', [
'editableDirectiveFactory',
'editableNgOptionsParser',
function(editableDirectiveFactory, editableNgOptionsParser) {
return editableDirectiveFactory({
directiveName: 'editableRadiolist',
inputTpl: '<span></span>',
render: function() {
this.parent.render.call(this);
var parsed = editableNgOptionsParser(this.attrs.eNgOptions);
var html = '<label ng-repeat="'+parsed.ngRepeat+'">'+
'<input type="radio" ng-model="$parent.$data" value="{{'+parsed.locals.valueFn+'}}">'+
'<span ng-bind="'+parsed.locals.displayFn+'"></span></label>';
this.inputEl.removeAttr('ng-model');
this.inputEl.removeAttr('ng-options');
this.inputEl.html(html);
},
autosubmit: function() {
var self = this;
self.inputEl.bind('change', function() {
setTimeout(function() {
self.scope.$apply(function() {
self.scope.$form.$submit();
});
}, 500);
});
}
});
}]);
//select
angular.module('xeditable').directive('editableSelect', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableSelect',
inputTpl: '<select></select>',
autosubmit: function() {
var self = this;
self.inputEl.bind('change', function() {
self.scope.$apply(function() {
self.scope.$form.$submit();
});
});
}
});
}]);
//textarea
angular.module('xeditable').directive('editableTextarea', ['editableDirectiveFactory',
function(editableDirectiveFactory) {
return editableDirectiveFactory({
directiveName: 'editableTextarea',
inputTpl: '<textarea></textarea>',
addListeners: function() {
var self = this;
self.parent.addListeners.call(self);
// submit textarea by ctrl+enter even with buttons
if (self.single && self.buttons !== 'no') {
self.autosubmit();
}
},
autosubmit: function() {
var self = this;
self.inputEl.bind('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && (e.keyCode === 13)) {
self.scope.$apply(function() {
self.scope.$form.$submit();
});
}
});
}
});
}]);
/**
* EditableController class.
* Attached to element with `editable-xxx` directive.
*
* @namespace editable-element
*/
/*
TODO: this file should be refactored to work more clear without closures!
*/
angular.module('xeditable').factory('editableController',
['$q', 'editableUtils',
function($q, editableUtils) {
//EditableController function
EditableController.$inject = ['$scope', '$attrs', '$element', '$parse', 'editableThemes', 'editableOptions', '$rootScope', '$compile', '$q'];
function EditableController($scope, $attrs, $element, $parse, editableThemes, editableOptions, $rootScope, $compile, $q) {
var valueGetter;
//if control is disabled - it does not participate in waiting process
var inWaiting;
var self = this;
self.scope = $scope;
self.elem = $element;
self.attrs = $attrs;
self.inputEl = null;
self.editorEl = null;
self.single = true;
self.error = '';
self.theme = editableThemes[editableOptions.theme] || editableThemes['default'];
self.parent = {};
//to be overwritten by directive
self.inputTpl = '';
self.directiveName = '';
// with majority of controls copy is not needed, but..
// copy MUST NOT be used for `select-multiple` with objects as items
// copy MUST be used for `checklist`
self.useCopy = false;
//runtime (defaults)
self.single = null;
/**
* Attributes defined with `e-*` prefix automatically transfered from original element to
* control.
* For example, if you set `<span editable-text="user.name" e-style="width: 100px"`>
* then input will appear as `<input style="width: 100px">`.
* See [demo](#text-customize).
*
* @var {any|attribute} e-*
* @memberOf editable-element
*/
/**
* Whether to show ok/cancel buttons. Values: `right|no`.
* If set to `no` control automatically submitted when value changed.
* If control is part of form buttons will never be shown.
*
* @var {string|attribute} buttons
* @memberOf editable-element
*/
self.buttons = 'right';
/**
* Action when control losses focus. Values: `cancel|submit|ignore`.
* Has sense only for single editable element.
* Otherwise, if control is part of form - you should set `blur` of form, not of individual element.
*
* @var {string|attribute} blur
* @memberOf editable-element
*/
// no real `blur` property as it is transfered to editable form
//init
self.init = function(single) {
self.single = single;
self.name = $attrs.eName || $attrs[self.directiveName];
/*
if(!$attrs[directiveName] && !$attrs.eNgModel && ($attrs.eValue === undefined)) {
throw 'You should provide value for `'+directiveName+'` or `e-value` in editable element!';
}
*/
if($attrs[self.directiveName]) {
valueGetter = $parse($attrs[self.directiveName]);
} else {
throw 'You should provide value for `'+self.directiveName+'` in editable element!';
}
// settings for single and non-single
if (!self.single) {
// hide buttons for non-single
self.buttons = 'no';
} else {
self.buttons = self.attrs.buttons || editableOptions.buttons;
}
//if name defined --> watch changes and update $data in form
if($attrs.eName) {
self.scope.$watch('$data', function(newVal){
self.scope.$form.$data[$attrs.eName] = newVal;
});
}
/**
* Called when control is shown.
* See [demo](#select-remote).
*
* @var {method|attribute} onshow
* @memberOf editable-element
*/
if($attrs.onshow) {
self.onshow = function() {
return self.catchError($parse($attrs.onshow)($scope));
};
}
/**
* Called when control is hidden after both save or cancel.
*
* @var {method|attribute} onhide
* @memberOf editable-element
*/
if($attrs.onhide) {
self.onhide = function() {
return $parse($attrs.onhide)($scope);
};
}
/**
* Called when control is cancelled.
*
* @var {method|attribute} oncancel
* @memberOf editable-element
*/
if($attrs.oncancel) {
self.oncancel = function() {
return $parse($attrs.oncancel)($scope);
};
}
/**
* Called during submit before value is saved to model.
* See [demo](#onbeforesave).
*
* @var {method|attribute} onbeforesave
* @memberOf editable-element
*/
if ($attrs.onbeforesave) {
self.onbeforesave = function() {
return self.catchError($parse($attrs.onbeforesave)($scope));
};
}
/**
* Called during submit after value is saved to model.
* See [demo](#onaftersave).
*
* @var {method|attribute} onaftersave
* @memberOf editable-element
*/
if ($attrs.onaftersave) {
self.onaftersave = function() {
return self.catchError($parse($attrs.onaftersave)($scope));
};
}
// watch change of model to update editable element
// now only add/remove `editable-empty` class.
// Initially this method called with newVal = undefined, oldVal = undefined
// so no need initially call handleEmpty() explicitly
$scope.$parent.$watch($attrs[self.directiveName], function(newVal, oldVal) {
self.handleEmpty();
});
};
self.render = function() {
var theme = self.theme;
//build input
self.inputEl = angular.element(self.inputTpl);
//build controls
self.controlsEl = angular.element(theme.controlsTpl);
self.controlsEl.append(self.inputEl);
//build buttons
if(self.buttons !== 'no') {
self.buttonsEl = angular.element(theme.buttonsTpl);
self.submitEl = angular.element(theme.submitTpl);
self.cancelEl = angular.element(theme.cancelTpl);
self.buttonsEl.append(self.submitEl).append(self.cancelEl);
self.controlsEl.append(self.buttonsEl);
self.inputEl.addClass('editable-has-buttons');
}
//build error
self.errorEl = angular.element(theme.errorTpl);
self.controlsEl.append(self.errorEl);
//build editor
self.editorEl = angular.element(self.single ? theme.formTpl : theme.noformTpl);
self.editorEl.append(self.controlsEl);
// transfer `e-*|data-e-*|x-e-*` attributes
for(var k in $attrs.$attr) {
if(k.length <= 1) {
continue;
}
var transferAttr = false;
var nextLetter = k.substring(1, 2);
// if starts with `e` + uppercase letter
if(k.substring(0, 1) === 'e' && nextLetter === nextLetter.toUpperCase()) {
transferAttr = k.substring(1); // cut `e`
} else {
continue;
}
// exclude `form` and `ng-submit`,
if(transferAttr === 'Form' || transferAttr === 'NgSubmit') {
continue;
}
// convert back to lowercase style
transferAttr = transferAttr.substring(0, 1).toLowerCase() + editableUtils.camelToDash(transferAttr.substring(1));
// workaround for attributes without value (e.g. `multiple = "multiple"`)
var attrValue = ($attrs[k] === '') ? transferAttr : $attrs[k];
// set attributes to input
self.inputEl.attr(transferAttr, attrValue);
}
self.inputEl.addClass('editable-input');
self.inputEl.attr('ng-model', '$data');
// add directiveName class to editor, e.g. `editable-text`
self.editorEl.addClass(editableUtils.camelToDash(self.directiveName));
if(self.single) {
self.editorEl.attr('editable-form', '$form');
// transfer `blur` to form
self.editorEl.attr('blur', self.attrs.blur || (self.buttons === 'no' ? 'cancel' : editableOptions.blurElem));
}
//apply `postrender` method of theme
if(angular.isFunction(theme.postrender)) {
theme.postrender.call(self);
}
};
// with majority of controls copy is not needed, but..
// copy MUST NOT be used for `select-multiple` with objects as items
// copy MUST be used for `checklist`
self.setLocalValue = function() {
self.scope.$data = self.useCopy ?
angular.copy(valueGetter($scope.$parent)) :
valueGetter($scope.$parent);
};
//show
self.show = function() {
// set value of scope.$data
self.setLocalValue();
/*
Originally render() was inside init() method, but some directives polluting editorEl,
so it is broken on second openning.
Cloning is not a solution as jqLite can not clone with event handler's.
*/
self.render();
// insert into DOM
$element.after(self.editorEl);
// compile (needed to attach ng-* events from markup)
$compile(self.editorEl)($scope);
// attach listeners (`escape`, autosubmit, etc)
self.addListeners();
// hide element
$element.addClass('editable-hide');
// onshow
return self.onshow();
};
//hide
self.hide = function() {
self.editorEl.remove();
$element.removeClass('editable-hide');
// onhide
return self.onhide();
};
// cancel
self.cancel = function() {
// oncancel
self.oncancel();
// don't call hide() here as it called in form's code
};
/*
Called after show to attach listeners
*/
self.addListeners = function() {
// bind keyup for `escape`
self.inputEl.bind('keyup', function(e) {
if(!self.single) {
return;
}
// todo: move this to editable-form!
switch(e.keyCode) {
// hide on `escape` press
case 27:
self.scope.$apply(function() {
self.scope.$form.$cancel();
});
break;
}
});
// autosubmit when `no buttons`
if (self.single && self.buttons === 'no') {
self.autosubmit();
}
// click - mark element as clicked to exclude in document click handler
self.editorEl.bind('click', function(e) {
// ignore right/middle button click
if (e.which !== 1) {
return;
}
if (self.scope.$form.$visible) {
self.scope.$form._clicked = true;
}
});
};
// setWaiting
self.setWaiting = function(value) {
if (value) {
// participate in waiting only if not disabled
inWaiting = !self.inputEl.attr('disabled') &&
!self.inputEl.attr('ng-disabled') &&
!self.inputEl.attr('ng-enabled');
if (inWaiting) {
self.inputEl.attr('disabled', 'disabled');
if(self.buttonsEl) {
self.buttonsEl.find('button').attr('disabled', 'disabled');
}
}
} else {
if (inWaiting) {
self.inputEl.removeAttr('disabled');
if (self.buttonsEl) {
self.buttonsEl.find('button').removeAttr('disabled');
}
}
}
};
self.activate = function() {
setTimeout(function() {
var el = self.inputEl[0];
if (editableOptions.activate === 'focus' && el.focus) {
el.focus();
}
if (editableOptions.activate === 'select' && el.select) {
el.select();
}
}, 0);
};
self.setError = function(msg) {
if(!angular.isObject(msg)) {
$scope.$error = msg;
self.error = msg;
}
};
/*
Checks that result is string or promise returned string and shows it as error message
Applied to onshow, onbeforesave, onaftersave
*/
self.catchError = function(result, noPromise) {
if (angular.isObject(result) && noPromise !== true) {
$q.when(result).then(
//success and fail handlers are equal
angular.bind(this, function(r) {
this.catchError(r, true);
}),
angular.bind(this, function(r) {
this.catchError(r, true);
})
);
//check $http error
} else if (noPromise && angular.isObject(result) && result.status &&
(result.status !== 200) && result.data && angular.isString(result.data)) {
this.setError(result.data);
//set result to string: to let form know that there was error
result = result.data;
} else if (angular.isString(result)) {
this.setError(result);
}
return result;
};
self.save = function() {
valueGetter.assign($scope.$parent, angular.copy(self.scope.$data));
// no need to call handleEmpty here as we are watching change of model value
// self.handleEmpty();
};
/*
attach/detach `editable-empty` class to element
*/
self.handleEmpty = function() {
var val = valueGetter($scope.$parent);
var isEmpty = val === null || val === undefined || val === "" || (angular.isArray(val) && val.length === 0);
$element.toggleClass('editable-empty', isEmpty);
};
/*
Called when `buttons = "no"` to submit automatically
*/
self.autosubmit = angular.noop;
self.onshow = angular.noop;
self.onhide = angular.noop;
self.oncancel = angular.noop;
self.onbeforesave = angular.noop;
self.onaftersave = angular.noop;
}
return EditableController;
}]);
/*
editableFactory is used to generate editable directives (see `/directives` folder)
Inside it does several things:
- detect form for editable element. Form may be one of three types:
1. autogenerated form (for single editable elements)
2. wrapper form (element wrapped by <form> tag)
3. linked form (element has `e-form` attribute pointing to existing form)
- attach editableController to element
Depends on: editableController, editableFormFactory
*/
angular.module('xeditable').factory('editableDirectiveFactory',
['$parse', '$compile', 'editableThemes', '$rootScope', '$document', 'editableController', 'editableFormController',
function($parse, $compile, editableThemes, $rootScope, $document, editableController, editableFormController) {
//directive object
return function(overwrites) {
return {
restrict: 'A',
scope: true,
require: [overwrites.directiveName, '?^form'],
controller: editableController,
link: function(scope, elem, attrs, ctrl) {
// editable controller
var eCtrl = ctrl[0];
// form controller
var eFormCtrl;
// this variable indicates is element is bound to some existing form,
// or it's single element who's form will be generated automatically
// By default consider single element without any linked form.ß
var hasForm = false;
// element wrapped by form
if(ctrl[1]) {
eFormCtrl = ctrl[1];
hasForm = true;
} else if(attrs.eForm) { // element not wrapped by <form>, but we hane `e-form` attr
var getter = $parse(attrs.eForm)(scope);
if(getter) { // form exists in scope (above), e.g. editable column
eFormCtrl = getter;
hasForm = true;
} else { // form exists below or not exist at all: check document.forms
for(var i=0; i<$document[0].forms.length;i++){
if($document[0].forms[i].name === attrs.eForm) {
// form is below and not processed yet
eFormCtrl = null;
hasForm = true;
break;
}
}
}
}
/*
if(hasForm && !attrs.eName) {
throw 'You should provide `e-name` for editable element inside form!';
}
*/
//check for `editable-form` attr in form
/*
if(eFormCtrl && ) {
throw 'You should provide `e-name` for editable element inside form!';
}
*/
// store original props to `parent` before merge
angular.forEach(overwrites, function(v, k) {
if(eCtrl[k] !== undefined) {
eCtrl.parent[k] = eCtrl[k];
}
});
// merge overwrites to base editable controller
angular.extend(eCtrl, overwrites);
// init editable ctrl
eCtrl.init(!hasForm);
// publich editable controller as `$editable` to be referenced in html
scope.$editable = eCtrl;
// add `editable` class to element
elem.addClass('editable');
// hasForm
if(hasForm) {
if(eFormCtrl) {
scope.$form = eFormCtrl;
if(!scope.$form.$addEditable) {
throw 'Form with editable elements should have `editable-form` attribute.';
}
scope.$form.$addEditable(eCtrl);
} else {
// future form (below): add editable controller to buffer and add to form later
$rootScope.$$editableBuffer = $rootScope.$$editableBuffer || {};
$rootScope.$$editableBuffer[attrs.eForm] = $rootScope.$$editableBuffer[attrs.eForm] || [];
$rootScope.$$editableBuffer[attrs.eForm].push(eCtrl);
scope.$form = null; //will be re-assigned later
}
// !hasForm
} else {
// create editableform controller
scope.$form = editableFormController();
// add self to editable controller
scope.$form.$addEditable(eCtrl);
// if `e-form` provided, publish local $form in scope
if(attrs.eForm) {
scope.$parent[attrs.eForm] = scope.$form;
}
// bind click - if no external form defined
if(!attrs.eForm) {
elem.addClass('editable-click');
elem.bind('click', function(e) {
e.preventDefault();
e.editable = eCtrl;
scope.$apply(function(){
scope.$form.$show();
});
});
}
}
}
};
};
}]);
/*
Returns editableForm controller
*/
angular.module('xeditable').factory('editableFormController',
['$parse', '$document', '$rootScope', 'editablePromiseCollection', 'editableUtils',
function($parse, $document, $rootScope, editablePromiseCollection, editableUtils) {
// array of opened editable forms
var shown = [];
// bind click to body: cancel|submit|ignore forms
$document.bind('click', function(e) {
// ignore right/middle button click
if (e.which !== 1) {
return;
}
var toCancel = [];
var toSubmit = [];
for (var i=0; i<shown.length; i++) {
// exclude clicked
if (shown[i]._clicked) {
shown[i]._clicked = false;
continue;
}
// exclude waiting
if (shown[i].$waiting) {
continue;
}
if (shown[i]._blur === 'cancel') {
toCancel.push(shown[i]);
}
if (shown[i]._blur === 'submit') {
toSubmit.push(shown[i]);
}
}
if (toCancel.length || toSubmit.length) {
$rootScope.$apply(function() {
angular.forEach(toCancel, function(v){ v.$cancel(); });
angular.forEach(toSubmit, function(v){ v.$submit(); });
});
}
});
var base = {
$addEditable: function(editable) {
//console.log('add editable', editable.elem, editable.elem.bind);
this.$editables.push(editable);
//'on' is not supported in angular 1.0.8
editable.elem.bind('$destroy', angular.bind(this, this.$removeEditable, editable));
//bind editable's local $form to self (if not bound yet, below form)
if (!editable.scope.$form) {
editable.scope.$form = this;
}
//if form already shown - call show() of new editable
if (this.$visible) {
editable.catchError(editable.show());
}
},
$removeEditable: function(editable) {
//arrayRemove
for(var i=0; i < this.$editables.length; i++) {
if(this.$editables[i] === editable) {
this.$editables.splice(i, 1);
return;
}
}
},
/**
* Shows form with editable controls.
*
* @method $show()
* @memberOf editable-form
*/
$show: function() {
if (this.$visible) {
return;
}
this.$visible = true;
var pc = editablePromiseCollection();
//own show
pc.when(this.$onshow());
//clear errors
this.$setError(null, '');
//children show
angular.forEach(this.$editables, function(editable) {
pc.when(editable.show());
});
//wait promises and activate
pc.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, this.$activate),
onFalse: angular.bind(this, this.$activate),
onString: angular.bind(this, this.$activate)
});
// add to internal list of shown forms
// setTimeout needed to prevent closing right after opening (e.g. when trigger by button)
setTimeout(angular.bind(this, function() {
// clear `clicked` to get ready for clicks on visible form
this._clicked = false;
if(editableUtils.indexOf(shown, this) === -1) {
shown.push(this);
}
}), 0);
},
/**
* Sets focus on form field specified by `name`.
*
* @method $activate(name)
* @param {string} name name of field
* @memberOf editable-form
*/
$activate: function(name) {
var i;
if (this.$editables.length) {
//activate by name
if (angular.isString(name)) {
for(i=0; i<this.$editables.length; i++) {
if (this.$editables[i].name === name) {
this.$editables[i].activate();
return;
}
}
}
//try activate error field
for(i=0; i<this.$editables.length; i++) {
if (this.$editables[i].error) {
this.$editables[i].activate();
return;
}
}
//by default activate first field
this.$editables[0].activate();
}
},
/**
* Hides form with editable controls without saving.
*
* @method $hide()
* @memberOf editable-form
*/
$hide: function() {
if (!this.$visible) {
return;
}
this.$visible = false;
// self hide
this.$onhide();
// children's hide
angular.forEach(this.$editables, function(editable) {
editable.hide();
});
// remove from internal list of shown forms
editableUtils.arrayRemove(shown, this);
},
/**
* Triggers `oncancel` event and calls `$hide()`.
*
* @method $cancel()
* @memberOf editable-form
*/
$cancel: function() {
if (!this.$visible) {
return;
}
// self cancel
this.$oncancel();
// children's cancel
angular.forEach(this.$editables, function(editable) {
editable.cancel();
});
// self hide
this.$hide();
},
$setWaiting: function(value) {
this.$waiting = !!value;
// we can't just set $waiting variable and use it via ng-disabled in children
// because in editable-row form is not accessible
angular.forEach(this.$editables, function(editable) {
editable.setWaiting(!!value);
});
},
/**
* Shows error message for particular field.
*
* @method $setError(name, msg)
* @param {string} name name of field
* @param {string} msg error message
* @memberOf editable-form
*/
$setError: function(name, msg) {
angular.forEach(this.$editables, function(editable) {
if(!name || editable.name === name) {
editable.setError(msg);
}
});
},
$submit: function() {
if (this.$waiting) {
return;
}
//clear errors
this.$setError(null, '');
//children onbeforesave
var pc = editablePromiseCollection();
angular.forEach(this.$editables, function(editable) {
pc.when(editable.onbeforesave());
});
/*
onbeforesave result:
- true/undefined: save data and close form
- false: close form without saving
- string: keep form open and show error
*/
pc.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, checkSelf, true),
onFalse: angular.bind(this, checkSelf, false),
onString: angular.bind(this, this.$activate)
});
//save
function checkSelf(childrenTrue){
var pc = editablePromiseCollection();
pc.when(this.$onbeforesave());
pc.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: childrenTrue ? angular.bind(this, this.$save) : angular.bind(this, this.$hide),
onFalse: angular.bind(this, this.$hide),
onString: angular.bind(this, this.$activate)
});
}
},
$save: function() {
// write model for each editable
angular.forEach(this.$editables, function(editable) {
editable.save();
});
//call onaftersave of self and children
var pc = editablePromiseCollection();
pc.when(this.$onaftersave());
angular.forEach(this.$editables, function(editable) {
pc.when(editable.onaftersave());
});
/*
onaftersave result:
- true/undefined/false: just close form
- string: keep form open and show error
*/
pc.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, this.$hide),
onFalse: angular.bind(this, this.$hide),
onString: angular.bind(this, this.$activate)
});
},
$onshow: angular.noop,
$oncancel: angular.noop,
$onhide: angular.noop,
$onbeforesave: angular.noop,
$onaftersave: angular.noop
};
return function() {
return angular.extend({
$editables: [],
/**
* Form visibility flag.
*
* @var {bool} $visible
* @memberOf editable-form
*/
$visible: false,
/**
* Form waiting flag. It becomes `true` when form is loading or saving data.
*
* @var {bool} $waiting
* @memberOf editable-form
*/
$waiting: false,
$data: {},
_clicked: false,
_blur: null
}, base);
};
}]);
/**
* EditableForm directive. Should be defined in <form> containing editable controls.
* It add some usefull methods to form variable exposed to scope by `name="myform"` attribute.
*
* @namespace editable-form
*/
angular.module('xeditable').directive('editableForm',
['$rootScope', '$parse', 'editableFormController', 'editableOptions',
function($rootScope, $parse, editableFormController, editableOptions) {
return {
restrict: 'A',
require: ['form'],
//require: ['form', 'editableForm'],
//controller: EditableFormController,
compile: function() {
return {
pre: function(scope, elem, attrs, ctrl) {
var form = ctrl[0];
var eForm;
//if `editableForm` has value - publish smartly under this value
//this is required only for single editor form that is created and removed
if(attrs.editableForm) {
if(scope[attrs.editableForm] && scope[attrs.editableForm].$show) {
eForm = scope[attrs.editableForm];
angular.extend(form, eForm);
} else {
eForm = editableFormController();
scope[attrs.editableForm] = eForm;
angular.extend(eForm, form);
}
} else { //just merge to form and publish if form has name
eForm = editableFormController();
angular.extend(form, eForm);
}
//read editables from buffer (that appeared before FORM tag)
var buf = $rootScope.$$editableBuffer;
var name = form.$name;
if(name && buf && buf[name]) {
angular.forEach(buf[name], function(editable) {
eForm.$addEditable(editable);
});
delete buf[name];
}
},
post: function(scope, elem, attrs, ctrl) {
var eForm;
if(attrs.editableForm && scope[attrs.editableForm] && scope[attrs.editableForm].$show) {
eForm = scope[attrs.editableForm];
} else {
eForm = ctrl[0];
}
/**
* Called when form is shown.
*
* @var {method|attribute} onshow
* @memberOf editable-form
*/
if(attrs.onshow) {
eForm.$onshow = angular.bind(eForm, $parse(attrs.onshow), scope);
}
/**
* Called when form hides after both save or cancel.
*
* @var {method|attribute} onhide
* @memberOf editable-form
*/
if(attrs.onhide) {
eForm.$onhide = angular.bind(eForm, $parse(attrs.onhide), scope);
}
/**
* Called when form is cancelled.
*
* @var {method|attribute} oncancel
* @memberOf editable-form
*/
if(attrs.oncancel) {
eForm.$oncancel = angular.bind(eForm, $parse(attrs.oncancel), scope);
}
/**
* Whether form initially rendered in shown state.
*
* @var {bool|attribute} shown
* @memberOf editable-form
*/
if(attrs.shown && $parse(attrs.shown)(scope)) {
eForm.$show();
}
/**
* Action when form losses focus. Values: `cancel|submit|ignore`.
* Default is `ignore`.
*
* @var {string|attribute} blur
* @memberOf editable-form
*/
eForm._blur = attrs.blur || editableOptions.blurForm;
// onbeforesave, onaftersave
if(!attrs.ngSubmit && !attrs.submit) {
/**
* Called after all children `onbeforesave` callbacks but before saving form values
* to model.
* If at least one children callback returns `non-string` - it will not not be called.
* See [editable-form demo](#editable-form) for details.
*
* @var {method|attribute} onbeforesave
* @memberOf editable-form
*
*/
if(attrs.onbeforesave) {
eForm.$onbeforesave = function() {
return $parse(attrs.onbeforesave)(scope, {$data: eForm.$data});
};
}
/**
* Called when form values are saved to model.
* See [editable-form demo](#editable-form) for details.
*
* @var {method|attribute} onaftersave
* @memberOf editable-form
*
*/
if(attrs.onaftersave) {
eForm.$onaftersave = function() {
return $parse(attrs.onaftersave)(scope, {$data: eForm.$data});
};
}
elem.bind('submit', function(event) {
event.preventDefault();
scope.$apply(function() {
eForm.$submit();
});
});
}
// click - mark form as clicked to exclude in document click handler
elem.bind('click', function(e) {
// ignore right/middle button click
if (e.which !== 1) {
return;
}
if (eForm.$visible) {
eForm._clicked = true;
}
});
}
};
}
};
}]);
/**
* editablePromiseCollection
*
* Collect results of function calls. Shows waiting if there are promises.
* Finally, applies callbacks if:
* - onTrue(): all results are true and all promises resolved to true
* - onFalse(): at least one result is false or promise resolved to false
* - onString(): at least one result is string or promise rejected or promise resolved to string
*/
angular.module('xeditable').factory('editablePromiseCollection', ['$q', function($q) {
function promiseCollection() {
return {
promises: [],
hasFalse: false,
hasString: false,
when: function(result, noPromise) {
if (result === false) {
this.hasFalse = true;
} else if (!noPromise && angular.isObject(result)) {
this.promises.push($q.when(result));
} else if (angular.isString(result)){
this.hasString = true;
} else { //result === true || result === undefined || result === null
return;
}
},
//callbacks: onTrue, onFalse, onString
then: function(callbacks) {
callbacks = callbacks || {};
var onTrue = callbacks.onTrue || angular.noop;
var onFalse = callbacks.onFalse || angular.noop;
var onString = callbacks.onString || angular.noop;
var onWait = callbacks.onWait || angular.noop;
var self = this;
if (this.promises.length) {
onWait(true);
$q.all(this.promises).then(
//all resolved
function(results) {
onWait(false);
//check all results via same `when` method (without checking promises)
angular.forEach(results, function(result) {
self.when(result, true);
});
applyCallback();
},
//some rejected
function(error) {
onWait(false);
onString();
}
);
} else {
applyCallback();
}
function applyCallback() {
if (!self.hasString && !self.hasFalse) {
onTrue();
} else if (!self.hasString && self.hasFalse) {
onFalse();
} else {
onString();
}
}
}
};
}
return promiseCollection;
}]);
/**
* editableUtils
*/
angular.module('xeditable').factory('editableUtils', [function() {
return {
indexOf: function (array, obj) {
if (array.indexOf) return array.indexOf(obj);
for ( var i = 0; i < array.length; i++) {
if (obj === array[i]) return i;
}
return -1;
},
arrayRemove: function (array, value) {
var index = this.indexOf(array, value);
if (index >= 0) {
array.splice(index, 1);
}
return value;
},
// copy from https://github.com/angular/angular.js/blob/master/src/Angular.js
camelToDash: function(str) {
var SNAKE_CASE_REGEXP = /[A-Z]/g;
return str.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
return (pos ? '-' : '') + letter.toLowerCase();
});
},
dashToCamel: function(str) {
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
return str.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
}
};
}]);
/**
* editableNgOptionsParser
*
* see: https://github.com/angular/angular.js/blob/master/src/ng/directive/select.js#L131
*/
angular.module('xeditable').factory('editableNgOptionsParser', [
function() {
//0000111110000000000022220000000000000000000000333300000000000000444444444444444000000000555555555555555000000066666666666666600000000000000007777000000000000000000088888
var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;
function parser(optionsExp) {
var match;
if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
throw 'ng-options parse error';
}
var
displayFn = match[2] || match[1],
valueName = match[4] || match[6],
keyName = match[5],
groupByFn = match[3] || '',
valueFn = match[2] ? match[1] : valueName,
valuesFn = match[7],
track = match[8],
trackFn = track ? match[8] : null;
var ngRepeat;
if (keyName === undefined) { // array
ngRepeat = valueName + ' in ' + valuesFn;
if (track !== undefined) {
ngRepeat += ' track by '+trackFn;
}
} else { // object
ngRepeat = '('+keyName+', '+valueName+') in '+valuesFn;
}
// group not supported yet
return {
ngRepeat: ngRepeat,
locals: {
valueName: valueName,
keyName: keyName,
valueFn: valueFn,
displayFn: displayFn
}
};
}
return parser;
}]);
/*
Editable themes:
- default
- bootstrap 2
- bootstrap 3
Note: in postrender() `this` is instance of editableController
*/
angular.module('xeditable').factory('editableThemes', function() {
var themes = {
//default
'default': {
formTpl: '<form class="editable-wrap"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<span class="editable-controls"></span>',
inputTpl: '',
errorTpl: '<div class="editable-error" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit">save</button>',
cancelTpl: '<button type="button" ng-click="$form.$cancel()">cancel</button>'
},
//bs2
'bs2': {
formTpl: '<form class="form-inline editable-wrap" role="form"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<div class="editable-controls controls control-group" ng-class="{\'error\': $error}"></div>',
inputTpl: '',
errorTpl: '<div class="editable-error help-block" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit" class="btn btn-primary"><span class="icon-ok icon-white"></span></button>',
cancelTpl: '<button type="button" class="btn" ng-click="$form.$cancel()">'+
'<span class="icon-remove"></span>'+
'</button>'
},
//bs3
'bs3': {
formTpl: '<form class="form-inline editable-wrap" role="form"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<div class="editable-controls form-group" ng-class="{\'has-error\': $error}"></div>',
inputTpl: '',
errorTpl: '<div class="editable-error help-block" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-ok"></span></button>',
cancelTpl: '<button type="button" class="btn btn-default" ng-click="$form.$cancel()">'+
'<span class="glyphicon glyphicon-remove"></span>'+
'</button>',
//bs3 specific prop to change buttons class: btn-sm, btn-lg
buttonsClass: '',
//bs3 specific prop to change standard inputs class: input-sm, input-lg
inputClass: '',
postrender: function() {
//apply `form-control` class to std inputs
switch(this.directiveName) {
case 'editableText':
case 'editableSelect':
case 'editableTextarea':
case 'editableEmail':
case 'editableTel':
case 'editableNumber':
case 'editableUrl':
case 'editableSearch':
case 'editableDate':
case 'editableDatetime':
case 'editableTime':
case 'editableMonth':
case 'editableWeek':
this.inputEl.addClass('form-control');
if(this.theme.inputClass) {
// don`t apply `input-sm` and `input-lg` to select multiple
// should be fixed in bs itself!
if(this.inputEl.attr('multiple') &&
(this.theme.inputClass === 'input-sm' || this.theme.inputClass === 'input-lg')) {
break;
}
this.inputEl.addClass(this.theme.inputClass);
}
break;
}
//apply buttonsClass (bs3 specific!)
if(this.buttonsEl && this.theme.buttonsClass) {
this.buttonsEl.find('button').addClass(this.theme.buttonsClass);
}
}
}
};
return themes;
});
File added
html, body{
margin: 0;
padding: 0;
border: 0;
font-family:Verdana,Helvetica,sans-serif;
font-size:12pt;
}
@media print, screen {
*{float: none}
h1{
font-size: 14pt;
}
h2{
font-size: 13pt;
}
th.header{
width: 100%;
border-bottom: 1px dashed black;
text-decoration: none;
font-weight: normal;
text-align: left;
height: 180px;
}
thead{
display: table-header-group;
}
#footer {
display: block;
position: fixed;
bottom: 0;
border-top: 1px dashed #000000;
}
#footer:after {
counter-increment: page;
content: "Seite" counter(page);
right: 0;
top: 0pt;
position: absolute;
}
table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin: 0;
}
.dattable table, .dattable th, .dattable td {
border: 1px solid black;
vertical-align: top;
}
.graycell{
background-color: transparent;
overflow: hidden;
z-index: 1;
border-right: 0;
border-bottom: 0;
}
.graycell:before{
content: "";
padding: 0;
height: 1px;
line-height: 1px;
width: 1px;
margin: -4px -994px -996px -6px;
display: block;
border: 0;
z-index: -1;
position:relative;
top: -500px;
border-top: 999px solid #d3d3d3;
border-left: 999px solid #d3d3d3;;
}
}
@media print {
.page-break {
display: block;
page-break-before: always;
}
.hide-print {
display: none;
}
}
@page {
margin: 3em;
}
.killbox {
border: 1px solid black;
height: 230px;
width: 45%;
float: left;
padding: 8px;
margin: 20px 20px 0 0;
page-break-inside: avoid;
}
.killbox:nth-child(odd) {
margin: 20px 0 0 0;
}
.killbox [role="killer"], .killbox [role="victim"] {
border-bottom: 1px dashed black;
display: block;
margin-bottom: 5px;
}
.killbox [role="killer"]:before {
content: 'Mörder: ';
font-weight: bold;
}
.killbox [role="victim"]:before {
content: 'Opfer: ';
font-weight: bold;
}
<?php
require_once __DIR__ . '/../../frameworks/Environment.php';
interface SignupMethodStatics {
/**
* @return string with humanly readable name of this method
*/
public static function getName();
/**
* @return string with a short description
*/
public static function getAltText();
/**
* This method will return some meta info about that method. It should return an associative array of that form:
*
* [
* version => '1.0',
* date => '20.08.2014',
* contributors => ['MH <mail>', 'TR <mail>']
* ]
*
* @return object containing meta info (see description)
*/
public static function getMetaInfo();
public static function getLogo();
public static function getScore($stats);
public static function getBadgeDetails($stats);
}
abstract class SignupMethod implements SignupMethodStatics {
// =================================================================================================================
// Abstract functions
// to be implemented by each method
// =================================================================================================================
/**
* @return array of (relative to '/view/signups/<folder>/') scripts to include in frontend
*/
abstract public function getJSDependencies();
/**
* @return array of (relative to '/view/signups/<folder>/') css files to include in frontend
*/
abstract public function getCSSDependencies();
/**
* @return string to be added to to the HTML page header
*/
abstract public function getAdditionalHeader();
/**
* @return string containing the necessary HTML code to bind the stuff needed into
* the placeholder on the signup page
*/
abstract public function showInlineHTML();
// =================================================================================================================
// Shared functions
// available to each signup method
// =================================================================================================================
protected static $signupsBasepath = 'signups/';
protected $environment;
public function __construct() {
$this->environment = Environment::getEnv();
}
/**
* @return string containing the basic form submit parameters
*/
protected function getFormSubmitBaseParams() {
$environment = Environment::getEnv();
$waitlist_mode = $environment->isInWaitlistMode();
$bachelor = $environment->getBachelor(false, true, true);
$bachelorData = $bachelor->getData();
return '?fid=' . $environment->getSelectedTripId() .
'&method=' . SignupMethods::getInstance()->getActiveMethodId() .
(isset($bachelorData['id']) ? '&bid=' . $bachelorData['id'] : '') .
($waitlist_mode ? '&waitlist' : '');
}
}
\ No newline at end of file
<?php
class FormSignupMethod extends SignupMethod {
public static function getName() {
return "Langweiliges Formular";
}
public static function getAltText() {
return "Seite zu bunt? Kein JavaScript? Oder einfach nur Langweiler?";
}
public static function getMetaInfo() {
return [
"version" => '1.2',
"date" => '20.09.2014',
"contributors" => ['Tim Repke <tim@repke.eu>']
];
}
public static function getLogo() {
return 'graphics/hej.svg';
}
public static function getScore($stats) {
return rand(30, 99);
}
public static function getBadgeDetails($stats) {
return 'superspecial <br /> Detials';
}
public function getJSDependencies() {
return [];
}
public function getCSSDependencies() {
return ['style.css'];
}
public function getAdditionalHeader() {
return '';
}
public function showInlineHTML() {
$soft_prot = new soft_protect();
$bachelor = $this->environment->getBachelor(false, true, true);
$bachelorData = $bachelor->getData();
$fahrt = $this->environment->getTrip();
$possible_dates = $fahrt->getPossibleDates();
$waitlist_mode = $this->environment->isInWaitlistMode();
$link_params = $this->getFormSubmitBaseParams();
echo '<div style="margin: 0 auto;width: 702px;">';
if ($waitlist_mode)
echo '<h1 style="color: red;">Warteliste</h1>
<p>Eintragen und hoffen...</p>';
else
echo '<h1>Anmeldeformular</h1>
<p>Bitte hier verbindlich anmelden.</p>';
echo '</div>';
echo '<div id="stylized" class="myform">
<form id="form" name="form" method="post" action="index.php' . $link_params . '">';
$this->show_formular_helper_hidden_input('signupstats', (isset($bachelorData['signupstats']) ? $bachelorData['signupstats'] : null));
$this->show_formular_helper_input('Vorname', 'forname', $bachelorData['forname'], '', 'width:47%; float:left;');
$this->show_formular_helper_input('Nachname', 'sirname', $bachelorData['sirname'], '', 'width:47%; float:right;');
echo '<div style="clear:both"></div>';
$this->show_formular_helper_input('Anzeigename', 'pseudo', $bachelorData['pseudo'], '', 'width:47%; float:left;');
$this->show_formular_helper_input('E-Mail-Adresse', 'mehl', $bachelorData['mehl'], 'regelmäßig lesen!', 'width:47%; float:right;');
echo '<div style="clear:both"></div>';
$this->show_formular_helper_sel("Du bist", "studityp", $this->environment->oconfig['studitypen'], $bachelorData["studityp"],
"", 'width:47%; float:left;');
echo '<div style="clear:both;"></div>';
$this->show_formular_helper_sel("Alter 18+?", "virgin", ['UNSET'=>'', 'JA'=>'Ja', 'NEIN' => 'Nein'],
isset($bachelorData['virgin']) ? ($bachelorData['virgin'] == 0 ? "JA" : "NEIN") : 'UNSET',
"Bist du älter als 18 Jahre?", 'width:47%; float:left;');
$this->show_formular_helper_sel("Essenswunsch", "essen", $this->environment->oconfig['essen'], $bachelorData["essen"],
"Info für den Koch.", 'width:47%; float:right;margin-right:-6px;');
echo '<div style="clear:both;"></div>';
$this->show_formular_helper_sel2("Anreise", "anday", array_slice($possible_dates, 0, -1), $bachelorData["anday"],
"antyp", $this->environment->oconfig['reisearten'], $bachelorData["antyp"], "",'width:47%; float:left;');
$this->show_formular_helper_sel2("Abreise", "abday", array_slice($possible_dates, 1), $bachelorData["abday"],
"abtyp", $this->environment->oconfig['reisearten'], $bachelorData["abtyp"], "",'width:47%; float:right;margin-right:-6px;');
echo '<div style="clear:both;"></div>';
$this->show_formular_helper_sel("Mörderspiel", "mGame", ['JA'=>'Ja'], 'JA', '', 'display:none;');
$this->show_formular_helper_input('Orgacode', 'isOrga', '', 'Nur für Orgamitglieder', 'width:47%; float:left;');
echo '<div style="clear:both;"></div>
<label>Anmerkung</label>
<textarea id="comment" name ="comment" rows="2" cols="50" maxlength="100">' . $bachelorData["comment"] . '</textarea>
<input type="checkbox" name="public" value="public" style="width:40px" />
<span>Anmeldung verstecken</span><br/>
<input type="checkbox" name="disclaimer" value="disclaimer" style="width:40px" />
<span><a style="text-decoration:underline;" target="_blank" href="'.$fahrt->get('disclaimlink').'">Disclaimer</a> gelesen und akzeptiert</span><br/>
<div style="clear:both"></div>';
$this->show_formular_helper_input("Captcha eingeben", "captcha", "", "",'width:45%; float:left;');
echo '<img src="view/captcha.php" style="float:right; width: 45%;" />
<div style="clear:both"></div>
<button type="submit" name="submit" id="submit" value="submit">Anmelden!</button>
</form>
</div>';
echo $soft_prot->add(array('forname', 'sirname', 'pseudo'), $this->environment->config['invalidChars'])->write();
}
/**
* Puts out Label and Selection box
*
* @param $name
* @param $id
* @param $values
* @param $selected
* @param $subtext
* @param $style
*/
private function show_formular_helper_sel($name, $id, $values, $selected, $subtext, $style = null) {
$style = (empty($style) ? '' : 'style="'.$style.'"');
echo '<div class="fieldbox" '.$style.'><label>' . $name . '
<span class="small">' . $subtext . '</span>
</label>
<select name="' . $id . '" id="' . $id . '">';
foreach ($values as $val => $show) {
echo '<option value="' . $val . '"';
if ($val == $selected) echo ' selected';
echo '>' . $show . '</option>';
}
echo '</select></div>';
}
/**
* Puts out Label and two selection boxes side by side right below
*
* @param $name
* @param $id
* @param $values
* @param $selected
* @param $id2
* @param $values2
* @param $selected2
* @param $subtext
* @param $style
*/
private function show_formular_helper_sel2($name, $id, $values, $selected, $id2, $values2, $selected2, $subtext, $style = null) {
$style = (empty($style) ? '' : 'style="'.$style.'"');
echo '<div class="fieldbox" '.$style.'><label style="text-align:left">' . $name . '
<span class="small">' . $subtext . '</span>
</label>
<select style="margin-bottom:0" name="' . $id . '" id="' . $id . '">';
foreach ($values as $val) {
echo '<option value="' . $val . '"';
if ($val == $selected) echo ' selected';
echo '>' . $val . '</option>';
}
echo '</select><select name="' . $id2 . '" id="' . $id2 . '">';
foreach ($values2 as $val => $show) {
echo '<option value="' . $val . '"';
if ($val == $selected2) echo ' selected';
echo '>' . $show . '</option>';
}
echo '</select></div>';
}
private function show_formular_helper_input($name, $id, $value, $subtext, $style=null) {
$style = (empty($style) ? '' : 'style="'.$style.'"');
echo '<div class="fieldbox" '.$style.'><label for="'.$id.'">' . $name . '
<span class="small">' . $subtext . '</span>
</label><br />
<input type="text" name="' . $id . '" id="' . $id . '" value="' . $value . '" /></div>';
}
private function show_formular_helper_hidden_input($id, $value) {
echo '<textarea style="display:none;" name="' . $id . '" id="' . $id . '">' . $value . '</textarea>';
}
}
/* ----------- My Form ----------- */
.myform {
margin: 0 auto;
width: 600px;
padding: 14px;
}
/* ----------- stylized ----------- */
#stylized {
border: 1px solid #b7ddf2;
padding: 30px 50px;
}
#stylized h1 {
font-size: 1.5em;
color: black;
font-weight: bold;
margin-bottom: 8px;
}
#stylized p {
font-size: 11px;
color: #666666;
margin-bottom: 20px;
border-bottom: 1px solid #b7ddf2;
padding-bottom: 10px;
}
#stylized label {
font-weight: bold;
text-align: left;
width: 140px;
}
#stylized .small {
color: #666666;
font-size: 11px;
font-weight: normal;
text-align: right;
width: 140px;
}
#stylized input, #stylized select, #stylized textarea {
font-size: 13px;
padding: 10px 0 10px 5px;
border: 1px solid #aacfe4;
width: 100%;
margin: 5px 0 20px 0;
background-color: inherit;
}
#stylized button {
display: block;
margin: 50px auto 10px auto;
width: 250px;
height: 50px;
background: #da4cad;
text-align: center;
line-height: 31px;
color: #0912bc;
font-size: 15px;
font-weight: bold;
border: 3px solid #39ff00;
cursor: pointer;
}
#stylized .fieldbox {
width: 100%;
margin: 0 auto;
}
\ No newline at end of file
Wie baut man eine Karte richtig?
=================================
Zum Bauen der Karte wird empfohlen Inkscrape zu nutzen.
## Definitionslayer
Es gibt drei Ebenen, die vorhanden sein müssen. Hierrauf sollten sich keine graphischen Objekte befinden.
Sie sind ausschließlich der Definition für das Program gedacht.
- WALK
- NOWALK
- EVENT
### WALK
Alle Objekte auf dieser Ebene sind begehbar. Anzulegen mit dem Bezier Kurven tool (aber nur gerade Linien ziehen!).
Konvention: Objekte mit weißem fill, Ebene leicht transparent stellen.
### NOWALK
Same.
Konvention: Objekte mit rotem fill, Ebene leicht transparent stellen.
### EVENT
Hier wird es interessant! Eigentlich kann man die Objekte wie zuvor anlegen. Nachträglich müssen sie noch mit Attributen versehen werden.
Empfohlen hierfür der XML Editor (Edit > XML Editor)
Folgende Attribute sollten gesetzt werden:
- trigger (= walkon, hover, click)
- type (= achievement, mapchange, ...)
- stopsWalk (= true, false)
- destination (optional, target map für mapchange)
- target (optional, spawn point für mapchange)
- id
- action (optional, action to call as defined in Events.actions)
- directAction (optional, set true to fire action before walkTo point is reached)
- walkTo (optional, before calling action, walk to point with this ID)
- condition (optional, expression with vars as defined in Environment.progress, parenthesis allowed, i.e.: `(!someVar||otherVar)&&moreVar`)
Am Beispiel eines Achievements, welches beim drüberlaufen gefeuert wird und die Bernd weiterlaufen lässt:
```
<path
stopsWalk="false"
type="achievement"
trigger="walkon"
id="first_step" ... />
```
Dies aktiviert das Achievement "first_step" (wie definiert, siehe `js/achievements.js`)
Ganz wichtig in der Start-Ebene: Ein Objekt mit der ID="player_spawn", ansonsten target nutzen.
Konvention: spawn roter Kreis, walkon pink, mapchange grün, ... ; Ebene leicht transparent
## Special elements
Man kann elementen das Attribut `special_elem` geben. Zum Beispiel mit dem Wert `speech_bubble`. Diese Elemente werden
direkt versteckt und beispielsweise in einer action sichtbar gemacht.
\ No newline at end of file
# Needed props
- Anreise Tag @ Ticketmensch im Dorf
- Anreise Art @ Ticketmensch im Dorf
- Abreise Tag @ Aufwachufer
- Abreise Art @ Aufwachufer
- Alter (18+ ja/nein) @ Dorfeingang
- Essen @ Bäckerei im Dorf
- Name (Vor und Nachname einzeln) @ Fachschaft Tafel
- Nickname @ Jemand auf der Karte fragt danach
- E-Mail @ Fachschaft Tafel
- Kommentar @ ???
- Ersti/Tutor/Hörsti @ firstApproach Fachschaft
- Anmeldung verstecken (ja/nein) @ Jemand im Dorf fragt danach
# Eastereggs
- Captcha
- in einem Haus im Dorf sitzen die devs (wenn man reingeht, bekommt man einen Hut)
- Niveau im Keller ablegen
- Hut kaufen
- Hugo (in einem Laden im Dorf ihm eine Kugel anhängen)
# Story
## Part 1
Schiff mit vielen Rittern/Erstis. Auf dem Schiff wird man angesprochen, dass man keine Rüstung hat und die in der FS bekommt.
Wenn das Schiff an Land ist, rennen alle weg (aus dem Bild), der eigene Spieler bleibt am Steg stehen.
Kleines Schild mit hint zeigt Richtung Schloss
## Part 2
Ins Schloss gehen. Dort landet man in Eingangshalle mit drei Fahrstuhltüren.
- Eine hat einen Sack Geld
- Eine führt in den Keller (zum Niveau ablegen, Install Gentoo video)
- Eine führt hoch in die FS
In der FS bekommt man Rüstung gegen Geld und man schreibt sich in die Anmeldeliste auf dem Tisch ein (oder geht zu Fr Lindner).
-> damit greifen wir den Namen ab.
#### Interactions:
- Beim Reingehen in die Fachschaft fragt jemand: "Kenne ich dich?" -> Antwort: ("Ne, bin neu hier" | "Klar, bin doch schon länger hier" | "Ja, bin Tutor dieses Jahr")
- George brüllt durch den Raum: "Ey, meld dich mal bei der FS Fahrt an! Schreib' einfach Name und E-Mail-Adresse an die Tafel." -> An die Tafel gehen, anschreiben.
## Part 3
Entlang des Weges steht eine Person. Dieser Wanderer sagt, man solle auf dem Weg bleiben, hohes Gras ist gefährlich.
Ein Stück vom Weg ist aber bewachsen. Hierin lauert eine Ziege, die man killt/zähmt und milkt.
Auf dem Feldern sollte man Zeug sammeln
## Part 4
Am Dorfeingang steht eine Wache. Die fragt, ob man 18+ ist. Je nachdem läuft man durch eins der beiden Tore. Kurze Einblendung
mit Gorilla.
## Part 5
Im Dorf kann man zu einem Koch gehen (All you can eat). Man gibt sein ganzes Zeug ab (von der Ziege) und er kocht was feines.
Die Regale füllen sich auf einmal, man kann das Regal wählen, aus dem man isst (veggy, Grießbrei, alles)
Beim Betreten des AYCE spielt eine kurze Sequenz (siehe Part 6)
## Part 6
~~Man hat gesehen, wie man beim Betreten etwas verloren hat. Ein Huhn greift es und rennt weg. [cut]~~
~~Kommt man wieder raus, grübelt der Spieler, dass er das Huhn finden muss, was gerade wegrennt. Das rennt einmal durchs Dorf.~~
~~Es verliert Papiere. Sammelt man die Papiere auf, hat man auf einmal einen Kalender.~~
~~Im Kalender kreuzt man an, wann man Zeit für die Fahrt hat. (An/Abreisetag)~~
Erstmal einfacher: Ticketfrau fragt nach dem Anreisedatum.
## Part 7
Im Shop kann man die gesammelten Waren gegen Geld eintauschen und sich Schrott kaufen. Im Laden steht Hugo, dem man eine
Kugel anhängen kann (Achievement!).
## Part 8
Am anderen Ende des Dorfs ist das Verkehrszentrum. Eine Brücke führt auf eine Insel. Am Ufer liegt ein Schlauchboot (individuelle Anreise).
Am Fahrkartenschalter kann man sich Tickets kaufen. Der Verkäufer passt auf, dass man das Schlauchboot nehmen muss, wenn man
später kommt. Er verleiht auch Fahrräder (same here).
## Part 9
Schlüsselszene!
Man geht ins Gästehaus schlafen. Wilde sinnlose Einblendungen. PARTY!
Bild verschwimmt, man wacht auf der anderen Seite des Ufers auf, man muss sich um den Rückweg kümmern. (hier irgendwas mit Pauls Anlage?)
Man kann einfach in die bereitstehende Bahn steigen, bzw das Rad greifen, was an der Brücke steht. (oder das Schlauchboot).
Bahn und Rad sind weg, wenn man früher abreist.
## Part 10
Während der Fahrt blendet das Bild über. Man sitzt an einem Tisch mit Brief, auf dem alles steht. Er ist adressiert an die Orga
der Fahrt.
Brief absenden = anmelden!
## ABSPANN
Starwars like text?
# Wilde Ideen
- Man kann in die Fenster im Dorf gucken, dahinter sind sinnlose GIFs
- ...
\ No newline at end of file
registration-system/view/signups/game1/chars/bernd.png

44.1 KiB

File suppressed by a .gitattributes entry or the file's encoding is unsupported.
registration-system/view/signups/game1/graphics/bernd.png

12.1 KiB

registration-system/view/signups/game1/graphics/bernd_logo.png

3.97 KiB