JFIF $ d d 7 * Z qn )ZP 0 !1 A "#a$2Qr D8 a Ri [f \m I ykI w0 c u F c Rı?lO7 к _f˓ [C $殷WF< _W ԣ s Kc ëI zyQy /_LK ℂ ;C",p F A : /] =H ~ , l s / 9 ć: [=/#f ; ) x { ٛE Q )~ = 𘙲r*2~ a _V = ' ku m F D } KYYC )( { * g& f `툪 r y ` = ^ c J. I ]( * `wq 1dđ #̩ ͑ 0 ; H ] u 搂 @:~ ו K L N s h } O I R* 8 :2 ! lD JV o ( 3 = M ( z Ȱ+i *N A r6K n S l ) ! J J Ӂ* % ݉?|D } d5: eP0 R; {$X' x F @ .ÊB {,WJ uQ ɲRI ;9 Q E琯 6 2fT .DU J ;*c P A\IL Nj! J ۱+ O\ ͔ ] ޒ S J ȧ c%A N ol ՎprU L Zԛe r E2= X D Xg VQeӓ k y P7 U* o m Q I s ,K `) 6\G3t?pgjr m ۛجw luGt f h 9uyP 0D;Uڽ"OXl i f $ ) &|ML 0 Z rm1 [ H XP l P R0 'G=i 2N +0 e 2 ]] 9 VT P O 7 h(F * 癈 ' = Q VZD F,d ߬ ~ T X G[ `le 69C R(!S2! P < 0 x < !1AQ "Raq 02Br #S CTb ? Ζ "]mH5WR 7 k.ۛ ! } Q~ + yԏ z |@ T20 S~ K e k *zF f^2X *( @ 8 r ? C I uI|֓>^Ex LgNU Y+{.R Ѫ τV YT D I 6 2 '8Y2 7'\T P.6 d &˦ @V q i |8 -O Ε ] ʔ U= T L 8= ;6c | !qfF3 a ů& ~$ l} 'NW U s$U k^S V : U#6w + +s &r+n ڐ { @ 29gL u " T Ù M=6 (^ "7 r}=6Yݾ lC u hquymp Ǧ G jhs ǜNl ɻ} o 7 #S6 a w 4 ! OS r D 5 7 % | ?x> L | / nD 6?/8 w # [ ) L 7 +6〼T A T g ! %5 Mm Z /c -{1_Je "| ^$ 'O & ޱմ < H vNqϡQ$ < 6 &Nݛ ֨tǻN (9 n ru~'όN sMG& ,uH Kw *Ī 5@ u6 BԒ i YN * f 0 _ GhKW u lT <nj- 0{ M L~ | /a v\ E = ?1 \ɟuq Ђ Y O a K ޡP q $ H8o Q˼EV ~ k 0 h' L Pp M -M" m^ !6l nմ 쮝C U T . ! :vMǨb h ډ Vc r @~p # !1QAa q ? AL0L x LU 4 d ; x " 16ad0 7.\ߋ 0 = P l v/ " c A Ay A|2pO8"d MV #1] = \ " ˡ ] k v I9 d ۓ & q ) ǐq E ꞅ v "P )q X &Q З non]я u ג./ ; gZ$ M QР 2M ]h ni 0 P $ێ 3CɏGjώy : m c # S_ l@ '_ \m|C 2`K _ 1 cIvGc $? PCQ S+D ? K aײ k Fr b 8 ύ NEدg ĝ U 3 6 #Ik+ v { v i ( ވ ? a e) X xy/*@Q Ǽ Ծ ) $ IWO l c G; !i k{ gOŀ L ('x T rb $ w) R $ & N1E td U3Uȉ1p M"N* (DNy d96.(jQ) X 5 c QɎMy W ? Q *!R > 6=7)Xj 5`J ] e 8%t ! + ' ! 1Q 5 !1 AQaq ё #2 "0BRb ? G t^ ## .l lQ T $ v , ,m 㵜5u bV =sY+ @d { N ! dn O < .- B; _w J t 6;Q Jd. Q c%p{ 1 ,sND dF H I0 Гo X ш e黅X ۢ F :)[ F G X ƹ / w _c MeD ,ʡc c . W D tA $ j@ : ) - #u c1< @ۗ9F ) KJ- hpP] _ x [ q B lb p ʖ w q " LFGd ƶ * s +ډ_Zc " ? % t[I P 6 J ]# =ɺ V v v CGs Gh1 > )6 |e y ? L ӣ m,4 G W Ui ` ] uJVo VDG< SB 6ϏQ @ TiU l y O U 0 kfV ~ ~}S Z @ *WU Ui ## ; s /[ = ! 7}" W N ] ' (L ! ~ y5 g9T̅J kbM' +s :S +B) v @ M j e C f j E 0 Y\Qn z G 1 д~ W o{T 9?` Rm yhsy3 !HAD ] m c1 ~ 2 L S u7x T ;j$ `} 4-> L# vzŏ I L S ֭ T { r jGK C ; b pU= - ` Bs K. S F w4 M q] Z dH S 0 ) tLg
/**
* tinymce_mce_popup.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
var tinymce, tinyMCE;
/**
* TinyMCE popup/dialog helper class. This gives you easy access to the
* parent editor instance and a bunch of other things. It's higly recommended
* that you load this script into your dialogs.
*
* @static
* @class tinyMCEPopup
*/
var tinyMCEPopup = {
/**
* Initializes the popup this will be called automatically.
*
* @method init
*/
init: function () {
var self = this, parentWin, settings, uiWindow;
// Find window & API
parentWin = self.getWin();
tinymce = tinyMCE = parentWin.tinymce;
self.editor = tinymce.EditorManager.activeEditor;
self.params = self.editor.windowManager.getParams();
uiWindow = self.editor.windowManager.windows[self.editor.windowManager.windows.length - 1];
self.features = uiWindow.features;
self.uiWindow = uiWindow;
settings = self.editor.settings;
// Setup popup CSS path(s)
if (settings.popup_css !== false) {
if (settings.popup_css) {
settings.popup_css = self.editor.documentBaseURI.toAbsolute(settings.popup_css);
} else {
settings.popup_css = self.editor.baseURI.toAbsolute("plugins/compat3x/css/dialog.css");
}
}
if (settings.popup_css_add) {
settings.popup_css += ',' + self.editor.documentBaseURI.toAbsolute(settings.popup_css_add);
}
// Setup local DOM
self.dom = self.editor.windowManager.createInstance('tinymce.dom.DOMUtils', document, {
ownEvents: true,
proxy: tinyMCEPopup._eventProxy
});
self.dom.bind(window, 'ready', self._onDOMLoaded, self);
// Enables you to skip loading the default css
if (self.features.popup_css !== false) {
self.dom.loadCSS(self.features.popup_css || self.editor.settings.popup_css);
}
// Setup on init listeners
self.listeners = [];
/**
* Fires when the popup is initialized.
*
* @event onInit
* @param {tinymce.Editor} editor Editor instance.
* @example
* // Alerts the selected contents when the dialog is loaded
* tinyMCEPopup.onInit.add(function(ed) {
* alert(ed.selection.getContent());
* });
*
* // Executes the init method on page load in some object using the SomeObject scope
* tinyMCEPopup.onInit.add(SomeObject.init, SomeObject);
*/
self.onInit = {
add: function (func, scope) {
self.listeners.push({ func: func, scope: scope });
}
};
self.isWindow = !self.getWindowArg('mce_inline');
self.id = self.getWindowArg('mce_window_id');
},
/**
* Returns the reference to the parent window that opened the dialog.
*
* @method getWin
* @return {Window} Reference to the parent window that opened the dialog.
*/
getWin: function () {
// Added frameElement check to fix bug: #2817583
return (!window.frameElement && window.dialogArguments) || opener || parent || top;
},
/**
* Returns a window argument/parameter by name.
*
* @method getWindowArg
* @param {String} name Name of the window argument to retrieve.
* @param {String} defaultValue Optional default value to return.
* @return {String} Argument value or default value if it wasn't found.
*/
getWindowArg: function (name, defaultValue) {
var value = this.params[name];
return tinymce.is(value) ? value : defaultValue;
},
/**
* Returns a editor parameter/config option value.
*
* @method getParam
* @param {String} name Name of the editor config option to retrieve.
* @param {String} defaultValue Optional default value to return.
* @return {String} Parameter value or default value if it wasn't found.
*/
getParam: function (name, defaultValue) {
return this.editor.getParam(name, defaultValue);
},
/**
* Returns a language item by key.
*
* @method getLang
* @param {String} name Language item like mydialog.something.
* @param {String} defaultValue Optional default value to return.
* @return {String} Language value for the item like "my string" or the default value if it wasn't found.
*/
getLang: function (name, defaultValue) {
return this.editor.getLang(name, defaultValue);
},
/**
* Executed a command on editor that opened the dialog/popup.
*
* @method execCommand
* @param {String} cmd Command to execute.
* @param {Boolean} ui Optional boolean value if the UI for the command should be presented or not.
* @param {Object} val Optional value to pass with the comman like an URL.
* @param {Object} a Optional arguments object.
*/
execCommand: function (cmd, ui, val, args) {
args = args || {};
args.skip_focus = 1;
this.restoreSelection();
return this.editor.execCommand(cmd, ui, val, args);
},
/**
* Resizes the dialog to the inner size of the window. This is needed since various browsers
* have different border sizes on windows.
*
* @method resizeToInnerSize
*/
resizeToInnerSize: function () {
/*var self = this;
// Detach it to workaround a Chrome specific bug
// https://sourceforge.net/tracker/?func=detail&atid=635682&aid=2926339&group_id=103281
setTimeout(function() {
var vp = self.dom.getViewPort(window);
self.editor.windowManager.resizeBy(
self.getWindowArg('mce_width') - vp.w,
self.getWindowArg('mce_height') - vp.h,
self.id || window
);
}, 10);*/
},
/**
* Will executed the specified string when the page has been loaded. This function
* was added for compatibility with the 2.x branch.
*
* @method executeOnLoad
* @param {String} evil String to evalutate on init.
*/
executeOnLoad: function (evil) {
this.onInit.add(function () {
eval(evil);
});
},
/**
* Stores the current editor selection for later restoration. This can be useful since some browsers
* looses it's selection if a control element is selected/focused inside the dialogs.
*
* @method storeSelection
*/
storeSelection: function () {
this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark(1);
},
/**
* Restores any stored selection. This can be useful since some browsers
* looses it's selection if a control element is selected/focused inside the dialogs.
*
* @method restoreSelection
*/
restoreSelection: function () {
var self = tinyMCEPopup;
if (!self.isWindow && tinymce.isIE) {
self.editor.selection.moveToBookmark(self.editor.windowManager.bookmark);
}
},
/**
* Loads a specific dialog language pack. If you pass in plugin_url as a argument
* when you open the window it will load the <plugin url>/langs/<code>_dlg.js lang pack file.
*
* @method requireLangPack
*/
requireLangPack: function () {
var self = this, url = self.getWindowArg('plugin_url') || self.getWindowArg('theme_url'), settings = self.editor.settings, lang;
if (settings.language !== false) {
lang = settings.language || "en";
}
if (url && lang && self.features.translate_i18n !== false && settings.language_load !== false) {
url += '/langs/' + lang + '_dlg.js';
if (!tinymce.ScriptLoader.isDone(url)) {
document.write('<script type="text/javascript" src="' + url + '"></script>');
tinymce.ScriptLoader.markDone(url);
}
}
},
/**
* Executes a color picker on the specified element id. When the user
* then selects a color it will be set as the value of the specified element.
*
* @method pickColor
* @param {DOMEvent} e DOM event object.
* @param {string} element_id Element id to be filled with the color value from the picker.
*/
pickColor: function (e, element_id) {
var el = document.getElementById(element_id), colorPickerCallback = this.editor.settings.color_picker_callback;
if (colorPickerCallback) {
colorPickerCallback.call(
this.editor,
function (value) {
el.value = value;
try {
el.onchange();
} catch (ex) {
// Try fire event, ignore errors
}
},
el.value
);
}
},
/**
* Opens a filebrowser/imagebrowser this will set the output value from
* the browser as a value on the specified element.
*
* @method openBrowser
* @param {string} element_id Id of the element to set value in.
* @param {string} type Type of browser to open image/file/flash.
* @param {string} option Option name to get the file_broswer_callback function name from.
*/
openBrowser: function (element_id, type) {
tinyMCEPopup.restoreSelection();
this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window);
},
/**
* Creates a confirm dialog. Please don't use the blocking behavior of this
* native version use the callback method instead then it can be extended.
*
* @method confirm
* @param {String} t Title for the new confirm dialog.
* @param {function} cb Callback function to be executed after the user has selected ok or cancel.
* @param {Object} s Optional scope to execute the callback in.
*/
confirm: function (t, cb, s) {
this.editor.windowManager.confirm(t, cb, s, window);
},
/**
* Creates a alert dialog. Please don't use the blocking behavior of this
* native version use the callback method instead then it can be extended.
*
* @method alert
* @param {String} tx Title for the new alert dialog.
* @param {function} cb Callback function to be executed after the user has selected ok.
* @param {Object} s Optional scope to execute the callback in.
*/
alert: function (tx, cb, s) {
this.editor.windowManager.alert(tx, cb, s, window);
},
/**
* Closes the current window.
*
* @method close
*/
close: function () {
var t = this;
// To avoid domain relaxing issue in Opera
function close() {
t.editor.windowManager.close(window);
tinymce = tinyMCE = t.editor = t.params = t.dom = t.dom.doc = null; // Cleanup
}
if (tinymce.isOpera) {
t.getWin().setTimeout(close, 0);
} else {
close();
}
},
// Internal functions
_restoreSelection: function () {
var e = window.event.srcElement;
if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) {
tinyMCEPopup.restoreSelection();
}
},
/* _restoreSelection : function() {
var e = window.event.srcElement;
// If user focus a non text input or textarea
if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text')
tinyMCEPopup.restoreSelection();
},*/
_onDOMLoaded: function () {
var t = tinyMCEPopup, ti = document.title, h, nv;
// Translate page
if (t.features.translate_i18n !== false) {
var map = {
"update": "Ok",
"insert": "Ok",
"cancel": "Cancel",
"not_set": "--",
"class_name": "Class name",
"browse": "Browse"
};
var langCode = (tinymce.settings ? tinymce.settings : t.editor.settings).language || 'en';
for (var key in map) {
tinymce.i18n.data[langCode + "." + key] = tinymce.i18n.translate(map[key]);
}
h = document.body.innerHTML;
// Replace a=x with a="x" in IE
if (tinymce.isIE) {
h = h.replace(/ (value|title|alt)=([^"][^\s>]+)/gi, ' $1="$2"');
}
document.dir = t.editor.getParam('directionality', '');
if ((nv = t.editor.translate(h)) && nv != h) {
document.body.innerHTML = nv;
}
if ((nv = t.editor.translate(ti)) && nv != ti) {
document.title = ti = nv;
}
}
if (!t.editor.getParam('browser_preferred_colors', false) || !t.isWindow) {
t.dom.addClass(document.body, 'forceColors');
}
document.body.style.display = '';
// Restore selection in IE when focus is placed on a non textarea or input element of the type text
if (tinymce.Env.ie) {
if (tinymce.Env.ie < 11) {
document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection);
// Add base target element for it since it would fail with modal dialogs
t.dom.add(t.dom.select('head')[0], 'base', { target: '_self' });
} else {
document.addEventListener('mouseup', tinyMCEPopup._restoreSelection, false);
}
}
t.restoreSelection();
t.resizeToInnerSize();
// Set inline title
if (!t.isWindow) {
t.editor.windowManager.setTitle(window, ti);
} else {
window.focus();
}
if (!tinymce.isIE && !t.isWindow) {
t.dom.bind(document, 'focus', function () {
t.editor.windowManager.focus(t.id);
});
}
// Patch for accessibility
tinymce.each(t.dom.select('select'), function (e) {
e.onkeydown = tinyMCEPopup._accessHandler;
});
// Call onInit
// Init must be called before focus so the selection won't get lost by the focus call
tinymce.each(t.listeners, function (o) {
o.func.call(o.scope, t.editor);
});
// Move focus to window
if (t.getWindowArg('mce_auto_focus', true)) {
window.focus();
// Focus element with mceFocus class
tinymce.each(document.forms, function (f) {
tinymce.each(f.elements, function (e) {
if (t.dom.hasClass(e, 'mceFocus') && !e.disabled) {
e.focus();
return false; // Break loop
}
});
});
}
document.onkeyup = tinyMCEPopup._closeWinKeyHandler;
if ('textContent' in document) {
t.uiWindow.getEl('head').firstChild.textContent = document.title;
} else {
t.uiWindow.getEl('head').firstChild.innerText = document.title;
}
},
_accessHandler: function (e) {
e = e || window.event;
if (e.keyCode == 13 || e.keyCode == 32) {
var elm = e.target || e.srcElement;
if (elm.onchange) {
elm.onchange();
}
return tinymce.dom.Event.cancel(e);
}
},
_closeWinKeyHandler: function (e) {
e = e || window.event;
if (e.keyCode == 27) {
tinyMCEPopup.close();
}
},
_eventProxy: function (id) {
return function (evt) {
tinyMCEPopup.dom.events.callNativeHandler(id, evt);
};
}
};
tinyMCEPopup.init();
tinymce.util.Dispatcher = function (scope) {
this.scope = scope || this;
this.listeners = [];
this.add = function (callback, scope) {
this.listeners.push({ cb: callback, scope: scope || this.scope });
return callback;
};
this.addToTop = function (callback, scope) {
var self = this, listener = { cb: callback, scope: scope || self.scope };
// Create new listeners if addToTop is executed in a dispatch loop
if (self.inDispatch) {
self.listeners = [listener].concat(self.listeners);
} else {
self.listeners.unshift(listener);
}
return callback;
};
this.remove = function (callback) {
var listeners = this.listeners, output = null;
tinymce.each(listeners, function (listener, i) {
if (callback == listener.cb) {
output = listener;
listeners.splice(i, 1);
return false;
}
});
return output;
};
this.dispatch = function () {
var self = this, returnValue, args = arguments, i, listeners = self.listeners, listener;
self.inDispatch = true;
// Needs to be a real loop since the listener count might change while looping
// And this is also more efficient
for (i = 0; i < listeners.length; i++) {
listener = listeners[i];
returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]);
if (returnValue === false) {
break;
}
}
self.inDispatch = false;
return returnValue;
};
};