From d825155631157f106b7ec237c34ad216f9d8f8f7 Mon Sep 17 00:00:00 2001 From: desrosj Date: Sun, 3 Nov 2019 15:31:02 +0000 Subject: [PATCH] External Libraries: Update Plupload from 2.1.9 to 2.3.6. This change also updates the MoxieJS dependency from 1.3.5 to 1.5.7, converts Plupload to a dependency in NPM, and integrates all relevant parts into the build process. For a full list of upstream changes, see https://github.com/moxiecode/plupload/compare/v2.1.9...v2.3.6. Props desrosj, hareesh-pillai. Fixes #48277. Built from https://develop.svn.wordpress.org/trunk@46634 git-svn-id: http://core.svn.wordpress.org/trunk@46434 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/js/plupload/handlers.js | 22 +- wp-includes/js/plupload/license.txt | 339 -- wp-includes/js/plupload/moxie.js | 5735 +++++++++++++++-------- wp-includes/js/plupload/moxie.min.js | 2 +- wp-includes/js/plupload/plupload.js | 542 ++- wp-includes/js/plupload/plupload.min.js | 2 +- wp-includes/js/plupload/wp-plupload.js | 16 +- wp-includes/script-loader.php | 6 +- wp-includes/version.php | 2 +- 9 files changed, 4130 insertions(+), 2536 deletions(-) delete mode 100644 wp-includes/js/plupload/license.txt diff --git a/wp-includes/js/plupload/handlers.js b/wp-includes/js/plupload/handlers.js index 9116a64eac..8c39578075 100644 --- a/wp-includes/js/plupload/handlers.js +++ b/wp-includes/js/plupload/handlers.js @@ -216,10 +216,10 @@ function itemAjaxError( id, message ) { return; item.html( '
' + - '' + pluploadL10n.dismiss + '' + - '' + pluploadL10n.error_uploading.replace( '%s', jQuery.trim( filename )) + ' ' + - message + - '
' ).data( 'last-err', id ); + '' + pluploadL10n.dismiss + '' + + '' + pluploadL10n.error_uploading.replace( '%s', jQuery.trim( filename )) + ' ' + + message + + '' ).data( 'last-err', id ); } function deleteSuccess( data ) { @@ -323,10 +323,10 @@ function uploadError( fileObj, errorCode, message, up ) { case plupload.SECURITY_ERROR: wpQueueError( pluploadL10n.security_error ); break; -/* case plupload.UPLOAD_ERROR.UPLOAD_STOPPED: - case plupload.UPLOAD_ERROR.FILE_CANCELLED: - jQuery( '#media-item-' + fileObj.id ).remove(); - break;*/ + /* case plupload.UPLOAD_ERROR.UPLOAD_STOPPED: + case plupload.UPLOAD_ERROR.FILE_CANCELLED: + jQuery( '#media-item-' + fileObj.id ).remove(); + break;*/ default: wpFileError( fileObj, pluploadL10n.default_error ); } @@ -461,7 +461,7 @@ jQuery( document ).ready( function( $ ) { action: 'media-create-image-subsizes', _wpnonce: wpUploaderInit.multipart_params._wpnonce, attachment_id: id, - _wp_upload_failed_cleanup: true, + _wp_upload_failed_cleanup: true } }); @@ -489,7 +489,7 @@ jQuery( document ).ready( function( $ ) { action: 'media-create-image-subsizes', _wpnonce: wpUploaderInit.multipart_params._wpnonce, attachment_id: id, - _legacy_support: 'true', + _legacy_support: 'true' } }).done( function( response ) { var message; @@ -512,7 +512,7 @@ jQuery( document ).ready( function( $ ) { wpQueueError( pluploadL10n.http_error_image ); }); - } + }; // init and set the uploader uploader_init = function() { diff --git a/wp-includes/js/plupload/license.txt b/wp-includes/js/plupload/license.txt deleted file mode 100644 index d511905c16..0000000000 --- a/wp-includes/js/plupload/license.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/wp-includes/js/plupload/moxie.js b/wp-includes/js/plupload/moxie.js index c7d26f4c4e..7568395346 100644 --- a/wp-includes/js/plupload/moxie.js +++ b/wp-includes/js/plupload/moxie.js @@ -1,7 +1,7 @@ ;var MXI_DEBUG = false; /** * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill - * v1.3.5 + * v1.5.7 * * Copyright 2013, Moxiecode Systems AB * Released under GPL License. @@ -9,17 +9,27 @@ * License: http://www.plupload.com/license * Contributing: http://www.plupload.com/contributing * - * Date: 2016-05-15 + * Date: 2017-11-03 */ +;(function (global, factory) { + var extract = function() { + var ctx = {}; + factory.apply(ctx, arguments); + return ctx.moxie; + }; + + if (typeof define === "function" && define.amd) { + define("moxie", [], extract); + } else if (typeof module === "object" && module.exports) { + module.exports = extract(); + } else { + global.moxie = extract(); + } +}(this || window, function() { /** * Compiled inline version. (Library mode) */ -/** - * Modified for WordPress, Silverlight and Flash runtimes support was removed. - * See https://core.trac.wordpress.org/ticket/41755. - */ - /*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */ /*globals $code */ @@ -110,18 +120,23 @@ * Contributing: http://www.plupload.com/contributing */ +/** +@class moxie/core/utils/Basic +@public +@static +*/ + define('moxie/core/utils/Basic', [], function() { /** Gets the true type of the built-in object (better version of typeof). @author Angus Croll (http://javascriptweblog.wordpress.com/) @method typeOf - @for Utils @static @param {Object} o Object to check. @return {String} Object [[Class]] */ - var typeOf = function(o) { + function typeOf(o) { var undef; if (o === undef) { @@ -134,10 +149,10 @@ define('moxie/core/utils/Basic', [], function() { // the snippet below is awesome, however it fails to detect null, undefined and arguments types in IE lte 8 return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); - }; - + } + /** - Extends the specified object with another object. + Extends the specified object with another object(s). @method extend @static @@ -145,25 +160,131 @@ define('moxie/core/utils/Basic', [], function() { @param {Object} [obj]* Multiple objects to extend with. @return {Object} Same as target, the extended object. */ - var extend = function(target) { - var undef; + function extend() { + return merge(false, false, arguments); + } - each(arguments, function(arg, i) { + + /** + Extends the specified object with another object(s), but only if the property exists in the target. + + @method extendIf + @static + @param {Object} target Object to extend. + @param {Object} [obj]* Multiple objects to extend with. + @return {Object} Same as target, the extended object. + */ + function extendIf() { + return merge(true, false, arguments); + } + + + function extendImmutable() { + return merge(false, true, arguments); + } + + + function extendImmutableIf() { + return merge(true, true, arguments); + } + + + function clone(value) { + switch (typeOf(value)) { + case 'array': + return merge(false, true, [[], value]); + + case 'object': + return merge(false, true, [{}, value]); + + default: + return value; + } + } + + + function shallowCopy(obj) { + switch (typeOf(obj)) { + case 'array': + return Array.prototype.slice.call(obj); + + case 'object': + return extend({}, obj); + } + return obj; + } + + + function merge(strict, immutable, args) { + var undef; + var target = args[0]; + + each(args, function(arg, i) { if (i > 0) { each(arg, function(value, key) { - if (value !== undef) { - if (typeOf(target[key]) === typeOf(value) && !!~inArray(typeOf(value), ['array', 'object'])) { - extend(target[key], value); - } else { - target[key] = value; - } + var isComplex = inArray(typeOf(value), ['array', 'object']) !== -1; + + if (value === undef || strict && target[key] === undef) { + return true; + } + + if (isComplex && immutable) { + value = shallowCopy(value); + } + + if (typeOf(target[key]) === typeOf(value) && isComplex) { + merge(strict, immutable, [target[key], value]); + } else { + target[key] = value; } }); } }); + return target; - }; - + } + + + /** + A way to inherit one `class` from another in a consisstent way (more or less) + + @method inherit + @static + @since >1.4.1 + @param {Function} child + @param {Function} parent + @return {Function} Prepared constructor + */ + function inherit(child, parent) { + // copy over all parent properties + for (var key in parent) { + if ({}.hasOwnProperty.call(parent, key)) { + child[key] = parent[key]; + } + } + + // give child `class` a place to define its own methods + function ctor() { + this.constructor = child; + + if (MXI_DEBUG) { + var getCtorName = function(fn) { + var m = fn.toString().match(/^function\s([^\(\s]+)/); + return m ? m[1] : false; + }; + + this.ctorName = getCtorName(child); + } + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + + // keep a way to reference parent methods + child.parent = parent.prototype; + return child; + } + + /** Executes the callback function for each item in array/object. If you return false in the callback it will break the loop. @@ -173,18 +294,17 @@ define('moxie/core/utils/Basic', [], function() { @param {Object} obj Object to iterate. @param {function} callback Callback function to execute for each item. */ - var each = function(obj, callback) { + function each(obj, callback) { var length, key, i, undef; if (obj) { - if (typeOf(obj.length) === 'number') { // it might be Array, FileList or even arguments object - // Loop array items - for (i = 0, length = obj.length; i < length; i++) { - if (callback(obj[i], i) === false) { - return; - } - } - } else if (typeOf(obj) === 'object') { + try { + length = obj.length; + } catch(ex) { + length = undef; + } + + if (length === undef || typeof(length) !== 'number') { // Loop object items for (key in obj) { if (obj.hasOwnProperty(key)) { @@ -193,19 +313,26 @@ define('moxie/core/utils/Basic', [], function() { } } } + } else { + // Loop array items + for (i = 0; i < length; i++) { + if (callback(obj[i], i) === false) { + return; + } + } } } - }; + } /** Checks if object is empty. - + @method isEmptyObj @static @param {Object} o Object to check. @return {Boolean} */ - var isEmptyObj = function(obj) { + function isEmptyObj(obj) { var prop; if (!obj || typeOf(obj) !== 'object') { @@ -217,7 +344,7 @@ define('moxie/core/utils/Basic', [], function() { } return true; - }; + } /** Recieve an array of functions (usually async) to call in sequence, each function @@ -231,7 +358,7 @@ define('moxie/core/utils/Basic', [], function() { @param {Array} queue Array of functions to call in sequence @param {Function} cb Main callback that is called in the end, or in case of error */ - var inSeries = function(queue, cb) { + function inSeries(queue, cb) { var i = 0, length = queue.length; if (typeOf(cb) !== 'function') { @@ -251,12 +378,12 @@ define('moxie/core/utils/Basic', [], function() { } } callNext(i); - }; + } /** Recieve an array of functions (usually async) to call in parallel, each function - receives a callback as first argument that it should call, when it completes. After + receives a callback as first argument that it should call, when it completes. After everything is complete, main callback is called. Passing truthy value to the callback as a first argument will interrupt the process and invoke main callback immediately. @@ -264,9 +391,9 @@ define('moxie/core/utils/Basic', [], function() { @method inParallel @static @param {Array} queue Array of functions to call in sequence - @param {Function} cb Main callback that is called in the end, or in case of error + @param {Function} cb Main callback that is called in the end, or in case of erro */ - var inParallel = function(queue, cb) { + function inParallel(queue, cb) { var count = 0, num = queue.length, cbArgs = new Array(num); each(queue, function(fn, i) { @@ -274,7 +401,7 @@ define('moxie/core/utils/Basic', [], function() { if (error) { return cb(error); } - + var args = [].slice.call(arguments); args.shift(); // strip error - undefined or not @@ -284,27 +411,27 @@ define('moxie/core/utils/Basic', [], function() { if (count === num) { cbArgs.unshift(null); cb.apply(this, cbArgs); - } + } }); }); - }; - - + } + + /** Find an element in array and return it's index if present, otherwise return -1. - + @method inArray @static @param {Mixed} needle Element to find @param {Array} array @return {Int} Index of the element, or -1 if not found */ - var inArray = function(needle, array) { + function inArray(needle, array) { if (array) { if (Array.prototype.indexOf) { return Array.prototype.indexOf.call(array, needle); } - + for (var i = 0, length = array.length; i < length; i++) { if (array[i] === needle) { return i; @@ -312,7 +439,7 @@ define('moxie/core/utils/Basic', [], function() { } } return -1; - }; + } /** @@ -324,7 +451,7 @@ define('moxie/core/utils/Basic', [], function() { @param {Array} array @return {Array|Boolean} */ - var arrayDiff = function(needles, array) { + function arrayDiff(needles, array) { var diff = []; if (typeOf(needles) !== 'array') { @@ -338,10 +465,10 @@ define('moxie/core/utils/Basic', [], function() { for (var i in needles) { if (inArray(needles[i], array) === -1) { diff.push(needles[i]); - } + } } return diff.length ? diff : false; - }; + } /** @@ -353,7 +480,7 @@ define('moxie/core/utils/Basic', [], function() { @param {Array} array2 @return {Array} Intersection of two arrays or null if there is none */ - var arrayIntersect = function(array1, array2) { + function arrayIntersect(array1, array2) { var result = []; each(array1, function(item) { if (inArray(item, array2) !== -1) { @@ -361,18 +488,18 @@ define('moxie/core/utils/Basic', [], function() { } }); return result.length ? result : null; - }; - - + } + + /** Forces anything into an array. - + @method toArray @static @param {Object} obj Object with length field. @return {Array} Array object containing all items. */ - var toArray = function(obj) { + function toArray(obj) { var i, arr = []; for (i = 0; i < obj.length; i++) { @@ -380,15 +507,15 @@ define('moxie/core/utils/Basic', [], function() { } return arr; - }; - - + } + + /** Generates an unique ID. The only way a user would be able to get the same ID is if the two persons - at the same exact millisecond manage to get the same 5 random numbers between 0-65535; it also uses - a counter so each ID is guaranteed to be unique for the given page. It is more probable for the earth + at the same exact millisecond manage to get the same 5 random numbers between 0-65535; it also uses + a counter so each ID is guaranteed to be unique for the given page. It is more probable for the earth to be hit with an asteroid. - + @method guid @static @param {String} prefix to prepend (by default 'o' will be prepended). @@ -397,48 +524,48 @@ define('moxie/core/utils/Basic', [], function() { */ var guid = (function() { var counter = 0; - + return function(prefix) { var guid = new Date().getTime().toString(32), i; for (i = 0; i < 5; i++) { guid += Math.floor(Math.random() * 65535).toString(32); } - + return (prefix || 'o_') + guid + (counter++).toString(32); }; }()); - + /** Trims white spaces around the string - + @method trim @static @param {String} str @return {String} */ - var trim = function(str) { + function trim(str) { if (!str) { return str; } return String.prototype.trim ? String.prototype.trim.call(str) : str.toString().replace(/^\s*/, '').replace(/\s*$/, ''); - }; + } /** Parses the specified size string into a byte value. For example 10kb becomes 10240. - + @method parseSizeStr @static @param {String/Number} size String to parse or number to just pass through. @return {Number} Size in bytes. */ - var parseSizeStr = function(size) { + function parseSizeStr(size) { if (typeof(size) !== 'string') { return size; } - + var muls = { t: 1099511627776, g: 1073741824, @@ -447,16 +574,15 @@ define('moxie/core/utils/Basic', [], function() { }, mul; - size = /^([0-9\.]+)([tmgk]?)$/.exec(size.toLowerCase().replace(/[^0-9\.tmkg]/g, '')); mul = size[2]; size = +size[1]; - + if (muls.hasOwnProperty(mul)) { size *= muls[mul]; } return Math.floor(size); - }; + } /** @@ -465,20 +591,50 @@ define('moxie/core/utils/Basic', [], function() { * @param {String} str String with tokens * @return {String} String with replaced tokens */ - var sprintf = function(str) { + function sprintf(str) { var args = [].slice.call(arguments, 1); - return str.replace(/%[a-z]/g, function() { + return str.replace(/%([a-z])/g, function($0, $1) { var value = args.shift(); - return typeOf(value) !== 'undefined' ? value : ''; + + switch ($1) { + case 's': + return value + ''; + + case 'd': + return parseInt(value, 10); + + case 'f': + return parseFloat(value); + + case 'c': + return ''; + + default: + return value; + } }); - }; - + } + + + + function delay(cb, timeout) { + var self = this; + setTimeout(function() { + cb.call(self); + }, timeout || 1); + } + return { guid: guid, typeOf: typeOf, extend: extend, + extendIf: extendIf, + extendImmutable: extendImmutable, + extendImmutableIf: extendImmutableIf, + clone: clone, + inherit: inherit, each: each, isEmptyObj: isEmptyObj, inSeries: inSeries, @@ -489,7 +645,193 @@ define('moxie/core/utils/Basic', [], function() { toArray: toArray, trim: trim, sprintf: sprintf, - parseSizeStr: parseSizeStr + parseSizeStr: parseSizeStr, + delay: delay + }; +}); + +// Included from: src/javascript/core/utils/Encode.js + +/** + * Encode.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/core/utils/Encode +@public +@static +*/ + +define('moxie/core/utils/Encode', [], function() { + + /** + Encode string with UTF-8 + + @method utf8_encode + @static + @param {String} str String to encode + @return {String} UTF-8 encoded string + */ + var utf8_encode = function(str) { + return unescape(encodeURIComponent(str)); + }; + + /** + Decode UTF-8 encoded string + + @method utf8_decode + @static + @param {String} str String to decode + @return {String} Decoded string + */ + var utf8_decode = function(str_data) { + return decodeURIComponent(escape(str_data)); + }; + + /** + Decode Base64 encoded string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_decode.js + + @method atob + @static + @param {String} data String to decode + @return {String} Decoded string + */ + var atob = function(data, utf8) { + if (typeof(window.atob) === 'function') { + return utf8 ? utf8_decode(window.atob(data)) : window.atob(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Thunder.m + // + input by: Aman Gupta + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); + // * returns 1: 'Kevin van Zonneveld' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window.atob == 'function') { + // return atob(data); + //} + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + dec = "", + tmp_arr = []; + + if (!data) { + return data; + } + + data += ''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + + o1 = bits >> 16 & 0xff; + o2 = bits >> 8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1); + } else if (h4 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2); + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); + } + } while (i < data.length); + + dec = tmp_arr.join(''); + + return utf8 ? utf8_decode(dec) : dec; + }; + + /** + Base64 encode string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_encode.js + + @method btoa + @static + @param {String} data String to encode + @return {String} Base64 encoded string + */ + var btoa = function(data, utf8) { + if (utf8) { + data = utf8_encode(data); + } + + if (typeof(window.btoa) === 'function') { + return window.btoa(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Bayron Guevara + // + improved by: Thunder.m + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: RafaƂ Kukawski (http://kukawski.pl) + // * example 1: base64_encode('Kevin van Zonneveld'); + // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' + // mozilla has this native + // - but breaks in 2.0.0.12! + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + enc = "", + tmp_arr = []; + + if (!data) { + return data; + } + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1 << 16 | o2 << 8 | o3; + + h1 = bits >> 18 & 0x3f; + h2 = bits >> 12 & 0x3f; + h3 = bits >> 6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + var r = data.length % 3; + + return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); + }; + + + return { + utf8_encode: utf8_encode, + utf8_decode: utf8_decode, + atob: atob, + btoa: btoa }; }); @@ -505,10 +847,16 @@ define('moxie/core/utils/Basic', [], function() { * Contributing: http://www.plupload.com/contributing */ +/** +@class moxie/core/utils/Env +@public +@static +*/ + define("moxie/core/utils/Env", [ "moxie/core/utils/Basic" ], function(Basic) { - + /** * UAParser.js v0.7.7 * Lightweight JavaScript-based User-Agent string parser @@ -711,7 +1059,7 @@ define("moxie/core/utils/Env", [ var regexes = { browser : [[ - + // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet @@ -1046,85 +1394,119 @@ define("moxie/core/utils/Env", [ var can = (function() { var caps = { - define_property: (function() { - /* // currently too much extra code required, not exactly worth it - try { // as of IE8, getters/setters are supported only on DOM elements - var obj = {}; - if (Object.defineProperty) { - Object.defineProperty(obj, 'prop', { - enumerable: true, - configurable: true - }); - return true; - } - } catch(ex) {} + access_global_ns: function () { + return !!window.moxie; + }, - if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { + define_property: (function() { + /* // currently too much extra code required, not exactly worth it + try { // as of IE8, getters/setters are supported only on DOM elements + var obj = {}; + if (Object.defineProperty) { + Object.defineProperty(obj, 'prop', { + enumerable: true, + configurable: true + }); return true; - }*/ - return false; - }()), - - create_canvas: (function() { - // On the S60 and BB Storm, getContext exists, but always returns undefined - // so we actually have to call getContext() to verify - // github.com/Modernizr/Modernizr/issues/issue/97/ - var el = document.createElement('canvas'); - return !!(el.getContext && el.getContext('2d')); - }()), - - return_response_type: function(responseType) { - try { - if (Basic.inArray(responseType, ['', 'text', 'document']) !== -1) { - return true; - } else if (window.XMLHttpRequest) { - var xhr = new XMLHttpRequest(); - xhr.open('get', '/'); // otherwise Gecko throws an exception - if ('responseType' in xhr) { - xhr.responseType = responseType; - // as of 23.0.1271.64, Chrome switched from throwing exception to merely logging it to the console (why? o why?) - if (xhr.responseType !== responseType) { - return false; - } - return true; - } - } - } catch (ex) {} - return false; - }, - - // ideas for this heavily come from Modernizr (http://modernizr.com/) - use_data_uri: (function() { - var du = new Image(); - - du.onload = function() { - caps.use_data_uri = (du.width === 1 && du.height === 1); - }; - - setTimeout(function() { - du.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; - }, 1); - return false; - }()), - - use_data_uri_over32kb: function() { // IE8 - return caps.use_data_uri && (Env.browser !== 'IE' || Env.version >= 9); - }, - - use_data_uri_of: function(bytes) { - return (caps.use_data_uri && bytes < 33000 || caps.use_data_uri_over32kb()); - }, - - use_fileinput: function() { - if (navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)) { - return false; } + } catch(ex) {} - var el = document.createElement('input'); - el.setAttribute('type', 'file'); - return !el.disabled; + if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { + return true; + }*/ + return false; + }()), + + create_canvas: function() { + // On the S60 and BB Storm, getContext exists, but always returns undefined + // so we actually have to call getContext() to verify + // github.com/Modernizr/Modernizr/issues/issue/97/ + var el = document.createElement('canvas'); + var isSupported = !!(el.getContext && el.getContext('2d')); + caps.create_canvas = isSupported; + return isSupported; + }, + + return_response_type: function(responseType) { + try { + if (Basic.inArray(responseType, ['', 'text', 'document']) !== -1) { + return true; + } else if (window.XMLHttpRequest) { + var xhr = new XMLHttpRequest(); + xhr.open('get', '/'); // otherwise Gecko throws an exception + if ('responseType' in xhr) { + xhr.responseType = responseType; + // as of 23.0.1271.64, Chrome switched from throwing exception to merely logging it to the console (why? o why?) + if (xhr.responseType !== responseType) { + return false; + } + return true; + } + } + } catch (ex) {} + return false; + }, + + use_blob_uri: function() { + var URL = window.URL; + caps.use_blob_uri = (URL && + 'createObjectURL' in URL && + 'revokeObjectURL' in URL && + (Env.browser !== 'IE' || Env.verComp(Env.version, '11.0.46', '>=')) // IE supports createObjectURL, but not fully, for example it fails to use it as a src for the image + ); + return caps.use_blob_uri; + }, + + // ideas for this heavily come from Modernizr (http://modernizr.com/) + use_data_uri: (function() { + var du = new Image(); + + du.onload = function() { + caps.use_data_uri = (du.width === 1 && du.height === 1); + }; + + setTimeout(function() { + du.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; + }, 1); + return false; + }()), + + use_data_uri_over32kb: function() { // IE8 + return caps.use_data_uri && (Env.browser !== 'IE' || Env.version >= 9); + }, + + use_data_uri_of: function(bytes) { + return (caps.use_data_uri && bytes < 33000 || caps.use_data_uri_over32kb()); + }, + + use_fileinput: function() { + if (navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)) { + return false; } - }; + + var el = document.createElement('input'); + el.setAttribute('type', 'file'); + return caps.use_fileinput = !el.disabled; + }, + + use_webgl: function() { + var canvas = document.createElement('canvas'); + var gl = null, isSupported; + try { + gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); + } + catch(e) {} + + if (!gl) { // it seems that sometimes it doesn't throw exception, but still fails to get context + gl = null; + } + + isSupported = !!gl; + caps.use_webgl = isSupported; // save result of our check + canvas = undefined; + return isSupported; + } + }; return function(cap) { var args = [].slice.call(arguments); @@ -1141,7 +1523,7 @@ define("moxie/core/utils/Env", [ can: can, uaParser: UAParser, - + browser: uaResult.browser.name, version: uaResult.browser.version, os: uaResult.os.name, // everybody intuitively types it in a lowercase for some reason @@ -1149,6 +1531,8 @@ define("moxie/core/utils/Env", [ verComp: version_compare, + swf_url: "../flash/Moxie.swf", + xap_url: "../silverlight/Moxie.xap", global_event_dispatcher: "moxie.core.EventTarget.instance.dispatchEvent" }; @@ -1163,20 +1547,15 @@ define("moxie/core/utils/Env", [ }; Env.log = function() { - + function logObj(data) { // TODO: this should recursively print out the object in a pretty way console.appendChild(document.createTextNode(data + "\n")); } - var data = arguments[0]; - - if (Basic.typeOf(data) === 'string') { - data = Basic.sprintf.apply(this, arguments); - } - - if (window && window.console && window.console.log) { - window.console.log(data); + // if debugger present, IE8 might have window.console.log method, but not be able to apply on it (why...) + if (window && window.console && window.console.log && window.console.log.apply) { + window.console.log.apply(window.console, arguments); } else if (document) { var console = document.getElementById('moxie-console'); if (!console) { @@ -1186,11 +1565,15 @@ define("moxie/core/utils/Env", [ document.body.appendChild(console); } - if (Basic.inArray(Basic.typeOf(data), ['object', 'array']) !== -1) { + var data = arguments[0]; + if (Basic.typeOf(data) === 'string') { + data = Basic.sprintf.apply(this, arguments); + } else if (Basic.inArray(Basic.typeOf(data), ['object', 'array']) !== -1) { logObj(data); - } else { - console.appendChild(document.createTextNode(data + "\n")); + return; } + + console.appendChild(document.createTextNode(data + "\n")); } }; } @@ -1198,10 +1581,10 @@ define("moxie/core/utils/Env", [ return Env; }); -// Included from: src/javascript/core/I18n.js +// Included from: src/javascript/core/Exceptions.js /** - * I18n.js + * Exceptions.js * * Copyright 2013, Moxiecode Systems AB * Released under GPL License. @@ -1210,254 +1593,158 @@ define("moxie/core/utils/Env", [ * Contributing: http://www.plupload.com/contributing */ -define("moxie/core/I18n", [ - "moxie/core/utils/Basic" +define('moxie/core/Exceptions', [ + 'moxie/core/utils/Basic' ], function(Basic) { - var i18n = {}; + + function _findKey(obj, value) { + var key; + for (key in obj) { + if (obj[key] === value) { + return key; + } + } + return null; + } + /** + @class moxie/core/Exception + */ return { - /** - * Extends the language pack object with new items. - * - * @param {Object} pack Language pack items to add. - * @return {Object} Extended language pack object. - */ - addI18n: function(pack) { - return Basic.extend(i18n, pack); - }, + RuntimeError: (function() { + var namecodes = { + NOT_INIT_ERR: 1, + EXCEPTION_ERR: 3, + NOT_SUPPORTED_ERR: 9, + JS_ERR: 4 + }; - /** - * Translates the specified string by checking for the english string in the language pack lookup. - * - * @param {String} str String to look for. - * @return {String} Translated string or the input string if it wasn't found. - */ - translate: function(str) { - return i18n[str] || str; - }, - - /** - * Shortcut for translate function - * - * @param {String} str String to look for. - * @return {String} Translated string or the input string if it wasn't found. - */ - _: function(str) { - return this.translate(str); - }, - - /** - * Pseudo sprintf implementation - simple way to replace tokens with specified values. - * - * @param {String} str String with tokens - * @return {String} String with replaced tokens - */ - sprintf: function(str) { - var args = [].slice.call(arguments, 1); - - return str.replace(/%[a-z]/g, function() { - var value = args.shift(); - return Basic.typeOf(value) !== 'undefined' ? value : ''; + function RuntimeError(code, message) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + (message || ": RuntimeError " + this.code); + } + + Basic.extend(RuntimeError, namecodes); + RuntimeError.prototype = Error.prototype; + return RuntimeError; + }()), + + OperationNotAllowedException: (function() { + + function OperationNotAllowedException(code) { + this.code = code; + this.name = 'OperationNotAllowedException'; + } + + Basic.extend(OperationNotAllowedException, { + NOT_ALLOWED_ERR: 1 }); - } + + OperationNotAllowedException.prototype = Error.prototype; + + return OperationNotAllowedException; + }()), + + ImageError: (function() { + var namecodes = { + WRONG_FORMAT: 1, + MAX_RESOLUTION_ERR: 2, + INVALID_META_ERR: 3 + }; + + function ImageError(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": ImageError " + this.code; + } + + Basic.extend(ImageError, namecodes); + ImageError.prototype = Error.prototype; + + return ImageError; + }()), + + FileException: (function() { + var namecodes = { + NOT_FOUND_ERR: 1, + SECURITY_ERR: 2, + ABORT_ERR: 3, + NOT_READABLE_ERR: 4, + ENCODING_ERR: 5, + NO_MODIFICATION_ALLOWED_ERR: 6, + INVALID_STATE_ERR: 7, + SYNTAX_ERR: 8 + }; + + function FileException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": FileException " + this.code; + } + + Basic.extend(FileException, namecodes); + FileException.prototype = Error.prototype; + return FileException; + }()), + + DOMException: (function() { + var namecodes = { + INDEX_SIZE_ERR: 1, + DOMSTRING_SIZE_ERR: 2, + HIERARCHY_REQUEST_ERR: 3, + WRONG_DOCUMENT_ERR: 4, + INVALID_CHARACTER_ERR: 5, + NO_DATA_ALLOWED_ERR: 6, + NO_MODIFICATION_ALLOWED_ERR: 7, + NOT_FOUND_ERR: 8, + NOT_SUPPORTED_ERR: 9, + INUSE_ATTRIBUTE_ERR: 10, + INVALID_STATE_ERR: 11, + SYNTAX_ERR: 12, + INVALID_MODIFICATION_ERR: 13, + NAMESPACE_ERR: 14, + INVALID_ACCESS_ERR: 15, + VALIDATION_ERR: 16, + TYPE_MISMATCH_ERR: 17, + SECURITY_ERR: 18, + NETWORK_ERR: 19, + ABORT_ERR: 20, + URL_MISMATCH_ERR: 21, + QUOTA_EXCEEDED_ERR: 22, + TIMEOUT_ERR: 23, + INVALID_NODE_TYPE_ERR: 24, + DATA_CLONE_ERR: 25 + }; + + function DOMException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": DOMException " + this.code; + } + + Basic.extend(DOMException, namecodes); + DOMException.prototype = Error.prototype; + return DOMException; + }()), + + EventException: (function() { + function EventException(code) { + this.code = code; + this.name = 'EventException'; + } + + Basic.extend(EventException, { + UNSPECIFIED_EVENT_TYPE_ERR: 0 + }); + + EventException.prototype = Error.prototype; + + return EventException; + }()) }; }); -// Included from: src/javascript/core/utils/Mime.js - -/** - * Mime.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -define("moxie/core/utils/Mime", [ - "moxie/core/utils/Basic", - "moxie/core/I18n" -], function(Basic, I18n) { - - var mimeData = "" + - "application/msword,doc dot," + - "application/pdf,pdf," + - "application/pgp-signature,pgp," + - "application/postscript,ps ai eps," + - "application/rtf,rtf," + - "application/vnd.ms-excel,xls xlb," + - "application/vnd.ms-powerpoint,ppt pps pot," + - "application/zip,zip," + - "application/x-shockwave-flash,swf swfl," + - "application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx," + - "application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx," + - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx," + - "application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx," + - "application/vnd.openxmlformats-officedocument.presentationml.template,potx," + - "application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx," + - "application/x-javascript,js," + - "application/json,json," + - "audio/mpeg,mp3 mpga mpega mp2," + - "audio/x-wav,wav," + - "audio/x-m4a,m4a," + - "audio/ogg,oga ogg," + - "audio/aiff,aiff aif," + - "audio/flac,flac," + - "audio/aac,aac," + - "audio/ac3,ac3," + - "audio/x-ms-wma,wma," + - "image/bmp,bmp," + - "image/gif,gif," + - "image/jpeg,jpg jpeg jpe," + - "image/photoshop,psd," + - "image/png,png," + - "image/svg+xml,svg svgz," + - "image/tiff,tiff tif," + - "text/plain,asc txt text diff log," + - "text/html,htm html xhtml," + - "text/css,css," + - "text/csv,csv," + - "text/rtf,rtf," + - "video/mpeg,mpeg mpg mpe m2v," + - "video/quicktime,qt mov," + - "video/mp4,mp4," + - "video/x-m4v,m4v," + - "video/x-flv,flv," + - "video/x-ms-wmv,wmv," + - "video/avi,avi," + - "video/webm,webm," + - "video/3gpp,3gpp 3gp," + - "video/3gpp2,3g2," + - "video/vnd.rn-realvideo,rv," + - "video/ogg,ogv," + - "video/x-matroska,mkv," + - "application/vnd.oasis.opendocument.formula-template,otf," + - "application/octet-stream,exe"; - - - var Mime = { - - mimes: {}, - - extensions: {}, - - // Parses the default mime types string into a mimes and extensions lookup maps - addMimeType: function (mimeData) { - var items = mimeData.split(/,/), i, ii, ext; - - for (i = 0; i < items.length; i += 2) { - ext = items[i + 1].split(/ /); - - // extension to mime lookup - for (ii = 0; ii < ext.length; ii++) { - this.mimes[ext[ii]] = items[i]; - } - // mime to extension lookup - this.extensions[items[i]] = ext; - } - }, - - - extList2mimes: function (filters, addMissingExtensions) { - var self = this, ext, i, ii, type, mimes = []; - - // convert extensions to mime types list - for (i = 0; i < filters.length; i++) { - ext = filters[i].extensions.split(/\s*,\s*/); - - for (ii = 0; ii < ext.length; ii++) { - - // if there's an asterisk in the list, then accept attribute is not required - if (ext[ii] === '*') { - return []; - } - - type = self.mimes[ext[ii]]; - if (type && Basic.inArray(type, mimes) === -1) { - mimes.push(type); - } - - // future browsers should filter by extension, finally - if (addMissingExtensions && /^\w+$/.test(ext[ii])) { - mimes.push('.' + ext[ii]); - } else if (!type) { - // if we have no type in our map, then accept all - return []; - } - } - } - return mimes; - }, - - - mimes2exts: function(mimes) { - var self = this, exts = []; - - Basic.each(mimes, function(mime) { - if (mime === '*') { - exts = []; - return false; - } - - // check if this thing looks like mime type - var m = mime.match(/^(\w+)\/(\*|\w+)$/); - if (m) { - if (m[2] === '*') { - // wildcard mime type detected - Basic.each(self.extensions, function(arr, mime) { - if ((new RegExp('^' + m[1] + '/')).test(mime)) { - [].push.apply(exts, self.extensions[mime]); - } - }); - } else if (self.extensions[mime]) { - [].push.apply(exts, self.extensions[mime]); - } - } - }); - return exts; - }, - - - mimes2extList: function(mimes) { - var accept = [], exts = []; - - if (Basic.typeOf(mimes) === 'string') { - mimes = Basic.trim(mimes).split(/\s*,\s*/); - } - - exts = this.mimes2exts(mimes); - - accept.push({ - title: I18n.translate('Files'), - extensions: exts.length ? exts.join(',') : '*' - }); - - // save original mimes string - accept.mimes = mimes; - - return accept; - }, - - - getFileExtension: function(fileName) { - var matches = fileName && fileName.match(/\.([^.]+)$/); - if (matches) { - return matches[1].toLowerCase(); - } - return ''; - }, - - getFileMime: function(fileName) { - return this.mimes[this.getFileExtension(fileName)] || ''; - } - }; - - Mime.addMimeType(mimeData); - - return Mime; -}); - // Included from: src/javascript/core/utils/Dom.js /** @@ -1470,13 +1757,18 @@ define("moxie/core/utils/Mime", [ * Contributing: http://www.plupload.com/contributing */ +/** +@class moxie/core/utils/Dom +@public +@static +*/ + define('moxie/core/utils/Dom', ['moxie/core/utils/Env'], function(Env) { /** Get DOM Element by it's id. @method get - @for Utils @param {String} id Identifier of the DOM Element @return {DOMElement} */ @@ -1641,165 +1933,6 @@ define('moxie/core/utils/Dom', ['moxie/core/utils/Env'], function(Env) { }; }); -// Included from: src/javascript/core/Exceptions.js - -/** - * Exceptions.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -define('moxie/core/Exceptions', [ - 'moxie/core/utils/Basic' -], function(Basic) { - function _findKey(obj, value) { - var key; - for (key in obj) { - if (obj[key] === value) { - return key; - } - } - return null; - } - - return { - RuntimeError: (function() { - var namecodes = { - NOT_INIT_ERR: 1, - NOT_SUPPORTED_ERR: 9, - JS_ERR: 4 - }; - - function RuntimeError(code) { - this.code = code; - this.name = _findKey(namecodes, code); - this.message = this.name + ": RuntimeError " + this.code; - } - - Basic.extend(RuntimeError, namecodes); - RuntimeError.prototype = Error.prototype; - return RuntimeError; - }()), - - OperationNotAllowedException: (function() { - - function OperationNotAllowedException(code) { - this.code = code; - this.name = 'OperationNotAllowedException'; - } - - Basic.extend(OperationNotAllowedException, { - NOT_ALLOWED_ERR: 1 - }); - - OperationNotAllowedException.prototype = Error.prototype; - - return OperationNotAllowedException; - }()), - - ImageError: (function() { - var namecodes = { - WRONG_FORMAT: 1, - MAX_RESOLUTION_ERR: 2, - INVALID_META_ERR: 3 - }; - - function ImageError(code) { - this.code = code; - this.name = _findKey(namecodes, code); - this.message = this.name + ": ImageError " + this.code; - } - - Basic.extend(ImageError, namecodes); - ImageError.prototype = Error.prototype; - - return ImageError; - }()), - - FileException: (function() { - var namecodes = { - NOT_FOUND_ERR: 1, - SECURITY_ERR: 2, - ABORT_ERR: 3, - NOT_READABLE_ERR: 4, - ENCODING_ERR: 5, - NO_MODIFICATION_ALLOWED_ERR: 6, - INVALID_STATE_ERR: 7, - SYNTAX_ERR: 8 - }; - - function FileException(code) { - this.code = code; - this.name = _findKey(namecodes, code); - this.message = this.name + ": FileException " + this.code; - } - - Basic.extend(FileException, namecodes); - FileException.prototype = Error.prototype; - return FileException; - }()), - - DOMException: (function() { - var namecodes = { - INDEX_SIZE_ERR: 1, - DOMSTRING_SIZE_ERR: 2, - HIERARCHY_REQUEST_ERR: 3, - WRONG_DOCUMENT_ERR: 4, - INVALID_CHARACTER_ERR: 5, - NO_DATA_ALLOWED_ERR: 6, - NO_MODIFICATION_ALLOWED_ERR: 7, - NOT_FOUND_ERR: 8, - NOT_SUPPORTED_ERR: 9, - INUSE_ATTRIBUTE_ERR: 10, - INVALID_STATE_ERR: 11, - SYNTAX_ERR: 12, - INVALID_MODIFICATION_ERR: 13, - NAMESPACE_ERR: 14, - INVALID_ACCESS_ERR: 15, - VALIDATION_ERR: 16, - TYPE_MISMATCH_ERR: 17, - SECURITY_ERR: 18, - NETWORK_ERR: 19, - ABORT_ERR: 20, - URL_MISMATCH_ERR: 21, - QUOTA_EXCEEDED_ERR: 22, - TIMEOUT_ERR: 23, - INVALID_NODE_TYPE_ERR: 24, - DATA_CLONE_ERR: 25 - }; - - function DOMException(code) { - this.code = code; - this.name = _findKey(namecodes, code); - this.message = this.name + ": DOMException " + this.code; - } - - Basic.extend(DOMException, namecodes); - DOMException.prototype = Error.prototype; - return DOMException; - }()), - - EventException: (function() { - function EventException(code) { - this.code = code; - this.name = 'EventException'; - } - - Basic.extend(EventException, { - UNSPECIFIED_EVENT_TYPE_ERR: 0 - }); - - EventException.prototype = Error.prototype; - - return EventException; - }()) - }; -}); - // Included from: src/javascript/core/EventTarget.js /** @@ -1817,289 +1950,326 @@ define('moxie/core/EventTarget', [ 'moxie/core/Exceptions', 'moxie/core/utils/Basic' ], function(Env, x, Basic) { + + // hash of event listeners by object uid + var eventpool = {}; + /** Parent object for all event dispatching components and objects - @class EventTarget + @class moxie/core/EventTarget @constructor EventTarget */ function EventTarget() { - // hash of event listeners by object uid - var eventpool = {}; - - Basic.extend(this, { - - /** - Unique id of the event dispatcher, usually overriden by children + /** + Unique id of the event dispatcher, usually overriden by children - @property uid - @type String - */ - uid: null, - - /** - Can be called from within a child in order to acquire uniqie id in automated manner - - @method init - */ - init: function() { - if (!this.uid) { - this.uid = Basic.guid('uid_'); - } - }, - - /** - Register a handler to a specific event dispatched by the object - - @method addEventListener - @param {String} type Type or basically a name of the event to subscribe to - @param {Function} fn Callback function that will be called when event happens - @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first - @param {Object} [scope=this] A scope to invoke event handler in - */ - addEventListener: function(type, fn, priority, scope) { - var self = this, list; - - // without uid no event handlers can be added, so make sure we got one - if (!this.hasOwnProperty('uid')) { - this.uid = Basic.guid('uid_'); - } - - type = Basic.trim(type); - - if (/\s/.test(type)) { - // multiple event types were passed for one handler - Basic.each(type.split(/\s+/), function(type) { - self.addEventListener(type, fn, priority, scope); - }); - return; - } - - type = type.toLowerCase(); - priority = parseInt(priority, 10) || 0; - - list = eventpool[this.uid] && eventpool[this.uid][type] || []; - list.push({fn : fn, priority : priority, scope : scope || this}); - - if (!eventpool[this.uid]) { - eventpool[this.uid] = {}; - } - eventpool[this.uid][type] = list; - }, - - /** - Check if any handlers were registered to the specified event - - @method hasEventListener - @param {String} type Type or basically a name of the event to check - @return {Mixed} Returns a handler if it was found and false, if - not - */ - hasEventListener: function(type) { - var list = type ? eventpool[this.uid] && eventpool[this.uid][type] : eventpool[this.uid]; - return list ? list : false; - }, - - /** - Unregister the handler from the event, or if former was not specified - unregister all handlers - - @method removeEventListener - @param {String} type Type or basically a name of the event - @param {Function} [fn] Handler to unregister - */ - removeEventListener: function(type, fn) { - type = type.toLowerCase(); - - var list = eventpool[this.uid] && eventpool[this.uid][type], i; - - if (list) { - if (fn) { - for (i = list.length - 1; i >= 0; i--) { - if (list[i].fn === fn) { - list.splice(i, 1); - break; - } - } - } else { - list = []; - } - - // delete event list if it has become empty - if (!list.length) { - delete eventpool[this.uid][type]; - - // and object specific entry in a hash if it has no more listeners attached - if (Basic.isEmptyObj(eventpool[this.uid])) { - delete eventpool[this.uid]; - } - } - } - }, - - /** - Remove all event handlers from the object - - @method removeAllEventListeners - */ - removeAllEventListeners: function() { - if (eventpool[this.uid]) { - delete eventpool[this.uid]; - } - }, - - /** - Dispatch the event - - @method dispatchEvent - @param {String/Object} Type of event or event object to dispatch - @param {Mixed} [...] Variable number of arguments to be passed to a handlers - @return {Boolean} true by default and false if any handler returned false - */ - dispatchEvent: function(type) { - var uid, list, args, tmpEvt, evt = {}, result = true, undef; - - if (Basic.typeOf(type) !== 'string') { - // we can't use original object directly (because of Silverlight) - tmpEvt = type; - - if (Basic.typeOf(tmpEvt.type) === 'string') { - type = tmpEvt.type; - - if (tmpEvt.total !== undef && tmpEvt.loaded !== undef) { // progress event - evt.total = tmpEvt.total; - evt.loaded = tmpEvt.loaded; - } - evt.async = tmpEvt.async || false; - } else { - throw new x.EventException(x.EventException.UNSPECIFIED_EVENT_TYPE_ERR); - } - } - - // check if event is meant to be dispatched on an object having specific uid - if (type.indexOf('::') !== -1) { - (function(arr) { - uid = arr[0]; - type = arr[1]; - }(type.split('::'))); - } else { - uid = this.uid; - } - - type = type.toLowerCase(); - - list = eventpool[uid] && eventpool[uid][type]; - - if (list) { - // sort event list by prority - list.sort(function(a, b) { return b.priority - a.priority; }); - - args = [].slice.call(arguments); - - // first argument will be pseudo-event object - args.shift(); - evt.type = type; - args.unshift(evt); - - if (MXI_DEBUG && Env.debug.events) { - Env.log("Event '%s' fired on %u", evt.type, uid); - } - - // Dispatch event to all listeners - var queue = []; - Basic.each(list, function(handler) { - // explicitly set the target, otherwise events fired from shims do not get it - args[0].target = handler.scope; - // if event is marked as async, detach the handler - if (evt.async) { - queue.push(function(cb) { - setTimeout(function() { - cb(handler.fn.apply(handler.scope, args) === false); - }, 1); - }); - } else { - queue.push(function(cb) { - cb(handler.fn.apply(handler.scope, args) === false); // if handler returns false stop propagation - }); - } - }); - if (queue.length) { - Basic.inSeries(queue, function(err) { - result = !err; - }); - } - } - return result; - }, - - /** - Alias for addEventListener - - @method bind - @protected - */ - bind: function() { - this.addEventListener.apply(this, arguments); - }, - - /** - Alias for removeEventListener - - @method unbind - @protected - */ - unbind: function() { - this.removeEventListener.apply(this, arguments); - }, - - /** - Alias for removeAllEventListeners - - @method unbindAll - @protected - */ - unbindAll: function() { - this.removeAllEventListeners.apply(this, arguments); - }, - - /** - Alias for dispatchEvent - - @method trigger - @protected - */ - trigger: function() { - return this.dispatchEvent.apply(this, arguments); - }, - - - /** - Handle properties of on[event] type. - - @method handleEventProps - @private - */ - handleEventProps: function(dispatches) { - var self = this; - - this.bind(dispatches.join(' '), function(e) { - var prop = 'on' + e.type.toLowerCase(); - if (Basic.typeOf(this[prop]) === 'function') { - this[prop].apply(this, arguments); - } - }); - - // object must have defined event properties, even if it doesn't make use of them - Basic.each(dispatches, function(prop) { - prop = 'on' + prop.toLowerCase(prop); - if (Basic.typeOf(self[prop]) === 'undefined') { - self[prop] = null; - } - }); - } - - }); + @property uid + @type String + */ + this.uid = Basic.guid(); } - EventTarget.instance = new EventTarget(); + + Basic.extend(EventTarget.prototype, { + + /** + Can be called from within a child in order to acquire uniqie id in automated manner + + @method init + */ + init: function() { + if (!this.uid) { + this.uid = Basic.guid('uid_'); + } + }, + + /** + Register a handler to a specific event dispatched by the object + + @method addEventListener + @param {String} type Type or basically a name of the event to subscribe to + @param {Function} fn Callback function that will be called when event happens + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + @param {Object} [scope=this] A scope to invoke event handler in + */ + addEventListener: function(type, fn, priority, scope) { + var self = this, list; + + // without uid no event handlers can be added, so make sure we got one + if (!this.hasOwnProperty('uid')) { + this.uid = Basic.guid('uid_'); + } + + type = Basic.trim(type); + + if (/\s/.test(type)) { + // multiple event types were passed for one handler + Basic.each(type.split(/\s+/), function(type) { + self.addEventListener(type, fn, priority, scope); + }); + return; + } + + type = type.toLowerCase(); + priority = parseInt(priority, 10) || 0; + + list = eventpool[this.uid] && eventpool[this.uid][type] || []; + list.push({fn : fn, priority : priority, scope : scope || this}); + + if (!eventpool[this.uid]) { + eventpool[this.uid] = {}; + } + eventpool[this.uid][type] = list; + }, + + /** + Check if any handlers were registered to the specified event + + @method hasEventListener + @param {String} [type] Type or basically a name of the event to check + @return {Mixed} Returns a handler if it was found and false, if - not + */ + hasEventListener: function(type) { + var list; + if (type) { + type = type.toLowerCase(); + list = eventpool[this.uid] && eventpool[this.uid][type]; + } else { + list = eventpool[this.uid]; + } + return list ? list : false; + }, + + /** + Unregister the handler from the event, or if former was not specified - unregister all handlers + + @method removeEventListener + @param {String} type Type or basically a name of the event + @param {Function} [fn] Handler to unregister + */ + removeEventListener: function(type, fn) { + var self = this, list, i; + + type = type.toLowerCase(); + + if (/\s/.test(type)) { + // multiple event types were passed for one handler + Basic.each(type.split(/\s+/), function(type) { + self.removeEventListener(type, fn); + }); + return; + } + + list = eventpool[this.uid] && eventpool[this.uid][type]; + + if (list) { + if (fn) { + for (i = list.length - 1; i >= 0; i--) { + if (list[i].fn === fn) { + list.splice(i, 1); + break; + } + } + } else { + list = []; + } + + // delete event list if it has become empty + if (!list.length) { + delete eventpool[this.uid][type]; + + // and object specific entry in a hash if it has no more listeners attached + if (Basic.isEmptyObj(eventpool[this.uid])) { + delete eventpool[this.uid]; + } + } + } + }, + + /** + Remove all event handlers from the object + + @method removeAllEventListeners + */ + removeAllEventListeners: function() { + if (eventpool[this.uid]) { + delete eventpool[this.uid]; + } + }, + + /** + Dispatch the event + + @method dispatchEvent + @param {String/Object} Type of event or event object to dispatch + @param {Mixed} [...] Variable number of arguments to be passed to a handlers + @return {Boolean} true by default and false if any handler returned false + */ + dispatchEvent: function(type) { + var uid, list, args, tmpEvt, evt = {}, result = true, undef; + + if (Basic.typeOf(type) !== 'string') { + // we can't use original object directly (because of Silverlight) + tmpEvt = type; + + if (Basic.typeOf(tmpEvt.type) === 'string') { + type = tmpEvt.type; + + if (tmpEvt.total !== undef && tmpEvt.loaded !== undef) { // progress event + evt.total = tmpEvt.total; + evt.loaded = tmpEvt.loaded; + } + evt.async = tmpEvt.async || false; + } else { + throw new x.EventException(x.EventException.UNSPECIFIED_EVENT_TYPE_ERR); + } + } + + // check if event is meant to be dispatched on an object having specific uid + if (type.indexOf('::') !== -1) { + (function(arr) { + uid = arr[0]; + type = arr[1]; + }(type.split('::'))); + } else { + uid = this.uid; + } + + type = type.toLowerCase(); + + list = eventpool[uid] && eventpool[uid][type]; + + if (list) { + // sort event list by prority + list.sort(function(a, b) { return b.priority - a.priority; }); + + args = [].slice.call(arguments); + + // first argument will be pseudo-event object + args.shift(); + evt.type = type; + args.unshift(evt); + + if (MXI_DEBUG && Env.debug.events) { + Env.log("%cEvent '%s' fired on %s", 'color: #999;', evt.type, (this.ctorName ? this.ctorName + '::' : '') + uid); + } + + // Dispatch event to all listeners + var queue = []; + Basic.each(list, function(handler) { + // explicitly set the target, otherwise events fired from shims do not get it + args[0].target = handler.scope; + // if event is marked as async, detach the handler + if (evt.async) { + queue.push(function(cb) { + setTimeout(function() { + cb(handler.fn.apply(handler.scope, args) === false); + }, 1); + }); + } else { + queue.push(function(cb) { + cb(handler.fn.apply(handler.scope, args) === false); // if handler returns false stop propagation + }); + } + }); + if (queue.length) { + Basic.inSeries(queue, function(err) { + result = !err; + }); + } + } + return result; + }, + + /** + Register a handler to the event type that will run only once + + @method bindOnce + @since >1.4.1 + @param {String} type Type or basically a name of the event to subscribe to + @param {Function} fn Callback function that will be called when event happens + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + @param {Object} [scope=this] A scope to invoke event handler in + */ + bindOnce: function(type, fn, priority, scope) { + var self = this; + self.bind.call(this, type, function cb() { + self.unbind(type, cb); + return fn.apply(this, arguments); + }, priority, scope); + }, + + /** + Alias for addEventListener + + @method bind + @protected + */ + bind: function() { + this.addEventListener.apply(this, arguments); + }, + + /** + Alias for removeEventListener + + @method unbind + @protected + */ + unbind: function() { + this.removeEventListener.apply(this, arguments); + }, + + /** + Alias for removeAllEventListeners + + @method unbindAll + @protected + */ + unbindAll: function() { + this.removeAllEventListeners.apply(this, arguments); + }, + + /** + Alias for dispatchEvent + + @method trigger + @protected + */ + trigger: function() { + return this.dispatchEvent.apply(this, arguments); + }, + + + /** + Handle properties of on[event] type. + + @method handleEventProps + @private + */ + handleEventProps: function(dispatches) { + var self = this; + + this.bind(dispatches.join(' '), function(e) { + var prop = 'on' + e.type.toLowerCase(); + if (Basic.typeOf(this[prop]) === 'function') { + this[prop].apply(this, arguments); + } + }); + + // object must have defined event properties, even if it doesn't make use of them + Basic.each(dispatches, function(prop) { + prop = 'on' + prop.toLowerCase(prop); + if (Basic.typeOf(self[prop]) === 'undefined') { + self[prop] = null; + } + }); + } + + }); + + + EventTarget.instance = new EventTarget(); return EventTarget; }); @@ -2127,7 +2297,7 @@ define('moxie/runtime/Runtime', [ /** Common set of methods and properties for every runtime instance - @class Runtime + @class moxie/runtime/Runtime @param {Object} options @param {String} type Sanitized name of the runtime @@ -2371,7 +2541,7 @@ define('moxie/runtime/Runtime', [ // if no container for shim, create one if (!shimContainer) { - container = this.options.container ? Dom.get(this.options.container) : document.body; + container = Dom.get(this.options.container) || document.body; // create shim container and insert it at an absolute position into the outer container shimContainer = document.createElement('div'); @@ -2475,7 +2645,7 @@ define('moxie/runtime/Runtime', [ @type String @static */ - Runtime.order = 'html5,html4'; + Runtime.order = 'html5,flash,silverlight,html4'; /** @@ -2646,7 +2816,7 @@ define('moxie/runtime/Runtime', [ // if cap requires conflicting mode - runtime cannot fulfill required caps if (MXI_DEBUG && Env.debug.runtime) { - Env.log("\t\t%c: %v (conflicting mode requested: %s)", cap, value, capMode); + Env.log("\t\t%s: %s (conflicting mode requested: %s)", cap, value, capMode); } return (mode = false); @@ -2654,7 +2824,7 @@ define('moxie/runtime/Runtime', [ } if (MXI_DEBUG && Env.debug.runtime) { - Env.log("\t\t%c: %v (compatible modes: %s)", cap, value, mode); + Env.log("\t\t%s: %s (compatible modes: %s)", cap, value, mode); } }); @@ -2668,6 +2838,30 @@ define('moxie/runtime/Runtime', [ }; + /** + * Third party shims (Flash and Silverlight) require global event target against which they + * will fire their events. However when moxie is not loaded to global namespace, default + * event target is not accessible and we have to create artificial ones. + * + * @method getGlobalEventTarget + * @static + * @return {String} Name of the global event target + */ + Runtime.getGlobalEventTarget = function() { + if (/^moxie\./.test(Env.global_event_dispatcher) && !Env.can('access_global_ns')) { + var uniqueCallbackName = Basic.guid('moxie_event_target_'); + + window[uniqueCallbackName] = function(e, data) { + EventTarget.instance.dispatchEvent(e, data); + }; + + Env.global_event_dispatcher = uniqueCallbackName; + } + + return Env.global_event_dispatcher; + }; + + /** Capability check that always returns true @@ -2728,7 +2922,7 @@ define('moxie/runtime/RuntimeClient', [ /** Set of methods and properties, required by a component to acquire ability to connect to a runtime - @class RuntimeClient + @class moxie/runtime/RuntimeClient */ return function RuntimeClient() { var runtime; @@ -2758,6 +2952,9 @@ define('moxie/runtime/RuntimeClient', [ type = items.shift().toLowerCase(); constructor = Runtime.getConstructor(type); if (!constructor) { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Constructor for '%s' runtime is not available.", type); + } initialize(items); return; } @@ -2781,6 +2978,7 @@ define('moxie/runtime/RuntimeClient', [ // jailbreak ... setTimeout(function() { runtime.clients++; + comp.ruid = runtime.uid; // this will be triggered on component comp.trigger('RuntimeInit', runtime); }, 1); @@ -2795,7 +2993,14 @@ define('moxie/runtime/RuntimeClient', [ initialize(items); }); - /*runtime.bind('Exception', function() { });*/ + runtime.bind('Exception', function(e, err) { + var message = err.name + "(#" + err.code + ")" + (err.message ? ", from: " + err.message : ''); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Runtime '%s' has thrown an exception: %s", this.type, message); + } + comp.trigger('RuntimeError', new x.RuntimeError(x.RuntimeError.EXCEPTION_ERR, message)); + }); if (MXI_DEBUG && Env.debug.runtime) { Env.log("\tselected mode: %s", runtime.mode); @@ -2820,6 +3025,7 @@ define('moxie/runtime/RuntimeClient', [ if (ruid) { runtime = Runtime.getRuntime(ruid); if (runtime) { + comp.ruid = ruid; runtime.clients++; return runtime; } else { @@ -2871,10 +3077,19 @@ define('moxie/runtime/RuntimeClient', [ @return {Mixed} Whatever runtime extension method returns */ exec: function() { - if (runtime) { - return runtime.exec.apply(this, arguments); - } - return null; + return runtime ? runtime.exec.apply(this, arguments) : null; + }, + + + /** + Test runtime client for specific capability + + @method can + @param {String} cap + @return {Bool} + */ + can: function(cap) { + return runtime ? runtime.can(cap) : false; } }); @@ -2883,515 +3098,6 @@ define('moxie/runtime/RuntimeClient', [ }); -// Included from: src/javascript/file/FileInput.js - -/** - * FileInput.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -define('moxie/file/FileInput', [ - 'moxie/core/utils/Basic', - 'moxie/core/utils/Env', - 'moxie/core/utils/Mime', - 'moxie/core/utils/Dom', - 'moxie/core/Exceptions', - 'moxie/core/EventTarget', - 'moxie/core/I18n', - 'moxie/runtime/Runtime', - 'moxie/runtime/RuntimeClient' -], function(Basic, Env, Mime, Dom, x, EventTarget, I18n, Runtime, RuntimeClient) { - /** - Provides a convenient way to create cross-browser file-picker. Generates file selection dialog on click, - converts selected files to _File_ objects, to be used in conjunction with _Image_, preloaded in memory - with _FileReader_ or uploaded to a server through _XMLHttpRequest_. - - @class FileInput - @constructor - @extends EventTarget - @uses RuntimeClient - @param {Object|String|DOMElement} options If options is string or node, argument is considered as _browse\_button_. - @param {String|DOMElement} options.browse_button DOM Element to turn into file picker. - @param {Array} [options.accept] Array of mime types to accept. By default accepts all. - @param {String} [options.file='file'] Name of the file field (not the filename). - @param {Boolean} [options.multiple=false] Enable selection of multiple files. - @param {Boolean} [options.directory=false] Turn file input into the folder input (cannot be both at the same time). - @param {String|DOMElement} [options.container] DOM Element to use as a container for file-picker. Defaults to parentNode - for _browse\_button_. - @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support. - - @example -
- Browse... -
- - - */ - var dispatches = [ - /** - Dispatched when runtime is connected and file-picker is ready to be used. - - @event ready - @param {Object} event - */ - 'ready', - - /** - Dispatched right after [ready](#event_ready) event, and whenever [refresh()](#method_refresh) is invoked. - Check [corresponding documentation entry](#method_refresh) for more info. - - @event refresh - @param {Object} event - */ - - /** - Dispatched when selection of files in the dialog is complete. - - @event change - @param {Object} event - */ - 'change', - - 'cancel', // TODO: might be useful - - /** - Dispatched when mouse cursor enters file-picker area. Can be used to style element - accordingly. - - @event mouseenter - @param {Object} event - */ - 'mouseenter', - - /** - Dispatched when mouse cursor leaves file-picker area. Can be used to style element - accordingly. - - @event mouseleave - @param {Object} event - */ - 'mouseleave', - - /** - Dispatched when functional mouse button is pressed on top of file-picker area. - - @event mousedown - @param {Object} event - */ - 'mousedown', - - /** - Dispatched when functional mouse button is released on top of file-picker area. - - @event mouseup - @param {Object} event - */ - 'mouseup' - ]; - - function FileInput(options) { - if (MXI_DEBUG) { - Env.log("Instantiating FileInput..."); - } - - var self = this, - container, browseButton, defaults; - - // if flat argument passed it should be browse_button id - if (Basic.inArray(Basic.typeOf(options), ['string', 'node']) !== -1) { - options = { browse_button : options }; - } - - // this will help us to find proper default container - browseButton = Dom.get(options.browse_button); - if (!browseButton) { - // browse button is required - throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); - } - - // figure out the options - defaults = { - accept: [{ - title: I18n.translate('All Files'), - extensions: '*' - }], - name: 'file', - multiple: false, - required_caps: false, - container: browseButton.parentNode || document.body - }; - - options = Basic.extend({}, defaults, options); - - // convert to object representation - if (typeof(options.required_caps) === 'string') { - options.required_caps = Runtime.parseCaps(options.required_caps); - } - - // normalize accept option (could be list of mime types or array of title/extensions pairs) - if (typeof(options.accept) === 'string') { - options.accept = Mime.mimes2extList(options.accept); - } - - container = Dom.get(options.container); - // make sure we have container - if (!container) { - container = document.body; - } - - // make container relative, if it's not - if (Dom.getStyle(container, 'position') === 'static') { - container.style.position = 'relative'; - } - - container = browseButton = null; // IE - - RuntimeClient.call(self); - - Basic.extend(self, { - /** - Unique id of the component - - @property uid - @protected - @readOnly - @type {String} - @default UID - */ - uid: Basic.guid('uid_'), - - /** - Unique id of the connected runtime, if any. - - @property ruid - @protected - @type {String} - */ - ruid: null, - - /** - Unique id of the runtime container. Useful to get hold of it for various manipulations. - - @property shimid - @protected - @type {String} - */ - shimid: null, - - /** - Array of selected mOxie.File objects - - @property files - @type {Array} - @default null - */ - files: null, - - /** - Initializes the file-picker, connects it to runtime and dispatches event ready when done. - - @method init - */ - init: function() { - self.bind('RuntimeInit', function(e, runtime) { - self.ruid = runtime.uid; - self.shimid = runtime.shimid; - - self.bind("Ready", function() { - self.trigger("Refresh"); - }, 999); - - // re-position and resize shim container - self.bind('Refresh', function() { - var pos, size, browseButton, shimContainer; - - browseButton = Dom.get(options.browse_button); - shimContainer = Dom.get(runtime.shimid); // do not use runtime.getShimContainer(), since it will create container if it doesn't exist - - if (browseButton) { - pos = Dom.getPos(browseButton, Dom.get(options.container)); - size = Dom.getSize(browseButton); - - if (shimContainer) { - Basic.extend(shimContainer.style, { - top : pos.y + 'px', - left : pos.x + 'px', - width : size.w + 'px', - height : size.h + 'px' - }); - } - } - shimContainer = browseButton = null; - }); - - runtime.exec.call(self, 'FileInput', 'init', options); - }); - - // runtime needs: options.required_features, options.runtime_order and options.container - self.connectRuntime(Basic.extend({}, options, { - required_caps: { - select_file: true - } - })); - }, - - /** - Disables file-picker element, so that it doesn't react to mouse clicks. - - @method disable - @param {Boolean} [state=true] Disable component if - true, enable if - false - */ - disable: function(state) { - var runtime = this.getRuntime(); - if (runtime) { - runtime.exec.call(this, 'FileInput', 'disable', Basic.typeOf(state) === 'undefined' ? true : state); - } - }, - - - /** - Reposition and resize dialog trigger to match the position and size of browse_button element. - - @method refresh - */ - refresh: function() { - self.trigger("Refresh"); - }, - - - /** - Destroy component. - - @method destroy - */ - destroy: function() { - var runtime = this.getRuntime(); - if (runtime) { - runtime.exec.call(this, 'FileInput', 'destroy'); - this.disconnectRuntime(); - } - - if (Basic.typeOf(this.files) === 'array') { - // no sense in leaving associated files behind - Basic.each(this.files, function(file) { - file.destroy(); - }); - } - this.files = null; - - this.unbindAll(); - } - }); - - this.handleEventProps(dispatches); - } - - FileInput.prototype = EventTarget.instance; - - return FileInput; -}); - -// Included from: src/javascript/core/utils/Encode.js - -/** - * Encode.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -define('moxie/core/utils/Encode', [], function() { - - /** - Encode string with UTF-8 - - @method utf8_encode - @for Utils - @static - @param {String} str String to encode - @return {String} UTF-8 encoded string - */ - var utf8_encode = function(str) { - return unescape(encodeURIComponent(str)); - }; - - /** - Decode UTF-8 encoded string - - @method utf8_decode - @static - @param {String} str String to decode - @return {String} Decoded string - */ - var utf8_decode = function(str_data) { - return decodeURIComponent(escape(str_data)); - }; - - /** - Decode Base64 encoded string (uses browser's default method if available), - from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_decode.js - - @method atob - @static - @param {String} data String to decode - @return {String} Decoded string - */ - var atob = function(data, utf8) { - if (typeof(window.atob) === 'function') { - return utf8 ? utf8_decode(window.atob(data)) : window.atob(data); - } - - // http://kevin.vanzonneveld.net - // + original by: Tyler Akins (http://rumkin.com) - // + improved by: Thunder.m - // + input by: Aman Gupta - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfixed by: Onno Marsman - // + bugfixed by: Pellentesque Malesuada - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Brett Zamir (http://brett-zamir.me) - // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); - // * returns 1: 'Kevin van Zonneveld' - // mozilla has this native - // - but breaks in 2.0.0.12! - //if (typeof this.window.atob == 'function') { - // return atob(data); - //} - var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, - ac = 0, - dec = "", - tmp_arr = []; - - if (!data) { - return data; - } - - data += ''; - - do { // unpack four hexets into three octets using index points in b64 - h1 = b64.indexOf(data.charAt(i++)); - h2 = b64.indexOf(data.charAt(i++)); - h3 = b64.indexOf(data.charAt(i++)); - h4 = b64.indexOf(data.charAt(i++)); - - bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; - - o1 = bits >> 16 & 0xff; - o2 = bits >> 8 & 0xff; - o3 = bits & 0xff; - - if (h3 == 64) { - tmp_arr[ac++] = String.fromCharCode(o1); - } else if (h4 == 64) { - tmp_arr[ac++] = String.fromCharCode(o1, o2); - } else { - tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); - } - } while (i < data.length); - - dec = tmp_arr.join(''); - - return utf8 ? utf8_decode(dec) : dec; - }; - - /** - Base64 encode string (uses browser's default method if available), - from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_encode.js - - @method btoa - @static - @param {String} data String to encode - @return {String} Base64 encoded string - */ - var btoa = function(data, utf8) { - if (utf8) { - data = utf8_encode(data); - } - - if (typeof(window.btoa) === 'function') { - return window.btoa(data); - } - - // http://kevin.vanzonneveld.net - // + original by: Tyler Akins (http://rumkin.com) - // + improved by: Bayron Guevara - // + improved by: Thunder.m - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfixed by: Pellentesque Malesuada - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: RafaƂ Kukawski (http://kukawski.pl) - // * example 1: base64_encode('Kevin van Zonneveld'); - // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' - // mozilla has this native - // - but breaks in 2.0.0.12! - var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, - ac = 0, - enc = "", - tmp_arr = []; - - if (!data) { - return data; - } - - do { // pack three octets into four hexets - o1 = data.charCodeAt(i++); - o2 = data.charCodeAt(i++); - o3 = data.charCodeAt(i++); - - bits = o1 << 16 | o2 << 8 | o3; - - h1 = bits >> 18 & 0x3f; - h2 = bits >> 12 & 0x3f; - h3 = bits >> 6 & 0x3f; - h4 = bits & 0x3f; - - // use hexets to index into b64, and append result to encoded string - tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); - } while (i < data.length); - - enc = tmp_arr.join(''); - - var r = data.length % 3; - - return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); - }; - - - return { - utf8_encode: utf8_encode, - utf8_decode: utf8_decode, - atob: atob, - btoa: btoa - }; -}); - // Included from: src/javascript/file/Blob.js /** @@ -3413,7 +3119,7 @@ define('moxie/file/Blob', [ var blobpool = {}; /** - @class Blob + @class moxie/file/Blob @constructor @param {String} ruid Unique id of the runtime, to which this blob belongs to @param {Object} blob Object "Native" blob object, as it is represented in the runtime @@ -3570,6 +3276,696 @@ define('moxie/file/Blob', [ return Blob; }); +// Included from: src/javascript/core/I18n.js + +/** + * I18n.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/I18n", [ + "moxie/core/utils/Basic" +], function(Basic) { + var i18n = {}; + + /** + @class moxie/core/I18n + */ + return { + /** + * Extends the language pack object with new items. + * + * @param {Object} pack Language pack items to add. + * @return {Object} Extended language pack object. + */ + addI18n: function(pack) { + return Basic.extend(i18n, pack); + }, + + /** + * Translates the specified string by checking for the english string in the language pack lookup. + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + translate: function(str) { + return i18n[str] || str; + }, + + /** + * Shortcut for translate function + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + _: function(str) { + return this.translate(str); + }, + + /** + * Pseudo sprintf implementation - simple way to replace tokens with specified values. + * + * @param {String} str String with tokens + * @return {String} String with replaced tokens + */ + sprintf: function(str) { + var args = [].slice.call(arguments, 1); + + return str.replace(/%[a-z]/g, function() { + var value = args.shift(); + return Basic.typeOf(value) !== 'undefined' ? value : ''; + }); + } + }; +}); + +// Included from: src/javascript/core/utils/Mime.js + +/** + * Mime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/core/utils/Mime +@public +@static +*/ + +define("moxie/core/utils/Mime", [ + "moxie/core/utils/Basic", + "moxie/core/I18n" +], function(Basic, I18n) { + + var mimeData = "" + + "application/msword,doc dot," + + "application/pdf,pdf," + + "application/pgp-signature,pgp," + + "application/postscript,ps ai eps," + + "application/rtf,rtf," + + "application/vnd.ms-excel,xls xlb xlt xla," + + "application/vnd.ms-powerpoint,ppt pps pot ppa," + + "application/zip,zip," + + "application/x-shockwave-flash,swf swfl," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx," + + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx," + + "application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx," + + "application/vnd.openxmlformats-officedocument.presentationml.template,potx," + + "application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx," + + "application/x-javascript,js," + + "application/json,json," + + "audio/mpeg,mp3 mpga mpega mp2," + + "audio/x-wav,wav," + + "audio/x-m4a,m4a," + + "audio/ogg,oga ogg," + + "audio/aiff,aiff aif," + + "audio/flac,flac," + + "audio/aac,aac," + + "audio/ac3,ac3," + + "audio/x-ms-wma,wma," + + "image/bmp,bmp," + + "image/gif,gif," + + "image/jpeg,jpg jpeg jpe," + + "image/photoshop,psd," + + "image/png,png," + + "image/svg+xml,svg svgz," + + "image/tiff,tiff tif," + + "text/plain,asc txt text diff log," + + "text/html,htm html xhtml," + + "text/css,css," + + "text/csv,csv," + + "text/rtf,rtf," + + "video/mpeg,mpeg mpg mpe m2v," + + "video/quicktime,qt mov," + + "video/mp4,mp4," + + "video/x-m4v,m4v," + + "video/x-flv,flv," + + "video/x-ms-wmv,wmv," + + "video/avi,avi," + + "video/webm,webm," + + "video/3gpp,3gpp 3gp," + + "video/3gpp2,3g2," + + "video/vnd.rn-realvideo,rv," + + "video/ogg,ogv," + + "video/x-matroska,mkv," + + "application/vnd.oasis.opendocument.formula-template,otf," + + "application/octet-stream,exe"; + + + /** + * Map of mimes to extensions + * + * @property mimes + * @type {Object} + */ + var mimes = {}; + + /** + * Map of extensions to mimes + * + * @property extensions + * @type {Object} + */ + var extensions = {}; + + + /** + * Parses mimeData string into a mimes and extensions lookup maps. String should have the + * following format: + * + * application/msword,doc dot,application/pdf,pdf, ... + * + * so mime-type followed by comma and followed by space-separated list of associated extensions, + * then comma again and then another mime-type, etc. + * + * If invoked externally will replace override internal lookup maps with user-provided data. + * + * @method addMimeType + * @param {String} mimeData + */ + var addMimeType = function (mimeData) { + var items = mimeData.split(/,/), i, ii, ext; + + for (i = 0; i < items.length; i += 2) { + ext = items[i + 1].split(/ /); + + // extension to mime lookup + for (ii = 0; ii < ext.length; ii++) { + mimes[ext[ii]] = items[i]; + } + // mime to extension lookup + extensions[items[i]] = ext; + } + }; + + + var extList2mimes = function (filters, addMissingExtensions) { + var ext, i, ii, type, mimes = []; + + // convert extensions to mime types list + for (i = 0; i < filters.length; i++) { + ext = filters[i].extensions.toLowerCase().split(/\s*,\s*/); + + for (ii = 0; ii < ext.length; ii++) { + + // if there's an asterisk in the list, then accept attribute is not required + if (ext[ii] === '*') { + return []; + } + + type = mimes[ext[ii]]; + + // future browsers should filter by extension, finally + if (addMissingExtensions && /^\w+$/.test(ext[ii])) { + mimes.push('.' + ext[ii]); + } else if (type && Basic.inArray(type, mimes) === -1) { + mimes.push(type); + } else if (!type) { + // if we have no type in our map, then accept all + return []; + } + } + } + return mimes; + }; + + + var mimes2exts = function(mimes) { + var exts = []; + + Basic.each(mimes, function(mime) { + mime = mime.toLowerCase(); + + if (mime === '*') { + exts = []; + return false; + } + + // check if this thing looks like mime type + var m = mime.match(/^(\w+)\/(\*|\w+)$/); + if (m) { + if (m[2] === '*') { + // wildcard mime type detected + Basic.each(extensions, function(arr, mime) { + if ((new RegExp('^' + m[1] + '/')).test(mime)) { + [].push.apply(exts, extensions[mime]); + } + }); + } else if (extensions[mime]) { + [].push.apply(exts, extensions[mime]); + } + } + }); + return exts; + }; + + + var mimes2extList = function(mimes) { + var accept = [], exts = []; + + if (Basic.typeOf(mimes) === 'string') { + mimes = Basic.trim(mimes).split(/\s*,\s*/); + } + + exts = mimes2exts(mimes); + + accept.push({ + title: I18n.translate('Files'), + extensions: exts.length ? exts.join(',') : '*' + }); + + return accept; + }; + + /** + * Extract extension from the given filename + * + * @method getFileExtension + * @param {String} fileName + * @return {String} File extension + */ + var getFileExtension = function(fileName) { + var matches = fileName && fileName.match(/\.([^.]+)$/); + if (matches) { + return matches[1].toLowerCase(); + } + return ''; + }; + + + /** + * Get file mime-type from it's filename - will try to match the extension + * against internal mime-type lookup map + * + * @method getFileMime + * @param {String} fileName + * @return File mime-type if found or an empty string if not + */ + var getFileMime = function(fileName) { + return mimes[getFileExtension(fileName)] || ''; + }; + + + addMimeType(mimeData); + + return { + mimes: mimes, + extensions: extensions, + addMimeType: addMimeType, + extList2mimes: extList2mimes, + mimes2exts: mimes2exts, + mimes2extList: mimes2extList, + getFileExtension: getFileExtension, + getFileMime: getFileMime + } +}); + +// Included from: src/javascript/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileInput', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Env', + 'moxie/core/utils/Mime', + 'moxie/core/utils/Dom', + 'moxie/core/Exceptions', + 'moxie/core/EventTarget', + 'moxie/core/I18n', + 'moxie/runtime/Runtime', + 'moxie/runtime/RuntimeClient' +], function(Basic, Env, Mime, Dom, x, EventTarget, I18n, Runtime, RuntimeClient) { + /** + Provides a convenient way to create cross-browser file-picker. Generates file selection dialog on click, + converts selected files to _File_ objects, to be used in conjunction with _Image_, preloaded in memory + with _FileReader_ or uploaded to a server through _XMLHttpRequest_. + + @class moxie/file/FileInput + @constructor + @extends EventTarget + @uses RuntimeClient + @param {Object|String|DOMElement} options If options is string or node, argument is considered as _browse\_button_. + @param {String|DOMElement} options.browse_button DOM Element to turn into file picker. + @param {Array} [options.accept] Array of mime types to accept. By default accepts all. + @param {Boolean} [options.multiple=false] Enable selection of multiple files. + @param {Boolean} [options.directory=false] Turn file input into the folder input (cannot be both at the same time). + @param {String|DOMElement} [options.container] DOM Element to use as a container for file-picker. Defaults to parentNode + for _browse\_button_. + @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support. + + @example +
+ Browse... +
+ + + */ + var dispatches = [ + /** + Dispatched when runtime is connected and file-picker is ready to be used. + + @event ready + @param {Object} event + */ + 'ready', + + /** + Dispatched right after [ready](#event_ready) event, and whenever [refresh()](#method_refresh) is invoked. + Check [corresponding documentation entry](#method_refresh) for more info. + + @event refresh + @param {Object} event + */ + + /** + Dispatched when selection of files in the dialog is complete. + + @event change + @param {Object} event + */ + 'change', + + 'cancel', // TODO: might be useful + + /** + Dispatched when mouse cursor enters file-picker area. Can be used to style element + accordingly. + + @event mouseenter + @param {Object} event + */ + 'mouseenter', + + /** + Dispatched when mouse cursor leaves file-picker area. Can be used to style element + accordingly. + + @event mouseleave + @param {Object} event + */ + 'mouseleave', + + /** + Dispatched when functional mouse button is pressed on top of file-picker area. + + @event mousedown + @param {Object} event + */ + 'mousedown', + + /** + Dispatched when functional mouse button is released on top of file-picker area. + + @event mouseup + @param {Object} event + */ + 'mouseup' + ]; + + function FileInput(options) { + if (MXI_DEBUG) { + Env.log("Instantiating FileInput..."); + } + + var container, browseButton, defaults; + + // if flat argument passed it should be browse_button id + if (Basic.inArray(Basic.typeOf(options), ['string', 'node']) !== -1) { + options = { browse_button : options }; + } + + // this will help us to find proper default container + browseButton = Dom.get(options.browse_button); + if (!browseButton) { + // browse button is required + throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); + } + + // figure out the options + defaults = { + accept: [{ + title: I18n.translate('All Files'), + extensions: '*' + }], + multiple: false, + required_caps: false, + container: browseButton.parentNode || document.body + }; + + options = Basic.extend({}, defaults, options); + + // convert to object representation + if (typeof(options.required_caps) === 'string') { + options.required_caps = Runtime.parseCaps(options.required_caps); + } + + // normalize accept option (could be list of mime types or array of title/extensions pairs) + if (typeof(options.accept) === 'string') { + options.accept = Mime.mimes2extList(options.accept); + } + + container = Dom.get(options.container); + // make sure we have container + if (!container) { + container = document.body; + } + + // make container relative, if it's not + if (Dom.getStyle(container, 'position') === 'static') { + container.style.position = 'relative'; + } + + container = browseButton = null; // IE + + RuntimeClient.call(this); + + Basic.extend(this, { + /** + Unique id of the component + + @property uid + @protected + @readOnly + @type {String} + @default UID + */ + uid: Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if any. + + @property ruid + @protected + @type {String} + */ + ruid: null, + + /** + Unique id of the runtime container. Useful to get hold of it for various manipulations. + + @property shimid + @protected + @type {String} + */ + shimid: null, + + /** + Array of selected moxie.file.File objects + + @property files + @type {Array} + @default null + */ + files: null, + + /** + Initializes the file-picker, connects it to runtime and dispatches event ready when done. + + @method init + */ + init: function() { + var self = this; + + self.bind('RuntimeInit', function(e, runtime) { + self.ruid = runtime.uid; + self.shimid = runtime.shimid; + + self.bind("Ready", function() { + self.trigger("Refresh"); + }, 999); + + // re-position and resize shim container + self.bind('Refresh', function() { + var pos, size, browseButton, shimContainer, zIndex; + + browseButton = Dom.get(options.browse_button); + shimContainer = Dom.get(runtime.shimid); // do not use runtime.getShimContainer(), since it will create container if it doesn't exist + + if (browseButton) { + pos = Dom.getPos(browseButton, Dom.get(options.container)); + size = Dom.getSize(browseButton); + zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 0; + + if (shimContainer) { + Basic.extend(shimContainer.style, { + top: pos.y + 'px', + left: pos.x + 'px', + width: size.w + 'px', + height: size.h + 'px', + zIndex: zIndex + 1 + }); + } + } + shimContainer = browseButton = null; + }); + + runtime.exec.call(self, 'FileInput', 'init', options); + }); + + // runtime needs: options.required_features, options.runtime_order and options.container + self.connectRuntime(Basic.extend({}, options, { + required_caps: { + select_file: true + } + })); + }, + + + /** + * Get current option value by its name + * + * @method getOption + * @param name + * @return {Mixed} + */ + getOption: function(name) { + return options[name]; + }, + + + /** + * Sets a new value for the option specified by name + * + * @method setOption + * @param name + * @param value + */ + setOption: function(name, value) { + if (!options.hasOwnProperty(name)) { + return; + } + + var oldValue = options[name]; + + switch (name) { + case 'accept': + if (typeof(value) === 'string') { + value = Mime.mimes2extList(value); + } + break; + + case 'container': + case 'required_caps': + throw new x.FileException(x.FileException.NO_MODIFICATION_ALLOWED_ERR); + } + + options[name] = value; + this.exec('FileInput', 'setOption', name, value); + + this.trigger('OptionChanged', name, value, oldValue); + }, + + /** + Disables file-picker element, so that it doesn't react to mouse clicks. + + @method disable + @param {Boolean} [state=true] Disable component if - true, enable if - false + */ + disable: function(state) { + var runtime = this.getRuntime(); + if (runtime) { + this.exec('FileInput', 'disable', Basic.typeOf(state) === 'undefined' ? true : state); + } + }, + + + /** + Reposition and resize dialog trigger to match the position and size of browse_button element. + + @method refresh + */ + refresh: function() { + this.trigger("Refresh"); + }, + + + /** + Destroy component. + + @method destroy + */ + destroy: function() { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileInput', 'destroy'); + this.disconnectRuntime(); + } + + if (Basic.typeOf(this.files) === 'array') { + // no sense in leaving associated files behind + Basic.each(this.files, function(file) { + file.destroy(); + }); + } + this.files = null; + + this.unbindAll(); + } + }); + + this.handleEventProps(dispatches); + } + + FileInput.prototype = EventTarget.instance; + + return FileInput; +}); + // Included from: src/javascript/file/File.js /** @@ -3588,7 +3984,7 @@ define('moxie/file/File', [ 'moxie/file/Blob' ], function(Basic, Mime, Blob) { /** - @class File + @class moxie/file/File @extends Blob @constructor @param {String} ruid Unique id of the runtime, to which this blob belongs to @@ -3691,10 +4087,10 @@ define('moxie/file/FileDrop', [
- @class FileDrop + @class moxie/file/FileDrop @constructor @extends EventTarget @uses RuntimeClient @@ -3855,7 +4251,7 @@ define('moxie/file/FileReader', [ Utility for preloading o.Blob/o.File objects in memory. By design closely follows [W3C FileReader](http://www.w3.org/TR/FileAPI/#dfn-filereader) interface. Where possible uses native FileReader, where - not falls back to shims. - @class FileReader + @class moxie/file/FileReader @constructor FileReader @extends EventTarget @uses RuntimeClient @@ -4118,13 +4514,20 @@ define('moxie/file/FileReader', [ * Contributing: http://www.plupload.com/contributing */ -define('moxie/core/utils/Url', [], function() { +/** +@class moxie/core/utils/Url +@public +@static +*/ + +define('moxie/core/utils/Url', [ + 'moxie/core/utils/Basic' +], function(Basic) { /** Parse url into separate components and fill in absent parts with parts from current url, based on https://raw.github.com/kvz/phpjs/master/functions/url/parse_url.js @method parseUrl - @for Utils @static @param {String} url Url to parse (defaults to empty string if undefined) @return {Object} Hash containing extracted uri components @@ -4137,24 +4540,36 @@ define('moxie/core/utils/Url', [], function() { https: 443 } , uri = {} - , regex = /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/ + , regex = /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?(\[[\da-fA-F:]+\]|[^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/ , m = regex.exec(url || '') + , isRelative + , isSchemeLess = /^\/\/\w/.test(url) ; - + + switch (Basic.typeOf(currentUrl)) { + case 'undefined': + currentUrl = parseUrl(document.location.href, false); + break; + + case 'string': + currentUrl = parseUrl(currentUrl, false); + break; + } + while (i--) { if (m[i]) { uri[key[i]] = m[i]; } } - // when url is relative, we set the origin and the path ourselves - if (!uri.scheme) { - // come up with defaults - if (!currentUrl || typeof(currentUrl) === 'string') { - currentUrl = parseUrl(currentUrl || document.location.href); - } + isRelative = !isSchemeLess && !uri.scheme; + if (isSchemeLess || isRelative) { uri.scheme = currentUrl.scheme; + } + + // when url is relative, we set the origin and the path ourselves + if (isRelative) { uri.host = currentUrl.host; uri.port = currentUrl.port; @@ -4175,8 +4590,8 @@ define('moxie/core/utils/Url', [], function() { if (!uri.port) { uri.port = ports[uri.scheme] || 80; - } - + } + uri.port = parseInt(uri.port, 10); if (!uri.path) { @@ -4211,6 +4626,7 @@ define('moxie/core/utils/Url', [], function() { Check if specified url has the same origin as the current document @method hasSameOrigin + @static @param {String|Object} url @return {Boolean} */ @@ -4218,11 +4634,11 @@ define('moxie/core/utils/Url', [], function() { function origin(url) { return [url.scheme, url.host, url.port].join('/'); } - + if (typeof url === 'string') { url = parseUrl(url); - } - + } + return origin(parseUrl()) === origin(url); }; @@ -4254,7 +4670,7 @@ define('moxie/runtime/RuntimeTarget', [ Instance of this class can be used as a target for the events dispatched by shims, when allowing them onto components is for either reason inappropriate - @class RuntimeTarget + @class moxie/runtime/RuntimeTarget @constructor @protected @extends EventTarget @@ -4297,7 +4713,7 @@ define('moxie/file/FileReaderSync', [ it can be used to read only preloaded blobs/files and only below certain size (not yet sure what that'd be, but probably < 1mb). Not meant to be used directly by user. - @class FileReaderSync + @class moxie/file/FileReaderSync @private @constructor */ @@ -4368,7 +4784,7 @@ define("moxie/xhr/FormData", [ /** FormData - @class FormData + @class moxie/xhr/FormData @constructor */ function FormData() { @@ -4555,13 +4971,13 @@ define("moxie/xhr/XMLHttpRequest", [ function XMLHttpRequestUpload() { this.uid = Basic.guid('uid_'); } - + XMLHttpRequestUpload.prototype = EventTarget.instance; /** Implementation of XMLHttpRequest - @class XMLHttpRequest + @class moxie/xhr/XMLHttpRequest @constructor @uses RuntimeClient @extends EventTarget @@ -4582,10 +4998,10 @@ define("moxie/xhr/XMLHttpRequest", [ 'loadend' // readystatechange (for historical reasons) - ]; - + ]; + var NATIVE = 1, RUNTIME = 2; - + function XMLHttpRequest() { var self = this, // this (together with _p() @see below) is here to gracefully upgrade to setter/getter syntax where possible @@ -4651,7 +5067,7 @@ define("moxie/xhr/XMLHttpRequest", [ /** Returns the response type. Can be set to change the response type. Values are: the empty string (default), "arraybuffer", "blob", "document", "json", and "text". - + @property responseType @type String */ @@ -4659,7 +5075,7 @@ define("moxie/xhr/XMLHttpRequest", [ /** Returns the document response entity body. - + Throws an "InvalidStateError" exception if responseType is not the empty string or "document". @property responseXML @@ -4669,7 +5085,7 @@ define("moxie/xhr/XMLHttpRequest", [ /** Returns the text response entity body. - + Throws an "InvalidStateError" exception if responseType is not the empty string or "text". @property responseText @@ -4680,7 +5096,7 @@ define("moxie/xhr/XMLHttpRequest", [ /** Returns the response entity body (http://www.w3.org/TR/XMLHttpRequest/#response-entity-body). Can become: ArrayBuffer, Blob, Document, JSON, Text - + @property response @type Mixed */ @@ -4717,7 +5133,7 @@ define("moxie/xhr/XMLHttpRequest", [ _responseHeadersBag ; - + Basic.extend(this, props, { /** Unique id of the component @@ -4726,7 +5142,7 @@ define("moxie/xhr/XMLHttpRequest", [ @type String */ uid: Basic.guid('uid_'), - + /** Target for Upload events @@ -4734,7 +5150,7 @@ define("moxie/xhr/XMLHttpRequest", [ @type XMLHttpRequestUpload */ upload: new XMLHttpRequestUpload(), - + /** Sets the request method, request URL, synchronous flag, request username, and request password. @@ -4762,12 +5178,12 @@ define("moxie/xhr/XMLHttpRequest", [ */ open: function(method, url, async, user, password) { var urlp; - + // first two arguments are required if (!method || !url) { throw new x.DOMException(x.DOMException.SYNTAX_ERR); } - + // 2 - check if any code point in method is higher than U+00FF or after deflating method it does not match the method if (/[\u0100-\uffff]/.test(method) || Encode.utf8_encode(method) !== method) { throw new x.DOMException(x.DOMException.SYNTAX_ERR); @@ -4777,8 +5193,8 @@ define("moxie/xhr/XMLHttpRequest", [ if (!!~Basic.inArray(method.toUpperCase(), ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'TRACE', 'TRACK'])) { _method = method.toUpperCase(); } - - + + // 4 - allowing these methods poses a security risk if (!!~Basic.inArray(_method, ['CONNECT', 'TRACE', 'TRACK'])) { throw new x.DOMException(x.DOMException.SECURITY_ERR); @@ -4786,15 +5202,15 @@ define("moxie/xhr/XMLHttpRequest", [ // 5 url = Encode.utf8_encode(url); - + // 6 - Resolve url relative to the XMLHttpRequest base URL. If the algorithm returns an error, throw a "SyntaxError". urlp = Url.parseUrl(url); _same_origin_flag = Url.hasSameOrigin(urlp); - + // 7 - manually build up absolute url _url = Url.resolveUrl(url); - + // 9-10, 12-13 if ((user || password) && !_same_origin_flag) { throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); @@ -4802,16 +5218,16 @@ define("moxie/xhr/XMLHttpRequest", [ _user = user || urlp.user; _password = password || urlp.pass; - + // 11 _async = async || true; - + if (_async === false && (_p('timeout') || _p('withCredentials') || _p('responseType') !== "")) { throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); } - + // 14 - terminate abort() - + // 15 - terminate send() // 18 @@ -4822,11 +5238,11 @@ define("moxie/xhr/XMLHttpRequest", [ // 19 _p('readyState', XMLHttpRequest.OPENED); - + // 20 this.dispatchEvent('readystatechange'); }, - + /** Appends an header to the list of author request headers, or if header is already in the list of author request headers, combines its value with value. @@ -4834,7 +5250,7 @@ define("moxie/xhr/XMLHttpRequest", [ Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set. Throws a "SyntaxError" exception if header is not a valid HTTP header field name or if value is not a valid HTTP header field value. - + @method setRequestHeader @param {String} header @param {String|Number} value @@ -4863,7 +5279,7 @@ define("moxie/xhr/XMLHttpRequest", [ "user-agent", "via" ]; - + // 1-2 if (_p('readyState') !== XMLHttpRequest.OPENED || _send_flag) { throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); @@ -4881,7 +5297,7 @@ define("moxie/xhr/XMLHttpRequest", [ }*/ header = Basic.trim(header).toLowerCase(); - + // setting of proxy-* and sec-* headers is prohibited by spec if (!!~Basic.inArray(header, uaHeaders) || /^(proxy\-|sec\-)/.test(header)) { return false; @@ -4890,7 +5306,7 @@ define("moxie/xhr/XMLHttpRequest", [ // camelize // browsers lowercase header names (at least for custom ones) // header = header.replace(/\b\w/g, function($1) { return $1.toUpperCase(); }); - + if (!_headers[header]) { _headers[header] = value; } else { @@ -4900,6 +5316,18 @@ define("moxie/xhr/XMLHttpRequest", [ return true; }, + /** + * Test if the specified header is already set on this request. + * Returns a header value or boolean false if it's not yet set. + * + * @method hasRequestHeader + * @param {String} header Name of the header to test + * @return {Boolean|String} + */ + hasRequestHeader: function(header) { + return header && _headers[header.toLowerCase()] || false; + }, + /** Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2. @@ -4911,7 +5339,7 @@ define("moxie/xhr/XMLHttpRequest", [ }, /** - Returns the header field value from the response of which the field name matches header, + Returns the header field value from the response of which the field name matches header, unless the field name is Set-Cookie or Set-Cookie2. @method getResponseHeader @@ -4946,7 +5374,7 @@ define("moxie/xhr/XMLHttpRequest", [ } return null; }, - + /** Sets the Content-Type header for the response to mime. Throws an "InvalidStateError" exception if the state is LOADING or DONE. @@ -4957,7 +5385,7 @@ define("moxie/xhr/XMLHttpRequest", [ */ overrideMimeType: function(mime) { var matches, charset; - + // 1 if (!!~Basic.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) { throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); @@ -4981,7 +5409,7 @@ define("moxie/xhr/XMLHttpRequest", [ _finalMime = mime; _finalCharset = charset; }, - + /** Initiates the request. The optional argument provides the request entity body. The argument is ignored if request method is GET or HEAD. @@ -4992,7 +5420,7 @@ define("moxie/xhr/XMLHttpRequest", [ @param {Blob|Document|String|FormData} [data] Request entity body @param {Object} [options] Set of requirements and pre-requisities for runtime initialization */ - send: function(data, options) { + send: function(data, options) { if (Basic.typeOf(options) === 'string') { _options = { ruid: options }; } else if (!options) { @@ -5000,19 +5428,19 @@ define("moxie/xhr/XMLHttpRequest", [ } else { _options = options; } - + // 1-2 if (this.readyState !== XMLHttpRequest.OPENED || _send_flag) { throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); } - - // 3 + + // 3 // sending Blob if (data instanceof Blob) { _options.ruid = data.ruid; _mimeType = data.type || 'application/octet-stream'; } - + // FormData else if (data instanceof FormData) { if (data.hasBlob()) { @@ -5021,12 +5449,12 @@ define("moxie/xhr/XMLHttpRequest", [ _mimeType = blob.type || 'application/octet-stream'; } } - + // DOMString else if (typeof data === 'string') { _encoding = 'UTF-8'; _mimeType = 'text/plain;charset=UTF-8'; - + // data should be converted to Unicode and encoded as UTF-8 data = Encode.utf8_encode(data); } @@ -5057,10 +5485,10 @@ define("moxie/xhr/XMLHttpRequest", [ // 8.5 - Return the send() method call, but continue running the steps in this algorithm. _doXHR.call(this, data); }, - + /** Cancels any network activity. - + @method abort */ abort: function() { @@ -5267,18 +5695,18 @@ define("moxie/xhr/XMLHttpRequest", [ } } } - + /* function _toASCII(str, AllowUnassigned, UseSTD3ASCIIRules) { // TODO: http://tools.ietf.org/html/rfc3490#section-4.1 return str.toLowerCase(); } */ - - + + function _doXHR(data) { var self = this; - + _start_time = new Date().getTime(); _xhr = new RuntimeTarget(); @@ -5298,12 +5726,12 @@ define("moxie/xhr/XMLHttpRequest", [ self.dispatchEvent('readystatechange'); self.dispatchEvent(e); - + if (_upload_events_flag) { self.upload.dispatchEvent(e); } }); - + _xhr.bind('Progress', function(e) { if (_p('readyState') !== XMLHttpRequest.LOADING) { _p('readyState', XMLHttpRequest.LOADING); // LoadStart unreliable (in Flash for example) @@ -5311,7 +5739,7 @@ define("moxie/xhr/XMLHttpRequest", [ } self.dispatchEvent(e); }); - + _xhr.bind('UploadProgress', function(e) { if (_upload_events_flag) { self.upload.dispatchEvent({ @@ -5322,12 +5750,12 @@ define("moxie/xhr/XMLHttpRequest", [ }); } }); - + _xhr.bind('Load', function(e) { _p('readyState', XMLHttpRequest.DONE); _p('status', Number(runtime.exec.call(_xhr, 'XMLHttpRequest', 'getStatus') || 0)); _p('statusText', httpCode[_p('status')] || ""); - + _p('response', runtime.exec.call(_xhr, 'XMLHttpRequest', 'getResponse', _p('responseType'))); if (!!~Basic.inArray(_p('responseType'), ['text', ''])) { @@ -5339,7 +5767,7 @@ define("moxie/xhr/XMLHttpRequest", [ _responseHeaders = runtime.exec.call(_xhr, 'XMLHttpRequest', 'getAllResponseHeaders'); self.dispatchEvent('readystatechange'); - + if (_p('status') > 0) { // status 0 usually means that server is unreachable if (_upload_events_flag) { self.upload.dispatchEvent(e); @@ -5356,7 +5784,7 @@ define("moxie/xhr/XMLHttpRequest", [ self.dispatchEvent(e); loadEnd(); }); - + _xhr.bind('Error', function(e) { _error_flag = true; _p('readyState', XMLHttpRequest.DONE); @@ -5401,7 +5829,7 @@ define("moxie/xhr/XMLHttpRequest", [ if (!_same_origin_flag) { _options.required_caps.do_cors = true; } - + if (_options.ruid) { // we do not need to wait if we can connect directly exec(_xhr.connectRuntime(_options)); @@ -5415,8 +5843,8 @@ define("moxie/xhr/XMLHttpRequest", [ _xhr.connectRuntime(_options); } } - - + + function _reset() { _p('responseText', ""); _p('responseXML', null); @@ -5432,7 +5860,7 @@ define("moxie/xhr/XMLHttpRequest", [ XMLHttpRequest.HEADERS_RECEIVED = 2; XMLHttpRequest.LOADING = 3; XMLHttpRequest.DONE = 4; - + XMLHttpRequest.prototype = EventTarget.instance; return XMLHttpRequest; @@ -5456,6 +5884,12 @@ define("moxie/runtime/Transporter", [ "moxie/runtime/RuntimeClient", "moxie/core/EventTarget" ], function(Basic, Encode, RuntimeClient, EventTarget) { + + /** + @class moxie/runtime/Transporter + @private + @constructor + */ function Transporter() { var mod, _runtime, _data, _size, _pos, _chunk_size; @@ -5605,7 +6039,7 @@ define("moxie/image/Image", [ /** Image preloading and manipulation utility. Additionally it provides access to image meta info (Exif, GPS) and raw binary data. - @class Image + @class moxie/image/Image @constructor @extends EventTarget */ @@ -5624,7 +6058,7 @@ define("moxie/image/Image", [ /** Dispatched when resize operation is complete. - + @event resize @param {Object} event */ @@ -5716,7 +6150,7 @@ define("moxie/image/Image", [ meta: {}, /** - Alias for load method, that takes another mOxie.Image object as a source (see load). + Alias for load method, that takes another moxie.image.Image object as a source (see load). @method clone @param {Image} src Source for the image @@ -5727,19 +6161,20 @@ define("moxie/image/Image", [ }, /** - Loads image from various sources. Currently the source for new image can be: mOxie.Image, mOxie.Blob/mOxie.File, - native Blob/File, dataUrl or URL. Depending on the type of the source, arguments - differ. When source is URL, - Image will be downloaded from remote destination and loaded in memory. + Loads image from various sources. Currently the source for new image can be: moxie.image.Image, + moxie.file.Blob/moxie.file.File, native Blob/File, dataUrl or URL. Depending on the type of the + source, arguments - differ. When source is URL, Image will be downloaded from remote destination + and loaded in memory. @example - var img = new mOxie.Image(); + var img = new moxie.image.Image(); img.onload = function() { var blob = img.getAsBlob(); - - var formData = new mOxie.FormData(); + + var formData = new moxie.xhr.FormData(); formData.append('file', blob); - var xhr = new mOxie.XMLHttpRequest(); + var xhr = new moxie.xhr.XMLHttpRequest(); xhr.onload = function() { // upload complete }; @@ -5747,7 +6182,7 @@ define("moxie/image/Image", [ xhr.send(formData); }; img.load("http://www.moxiecode.com/images/mox-logo.jpg"); // notice file extension (.jpg) - + @method load @param {Image|Blob|File|String} src Source for the image @@ -5757,30 +6192,188 @@ define("moxie/image/Image", [ _load.apply(this, arguments); }, + + /** + Resizes the image to fit the specified width/height. If crop is specified, image will also be + cropped to the exact dimensions. + + @method resize + @since 3.0 + @param {Object} options + @param {Number} options.width Resulting width + @param {Number} [options.height=width] Resulting height (optional, if not supplied will default to width) + @param {String} [options.type='image/jpeg'] MIME type of the resulting image + @param {Number} [options.quality=90] In the case of JPEG, controls the quality of resulting image + @param {Boolean} [options.crop='cc'] If not falsy, image will be cropped, by default from center + @param {Boolean} [options.fit=true] Whether to upscale the image to fit the exact dimensions + @param {Boolean} [options.preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) + @param {String} [options.resample='default'] Resampling algorithm to use during resize + @param {Boolean} [options.multipass=true] Whether to scale the image in steps (results in better quality) + */ + resize: function(options) { + var self = this; + var orientation; + var scale; + + var srcRect = { + x: 0, + y: 0, + width: self.width, + height: self.height + }; + + var opts = Basic.extendIf({ + width: self.width, + height: self.height, + type: self.type || 'image/jpeg', + quality: 90, + crop: false, + fit: true, + preserveHeaders: true, + resample: 'default', + multipass: true + }, options); + + try { + if (!self.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // no way to reliably intercept the crash due to high resolution, so we simply avoid it + if (self.width > Image.MAX_RESIZE_WIDTH || self.height > Image.MAX_RESIZE_HEIGHT) { + throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); + } + + // take into account orientation tag + orientation = (self.meta && self.meta.tiff && self.meta.tiff.Orientation) || 1; + + if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation + var tmp = opts.width; + opts.width = opts.height; + opts.height = tmp; + } + + if (opts.crop) { + scale = Math.max(opts.width/self.width, opts.height/self.height); + + if (options.fit) { + // first scale it up or down to fit the original image + srcRect.width = Math.min(Math.ceil(opts.width/scale), self.width); + srcRect.height = Math.min(Math.ceil(opts.height/scale), self.height); + + // recalculate the scale for adapted dimensions + scale = opts.width/srcRect.width; + } else { + srcRect.width = Math.min(opts.width, self.width); + srcRect.height = Math.min(opts.height, self.height); + + // now we do not need to scale it any further + scale = 1; + } + + if (typeof(opts.crop) === 'boolean') { + opts.crop = 'cc'; + } + + switch (opts.crop.toLowerCase().replace(/_/, '-')) { + case 'rb': + case 'right-bottom': + srcRect.x = self.width - srcRect.width; + srcRect.y = self.height - srcRect.height; + break; + + case 'cb': + case 'center-bottom': + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = self.height - srcRect.height; + break; + + case 'lb': + case 'left-bottom': + srcRect.x = 0; + srcRect.y = self.height - srcRect.height; + break; + + case 'lt': + case 'left-top': + srcRect.x = 0; + srcRect.y = 0; + break; + + case 'ct': + case 'center-top': + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = 0; + break; + + case 'rt': + case 'right-top': + srcRect.x = self.width - srcRect.width; + srcRect.y = 0; + break; + + case 'rc': + case 'right-center': + case 'right-middle': + srcRect.x = self.width - srcRect.width; + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + break; + + + case 'lc': + case 'left-center': + case 'left-middle': + srcRect.x = 0; + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + break; + + case 'cc': + case 'center-center': + case 'center-middle': + default: + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + } + + // original image might be smaller than requested crop, so - avoid negative values + srcRect.x = Math.max(srcRect.x, 0); + srcRect.y = Math.max(srcRect.y, 0); + } else { + scale = Math.min(opts.width/self.width, opts.height/self.height); + + // do not upscale if we were asked to not fit it + if (scale > 1 && !opts.fit) { + scale = 1; + } + } + + this.exec('Image', 'resize', srcRect, scale, opts); + } catch(ex) { + // for now simply trigger error event + self.trigger('error', ex.code); + } + }, + /** Downsizes the image to fit the specified width/height. If crop is supplied, image will be cropped to exact dimensions. @method downsize - @param {Object} opts - @param {Number} opts.width Resulting width - @param {Number} [opts.height=width] Resulting height (optional, if not supplied will default to width) - @param {Boolean} [opts.crop=false] Whether to crop the image to exact dimensions - @param {Boolean} [opts.preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) - @param {String} [opts.resample=false] Resampling algorithm to use for resizing + @deprecated use resize() */ - downsize: function(opts) { + downsize: function(options) { var defaults = { width: this.width, height: this.height, type: this.type || 'image/jpeg', quality: 90, crop: false, + fit: false, preserveHeaders: true, - resample: false - }; + resample: 'default' + }, opts; - if (typeof(opts) === 'object') { - opts = Basic.extend(defaults, opts); + if (typeof(options) === 'object') { + opts = Basic.extend(defaults, options); } else { // for backward compatibility opts = Basic.extend(defaults, { @@ -5791,26 +6384,12 @@ define("moxie/image/Image", [ }); } - try { - if (!this.size) { // only preloaded image objects can be used as source - throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); - } - - // no way to reliably intercept the crash due to high resolution, so we simply avoid it - if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) { - throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); - } - - this.exec('Image', 'downsize', opts.width, opts.height, opts.crop, opts.preserveHeaders); - } catch(ex) { - // for now simply trigger error event - this.trigger('error', ex.code); - } + this.resize(opts); }, /** Alias for downsize(width, height, true). (see downsize) - + @method crop @param {Number} width Resulting width @param {Number} [height=width] Resulting height (optional, if not supplied will default to width) @@ -5824,13 +6403,11 @@ define("moxie/image/Image", [ if (!Env.can('create_canvas')) { throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); } - - var runtime = this.connectRuntime(this.ruid); - return runtime.exec.call(this, 'Image', 'getAsCanvas'); + return this.exec('Image', 'getAsCanvas'); }, /** - Retrieves image in it's current state as mOxie.Blob object. Cannot be run on empty or image in progress (throws + Retrieves image in it's current state as moxie.file.Blob object. Cannot be run on empty or image in progress (throws DOMException.INVALID_STATE_ERR). @method getAsBlob @@ -5876,31 +6453,34 @@ define("moxie/image/Image", [ }, /** - Embeds a visual representation of the image into the specified node. Depending on the runtime, - it might be a canvas, an img node or a thrid party shim object (Flash or SilverLight - very rare, + Embeds a visual representation of the image into the specified node. Depending on the runtime, + it might be a canvas, an img node or a thrid party shim object (Flash or SilverLight - very rare, can be used in legacy browsers that do not have canvas or proper dataURI support). @method embed @param {DOMElement} el DOM element to insert the image object into - @param {Object} [opts] - @param {Number} [opts.width] The width of an embed (defaults to the image width) - @param {Number} [opts.height] The height of an embed (defaults to the image height) - @param {String} [type="image/jpeg"] Mime type - @param {Number} [quality=90] Quality of an embed, if mime type is image/jpeg - @param {Boolean} [crop=false] Whether to crop an embed to the specified dimensions + @param {Object} [options] + @param {Number} [options.width] The width of an embed (defaults to the image width) + @param {Number} [options.height] The height of an embed (defaults to the image height) + @param {String} [options.type="image/jpeg"] Mime type + @param {Number} [options.quality=90] Quality of an embed, if mime type is image/jpeg + @param {Boolean} [options.crop=false] Whether to crop an embed to the specified dimensions + @param {Boolean} [options.fit=true] By default thumbs will be up- or downscaled as necessary to fit the dimensions */ - embed: function(el, opts) { + embed: function(el, options) { var self = this , runtime // this has to be outside of all the closures to contain proper runtime ; - opts = Basic.extend({ + var opts = Basic.extend({ width: this.width, height: this.height, type: this.type || 'image/jpeg', - quality: 90 - }, opts || {}); - + quality: 90, + fit: true, + resample: 'nearest' + }, options); + function render(type, quality) { var img = this; @@ -5923,7 +6503,7 @@ define("moxie/image/Image", [ } if (Env.can('use_data_uri_of', dataUrl.length)) { - el.innerHTML = ''; + el.innerHTML = ''; img.destroy(); self.trigger('embedded'); } else { @@ -5976,7 +6556,7 @@ define("moxie/image/Image", [ if (!this.size) { // only preloaded image objects can be used as source throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); } - + // high-resolution images cannot be consistently handled across the runtimes if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) { //throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); @@ -5989,7 +6569,7 @@ define("moxie/image/Image", [ }); imgCopy.bind("Load", function() { - imgCopy.downsize(opts); + this.downsize(opts); }); // if embedded thumb data is available and dimensions are big enough, use it @@ -6007,7 +6587,8 @@ define("moxie/image/Image", [ }, /** - Properly destroys the image and frees resources in use. If any. Recommended way to dispose mOxie.Image object. + Properly destroys the image and frees resources in use. If any. Recommended way to dispose + moxie.image.Image object. @method destroy */ @@ -6016,6 +6597,10 @@ define("moxie/image/Image", [ this.getRuntime().exec.call(this, 'Image', 'destroy'); this.disconnectRuntime(); } + if (this.meta && this.meta.thumb) { + // thumb is blob, make sure we destroy it first + this.meta.thumb.data.destroy(); + } this.unbindAll(); } }); @@ -6025,27 +6610,34 @@ define("moxie/image/Image", [ this.handleEventProps(dispatches); this.bind('Load Resize', function() { - _updateInfo.call(this); + return _updateInfo.call(this); // if operation fails (e.g. image is neither PNG nor JPEG) cancel all pending events }, 999); function _updateInfo(info) { - if (!info) { - info = this.exec('Image', 'getInfo'); - } + try { + if (!info) { + info = this.exec('Image', 'getInfo'); + } - this.size = info.size; - this.width = info.width; - this.height = info.height; - this.type = info.type; - this.meta = info.meta; + this.size = info.size; + this.width = info.width; + this.height = info.height; + this.type = info.type; + this.meta = info.meta; - // update file name, only if empty - if (this.name === '') { - this.name = info.name; + // update file name, only if empty + if (this.name === '') { + this.name = info.name; + } + + return true; + } catch(ex) { + this.trigger('error', ex.code); + return false; } } - + function _load(src) { var srcType = Basic.typeOf(src); @@ -6167,7 +6759,7 @@ define("moxie/image/Image", [ // virtual world will crash on you if image has a resolution higher than this: Image.MAX_RESIZE_WIDTH = 8192; - Image.MAX_RESIZE_HEIGHT = 8192; + Image.MAX_RESIZE_HEIGHT = 8192; Image.prototype = EventTarget.instance; @@ -6214,7 +6806,10 @@ define("moxie/runtime/html5/Runtime", [ access_image_binary: function() { return I.can('access_binary') && !!extensions.Image; }, - display_media: Test(Env.can('create_canvas') || Env.can('use_data_uri_over32kb')), + display_media: Test( + (Env.can('create_canvas') || Env.can('use_data_uri_over32kb')) && + defined('moxie/image/Image') + ), do_cors: Test(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()), drag_and_drop: Test(function() { // this comes directly from Modernizr: http://www.modernizr.com/ @@ -6224,9 +6819,12 @@ define("moxie/runtime/html5/Runtime", [ (Env.browser !== 'IE' || Env.verComp(Env.version, 9, '>')); }()), filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest - return (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '>=')) || - (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || - (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '>=')); + return !( + (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) || + (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '<')) || + (Env.browser === 'Firefox' && Env.verComp(Env.version, 37, '<')) + ); }()), return_response_headers: True, return_response_type: function(responseType) { @@ -6244,7 +6842,10 @@ define("moxie/runtime/html5/Runtime", [ return Env.can('use_fileinput') && window.File; }, select_folder: function() { - return I.can('select_file') && Env.browser === 'Chrome' && Env.verComp(Env.version, 21, '>='); + return I.can('select_file') && ( + Env.browser === 'Chrome' && Env.verComp(Env.version, 21, '>=') || + Env.browser === 'Firefox' && Env.verComp(Env.version, 42, '>=') // https://developer.mozilla.org/en-US/Firefox/Releases/42 + ); }, select_multiple: function() { // it is buggy on Safari Windows and iOS @@ -6262,14 +6863,14 @@ define("moxie/runtime/html5/Runtime", [ return I.can('slice_blob') && I.can('send_multipart'); }, summon_file_dialog: function() { // yeah... some dirty sniffing here... - return I.can('select_file') && ( - (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '>=')) || - (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '>=')) || - (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || - !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']) + return I.can('select_file') && !( + (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '<')) || + (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) ); }, - upload_filesize: True + upload_filesize: True, + use_http_method: True }, arguments[2] ); @@ -6299,6 +6900,59 @@ define("moxie/runtime/html5/Runtime", [ return extensions; }); +// Included from: src/javascript/runtime/html5/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/Blob +@private +*/ +define("moxie/runtime/html5/file/Blob", [ + "moxie/runtime/html5/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + function HTML5Blob() { + function w3cBlobSlice(blob, start, end) { + var blobSlice; + + if (window.File.prototype.slice) { + try { + blob.slice(); // depricated version will throw WRONG_ARGUMENTS_ERR exception + return blob.slice(start, end); + } catch (e) { + // depricated slice method + return blob.slice(start, end - start); + } + // slice method got prefixed: https://bugzilla.mozilla.org/show_bug.cgi?id=649672 + } else if ((blobSlice = window.File.prototype.webkitSlice || window.File.prototype.mozSlice)) { + return blobSlice.call(blob, start, end); + } else { + return null; // or throw some exception + } + } + + this.slice = function() { + return new Blob(this.getRuntime().uid, w3cBlobSlice.apply(this, arguments)); + }; + + this.destroy = function() { + this.getRuntime().getShim().removeInstance(this.uid); + }; + } + + return (extensions.Blob = HTML5Blob); +}); + // Included from: src/javascript/core/utils/Events.js /** @@ -6311,6 +6965,12 @@ define("moxie/runtime/html5/Runtime", [ * Contributing: http://www.plupload.com/contributing */ +/** +@class moxie/core/utils/Events +@public +@static +*/ + define('moxie/core/utils/Events', [ 'moxie/core/utils/Basic' ], function(Basic) { @@ -6330,7 +6990,6 @@ define('moxie/core/utils/Events', [ in objects internal Plupload registry (@see removeEvent). @method addEvent - @for Utils @static @param {Object} obj DOM element like object to add handler to. @param {String} name Name to add event listener to. @@ -6499,7 +7158,7 @@ define("moxie/runtime/html5/file/FileInput", [ ], function(extensions, File, Basic, Dom, Events, Mime, Env) { function FileInput() { - var _options; + var _options, _browseBtnZIndex; // save original z-index Basic.extend(this, { init: function(options) { @@ -6508,7 +7167,7 @@ define("moxie/runtime/html5/file/FileInput", [ _options = options; // figure out accept string - mimes = _options.accept.mimes || Mime.extList2mimes(_options.accept, I.can('filter_by_extension')); + mimes = Mime.extList2mimes(_options.accept, I.can('filter_by_extension')); shimContainer = I.getShimContainer(); @@ -6530,6 +7189,7 @@ define("moxie/runtime/html5/file/FileInput", [ browseButton = Dom.get(_options.browse_button); + _browseBtnZIndex = Dom.getStyle(browseButton, 'z-index') || 'auto'; // Route click event to the input[type=file] element for browsers that support such behavior if (I.can('summon_file_dialog')) { @@ -6537,11 +7197,6 @@ define("moxie/runtime/html5/file/FileInput", [ browseButton.style.position = 'relative'; } - zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 1; - - browseButton.style.zIndex = zIndex; - shimContainer.style.zIndex = zIndex - 1; - Events.addEvent(browseButton, 'click', function(e) { var input = Dom.get(I.uid); if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file] @@ -6549,6 +7204,13 @@ define("moxie/runtime/html5/file/FileInput", [ } e.preventDefault(); }, comp.uid); + + comp.bind('Refresh', function() { + zIndex = parseInt(_browseBtnZIndex, 10) || 1; + + Dom.get(_options.browse_button).style.zIndex = zIndex; + this.getRuntime().getShimContainer().style.zIndex = zIndex - 1; + }); } /* Since we have to place input[type=file] on top of the browse_button for some browsers, @@ -6571,8 +7233,10 @@ define("moxie/runtime/html5/file/FileInput", [ comp.trigger('mouseup'); }, comp.uid); + // it shouldn't be possible to tab into the hidden element + (I.can('summon_file_dialog') ? input : browseButton).setAttribute('tabindex', -1); - input.onchange = function onChange(e) { // there should be only one handler for this + input.onchange = function onChange() { // there should be only one handler for this comp.files = []; Basic.each(this.files, function(file) { @@ -6621,6 +7285,41 @@ define("moxie/runtime/html5/file/FileInput", [ }, + setOption: function(name, value) { + var I = this.getRuntime(); + var input = Dom.get(I.uid); + + switch (name) { + case 'accept': + if (value) { + var mimes = value.mimes || Mime.extList2mimes(value, I.can('filter_by_extension')); + input.setAttribute('accept', mimes.join(',')); + } else { + input.removeAttribute('accept'); + } + break; + + case 'directory': + if (value && I.can('select_folder')) { + input.setAttribute('directory', ''); + input.setAttribute('webkitdirectory', ''); + } else { + input.removeAttribute('directory'); + input.removeAttribute('webkitdirectory'); + } + break; + + case 'multiple': + if (value && I.can('select_multiple')) { + input.setAttribute('multiple', ''); + } else { + input.removeAttribute('multiple'); + } + + } + }, + + disable: function(state) { var I = this.getRuntime(), input; @@ -6633,19 +7332,27 @@ define("moxie/runtime/html5/file/FileInput", [ var I = this.getRuntime() , shim = I.getShim() , shimContainer = I.getShimContainer() + , container = _options && Dom.get(_options.container) + , browseButton = _options && Dom.get(_options.browse_button) ; - Events.removeAllEvents(shimContainer, this.uid); - Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); - Events.removeAllEvents(_options && Dom.get(_options.browse_button), this.uid); + if (container) { + Events.removeAllEvents(container, this.uid); + } + + if (browseButton) { + Events.removeAllEvents(browseButton, this.uid); + browseButton.style.zIndex = _browseBtnZIndex; // reset to original value + } if (shimContainer) { + Events.removeAllEvents(shimContainer, this.uid); shimContainer.innerHTML = ''; } shim.removeInstance(this.uid); - _options = shimContainer = shim = null; + _options = shimContainer = container = browseButton = shim = null; } }); } @@ -6653,55 +7360,6 @@ define("moxie/runtime/html5/file/FileInput", [ return (extensions.FileInput = FileInput); }); -// Included from: src/javascript/runtime/html5/file/Blob.js - -/** - * Blob.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -/** -@class moxie/runtime/html5/file/Blob -@private -*/ -define("moxie/runtime/html5/file/Blob", [ - "moxie/runtime/html5/Runtime", - "moxie/file/Blob" -], function(extensions, Blob) { - - function HTML5Blob() { - function w3cBlobSlice(blob, start, end) { - var blobSlice; - - if (window.File.prototype.slice) { - try { - blob.slice(); // depricated version will throw WRONG_ARGUMENTS_ERR exception - return blob.slice(start, end); - } catch (e) { - // depricated slice method - return blob.slice(start, end - start); - } - // slice method got prefixed: https://bugzilla.mozilla.org/show_bug.cgi?id=649672 - } else if ((blobSlice = window.File.prototype.webkitSlice || window.File.prototype.mozSlice)) { - return blobSlice.call(blob, start, end); - } else { - return null; // or throw some exception - } - } - - this.slice = function() { - return new Blob(this.getRuntime().uid, w3cBlobSlice.apply(this, arguments)); - }; - } - - return (extensions.Blob = HTML5Blob); -}); - // Included from: src/javascript/runtime/html5/file/FileDrop.js /** @@ -6782,6 +7440,7 @@ define("moxie/runtime/html5/file/FileDrop", [ destroy: function() { Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); _ruid = _files = _allowedExts = _options = null; + this.getRuntime().getShim().removeInstance(this.uid); } }); @@ -6974,6 +7633,7 @@ define("moxie/runtime/html5/file/FileReader", [ destroy: function() { _fr = null; + this.getRuntime().getShim().removeInstance(this.uid); } }); @@ -7141,11 +7801,14 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [ _xhr.onreadystatechange = function() {}; // usually status 0 is returned when server is unreachable, but FF also fails to status 0 for 408 timeout - if (_xhr.status === 0) { - target.trigger('error'); - } else { - target.trigger('load'); - } + try { + if (_xhr.status >= 200 && _xhr.status < 400) { + target.trigger('load'); + break; + } + } catch(ex) {} + + target.trigger('error'); break; } }; @@ -7256,6 +7919,7 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [ destroy: function() { self = _filename = null; + this.getRuntime().getShim().removeInstance(this.uid); } }); @@ -7388,7 +8052,6 @@ define("moxie/runtime/html5/utils/BinaryReader", [ UTF16StringReader.apply(this, arguments); } } -   Basic.extend(BinaryReader.prototype, { @@ -8488,8 +9151,16 @@ define("moxie/runtime/html5/image/PNG", [ */ /** +Optional image investigation tool for HTML5 runtime. Provides the following features: +- ability to distinguish image type (JPEG or PNG) by signature +- ability to extract image width/height directly from it's internals, without preloading in memory (fast) +- ability to extract APP headers from JPEGs (Exif, GPS, etc) +- ability to replace width/height tags in extracted JPEG headers +- ability to restore APP headers, that were for example stripped during image manipulation + @class moxie/runtime/html5/image/ImageInfo @private +@param {String} data Image source as binary string */ define("moxie/runtime/html5/image/ImageInfo", [ "moxie/core/utils/Basic", @@ -8497,18 +9168,7 @@ define("moxie/runtime/html5/image/ImageInfo", [ "moxie/runtime/html5/image/JPEG", "moxie/runtime/html5/image/PNG" ], function(Basic, x, JPEG, PNG) { - /** - Optional image investigation tool for HTML5 runtime. Provides the following features: - - ability to distinguish image type (JPEG or PNG) by signature - - ability to extract image width/height directly from it's internals, without preloading in memory (fast) - - ability to extract APP headers from JPEGs (Exif, GPS, etc) - - ability to replace width/height tags in extracted JPEG headers - - ability to restore APP headers, that were for example stripped during image manipulation - @class ImageInfo - @constructor - @param {String} data Image source as binary string - */ return function(data) { var _cs = [JPEG, PNG], _img; @@ -8611,141 +9271,62 @@ define("moxie/runtime/html5/image/ImageInfo", [ }; }); -// Included from: src/javascript/runtime/html5/image/MegaPixel.js +// Included from: src/javascript/runtime/html5/image/ResizerCanvas.js /** -(The MIT License) - -Copyright (c) 2012 Shinichi Tomita ; - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/** - * Mega pixel image rendering library for iOS6 Safari + * ResizerCanvas.js * - * Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel), - * which causes unexpected subsampling when drawing it in canvas. - * By using this library, you can safely render the image with proper stretching. + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. * - * Copyright (c) 2012 Shinichi Tomita - * Released under the MIT license + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing */ /** -@class moxie/runtime/html5/image/MegaPixel -@private -*/ -define("moxie/runtime/html5/image/MegaPixel", [], function() { + * Resizes image/canvas using canvas + */ +define("moxie/runtime/html5/image/ResizerCanvas", [], function() { - /** - * Rendering image element (with resizing) into the canvas element - */ - function renderImageToCanvas(img, canvas, options) { - var iw = img.naturalWidth, ih = img.naturalHeight; - var width = options.width, height = options.height; - var x = options.x || 0, y = options.y || 0; - var ctx = canvas.getContext('2d'); - if (detectSubsampling(img)) { - iw /= 2; - ih /= 2; - } - var d = 1024; // size of tiling canvas - var tmpCanvas = document.createElement('canvas'); - tmpCanvas.width = tmpCanvas.height = d; - var tmpCtx = tmpCanvas.getContext('2d'); - var vertSquashRatio = detectVerticalSquash(img, iw, ih); - var sy = 0; - while (sy < ih) { - var sh = sy + d > ih ? ih - sy : d; - var sx = 0; - while (sx < iw) { - var sw = sx + d > iw ? iw - sx : d; - tmpCtx.clearRect(0, 0, d, d); - tmpCtx.drawImage(img, -sx, -sy); - var dx = (sx * width / iw + x) << 0; - var dw = Math.ceil(sw * width / iw); - var dy = (sy * height / ih / vertSquashRatio + y) << 0; - var dh = Math.ceil(sh * height / ih / vertSquashRatio); - ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh); - sx += d; - } - sy += d; - } - tmpCanvas = tmpCtx = null; - } + function scale(image, ratio, resample) { + var sD = image.width > image.height ? 'width' : 'height'; // take the largest side + var dD = Math.round(image[sD] * ratio); + var scaleCapped = false; - /** - * Detect subsampling in loaded image. - * In iOS, larger images than 2M pixels may be subsampled in rendering. - */ - function detectSubsampling(img) { - var iw = img.naturalWidth, ih = img.naturalHeight; - if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image - var canvas = document.createElement('canvas'); - canvas.width = canvas.height = 1; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, -iw + 1, 0); - // subsampled image becomes half smaller in rendering size. - // check alpha channel value to confirm image is covering edge pixel or not. - // if alpha value is 0 image is not covering, hence subsampled. - return ctx.getImageData(0, 0, 1, 1).data[3] === 0; - } else { - return false; - } - } + if (resample !== 'nearest' && (ratio < 0.5 || ratio > 2)) { + ratio = ratio < 0.5 ? 0.5 : 2; + scaleCapped = true; + } + + var tCanvas = _scale(image, ratio); + + if (scaleCapped) { + return scale(tCanvas, dD / tCanvas[sD], resample); + } else { + return tCanvas; + } + } - /** - * Detecting vertical squash in loaded image. - * Fixes a bug which squash image vertically while drawing into canvas for some images. - */ - function detectVerticalSquash(img, iw, ih) { - var canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = ih; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0); - var data = ctx.getImageData(0, 0, 1, ih).data; - // search image edge pixel position in case it is squashed vertically. - var sy = 0; - var ey = ih; - var py = ih; - while (py > sy) { - var alpha = data[(py - 1) * 4 + 3]; - if (alpha === 0) { - ey = py; - } else { - sy = py; - } - py = (ey + sy) >> 1; - } - canvas = null; - var ratio = (py / ih); - return (ratio === 0) ? 1 : ratio; - } + function _scale(image, ratio) { + var sW = image.width; + var sH = image.height; + var dW = Math.round(sW * ratio); + var dH = Math.round(sH * ratio); + + var canvas = document.createElement('canvas'); + canvas.width = dW; + canvas.height = dH; + canvas.getContext("2d").drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH); + + image = null; // just in case + return canvas; + } + + return { + scale: scale + }; - return { - isSubsampled: detectSubsampling, - renderTo: renderImageToCanvas - }; }); // Included from: src/javascript/runtime/html5/image/Image.js @@ -8772,11 +9353,11 @@ define("moxie/runtime/html5/image/Image", [ "moxie/file/Blob", "moxie/file/File", "moxie/runtime/html5/image/ImageInfo", - "moxie/runtime/html5/image/MegaPixel", + "moxie/runtime/html5/image/ResizerCanvas", "moxie/core/utils/Mime", "moxie/core/utils/Env" -], function(extensions, Basic, x, Encode, Blob, File, ImageInfo, MegaPixel, Mime, Env) { - +], function(extensions, Basic, x, Encode, Blob, File, ImageInfo, ResizerCanvas, Mime, Env) { + function HTML5Image() { var me = this , _img, _imgInfo, _canvas, _binStr, _blob @@ -8786,7 +9367,7 @@ define("moxie/runtime/html5/image/Image", [ Basic.extend(this, { loadFromBlob: function(blob) { - var comp = this, I = comp.getRuntime() + var I = this.getRuntime() , asBinary = arguments.length > 1 ? arguments[1] : true ; @@ -8805,7 +9386,7 @@ define("moxie/runtime/html5/image/Image", [ if (asBinary) { _binStr = _toBinary(dataUrl); } - _preload.call(comp, dataUrl); + _preload.call(this, dataUrl); }); } }, @@ -8829,46 +9410,78 @@ define("moxie/runtime/html5/image/Image", [ _imgInfo = new ImageInfo(_binStr); } + // this stuff below is definitely having fun with itself info = { width: _getImg().width || 0, height: _getImg().height || 0, type: _blob.type || Mime.getFileMime(_blob.name), size: _binStr && _binStr.length || _blob.size || 0, name: _blob.name || '', - meta: _imgInfo && _imgInfo.meta || this.meta || {} + meta: null }; - // store thumbnail data as blob - if (info.meta && info.meta.thumb && !(info.meta.thumb.data instanceof Blob)) { - info.meta.thumb.data = new Blob(null, { - type: 'image/jpeg', - data: info.meta.thumb.data - }); + if (_preserveHeaders) { + info.meta = _imgInfo && _imgInfo.meta || this.meta || {}; + + // if data was taken from ImageInfo it will be a binary string, so we convert it to blob + if (info.meta && info.meta.thumb && !(info.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(null, { + type: 'image/jpeg', + data: info.meta.thumb.data + }); + } } return info; }, - downsize: function() { - _downsize.apply(this, arguments); + + resize: function(rect, ratio, options) { + var canvas = document.createElement('canvas'); + canvas.width = rect.width; + canvas.height = rect.height; + + canvas.getContext("2d").drawImage(_getImg(), rect.x, rect.y, rect.width, rect.height, 0, 0, canvas.width, canvas.height); + + _canvas = ResizerCanvas.scale(canvas, ratio); + + _preserveHeaders = options.preserveHeaders; + + // rotate if required, according to orientation tag + if (!_preserveHeaders) { + var orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1; + _canvas = _rotateToOrientaion(_canvas, orientation); + } + + this.width = _canvas.width; + this.height = _canvas.height; + + _modified = true; + + this.trigger('Resize'); }, getAsCanvas: function() { - if (_canvas) { - _canvas.id = this.uid + '_canvas'; + if (!_canvas) { + _canvas = _getCanvas(); } + _canvas.id = this.uid + '_canvas'; return _canvas; }, getAsBlob: function(type, quality) { if (type !== this.type) { - // if different mime type requested prepare image for conversion - _downsize.call(this, this.width, this.height, false); + _modified = true; // reconsider the state + return new File(null, { + name: _blob.name || '', + type: type, + data: me.getAsDataURL(type, quality) + }); } return new File(null, { name: _blob.name || '', type: type, - data: me.getAsBinaryString.call(this, type, quality) + data: me.getAsBinaryString(type, quality) }); }, @@ -8880,6 +9493,9 @@ define("moxie/runtime/html5/image/Image", [ return _img.src; } + // make sure we have a canvas to work with + _getCanvas(); + if ('image/jpeg' !== type) { return _canvas.toDataURL('image/png'); } else { @@ -8912,6 +9528,9 @@ define("moxie/runtime/html5/image/Image", [ quality = 90; } + // make sure we have a canvas to work with + _getCanvas(); + try { // older Geckos used to result in an exception on quality argument dataUrl = _canvas.toDataURL('image/jpeg', quality/100); @@ -8964,6 +9583,19 @@ define("moxie/runtime/html5/image/Image", [ } + function _getCanvas() { + var canvas = _getImg(); + if (canvas.nodeName.toLowerCase() == 'canvas') { + return canvas; + } + _canvas = document.createElement('canvas'); + _canvas.width = canvas.width; + _canvas.height = canvas.height; + _canvas.getContext("2d").drawImage(canvas, 0, 0); + return _canvas; + } + + function _toBinary(str) { return Encode.atob(str.substring(str.indexOf('base64,') + 7)); } @@ -8997,130 +9629,35 @@ define("moxie/runtime/html5/image/Image", [ if (window.FileReader) { fr = new FileReader(); fr.onload = function() { - callback(this.result); + callback.call(comp, this.result); }; fr.onerror = function() { comp.trigger('error', x.ImageError.WRONG_FORMAT); }; fr.readAsDataURL(file); } else { - return callback(file.getAsDataURL()); + return callback.call(this, file.getAsDataURL()); } } - function _downsize(width, height, crop, preserveHeaders) { - var self = this - , scale - , mathFn - , x = 0 - , y = 0 - , img - , destWidth - , destHeight - , orientation - ; - - _preserveHeaders = preserveHeaders; // we will need to check this on export (see getAsBinaryString()) - - // take into account orientation tag - orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1; - - if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation - // swap dimensions - var tmp = width; - width = height; - height = tmp; - } - - img = _getImg(); - - // unify dimensions - if (!crop) { - scale = Math.min(width/img.width, height/img.height); - } else { - // one of the dimensions may exceed the actual image dimensions - we need to take the smallest value - width = Math.min(width, img.width); - height = Math.min(height, img.height); - - scale = Math.max(width/img.width, height/img.height); - } - - // we only downsize here - if (scale > 1 && !crop && preserveHeaders) { - this.trigger('Resize'); - return; - } - - // prepare canvas if necessary - if (!_canvas) { - _canvas = document.createElement("canvas"); - } - - // calculate dimensions of proportionally resized image - destWidth = Math.round(img.width * scale); - destHeight = Math.round(img.height * scale); - - // scale image and canvas - if (crop) { - _canvas.width = width; - _canvas.height = height; - - // if dimensions of the resulting image still larger than canvas, center it - if (destWidth > width) { - x = Math.round((destWidth - width) / 2); - } - - if (destHeight > height) { - y = Math.round((destHeight - height) / 2); - } - } else { - _canvas.width = destWidth; - _canvas.height = destHeight; - } - - // rotate if required, according to orientation tag - if (!_preserveHeaders) { - _rotateToOrientaion(_canvas.width, _canvas.height, orientation); - } - - _drawToCanvas.call(this, img, _canvas, -x, -y, destWidth, destHeight); - - this.width = _canvas.width; - this.height = _canvas.height; - - _modified = true; - self.trigger('Resize'); - } - - - function _drawToCanvas(img, canvas, x, y, w, h) { - if (Env.OS === 'iOS') { - // avoid squish bug in iOS6 - MegaPixel.renderTo(img, canvas, { width: w, height: h, x: x, y: y }); - } else { - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, x, y, w, h); - } - } - - /** * Transform canvas coordination according to specified frame size and orientation * Orientation value is from EXIF tag * @author Shinichi Tomita */ - function _rotateToOrientaion(width, height, orientation) { - switch (orientation) { - case 5: - case 6: - case 7: - case 8: - _canvas.width = height; - _canvas.height = width; - break; - default: - _canvas.width = width; - _canvas.height = height; + function _rotateToOrientaion(img, orientation) { + var RADIANS = Math.PI/180; + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + var width = img.width; + var height = img.height; + + if (Basic.inArray(orientation, [5,6,7,8]) > -1) { + canvas.width = height; + canvas.height = width; + } else { + canvas.width = width; + canvas.height = height; } /** @@ -9133,8 +9670,6 @@ define("moxie/runtime/html5/image/Image", [ 7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. 8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. */ - - var ctx = _canvas.getContext('2d'); switch (orientation) { case 2: // horizontal flip @@ -9144,7 +9679,7 @@ define("moxie/runtime/html5/image/Image", [ case 3: // 180 rotate left ctx.translate(width, height); - ctx.rotate(Math.PI); + ctx.rotate(180 * RADIANS); break; case 4: // vertical flip @@ -9153,26 +9688,29 @@ define("moxie/runtime/html5/image/Image", [ break; case 5: // vertical flip + 90 rotate right - ctx.rotate(0.5 * Math.PI); + ctx.rotate(90 * RADIANS); ctx.scale(1, -1); break; case 6: // 90 rotate right - ctx.rotate(0.5 * Math.PI); + ctx.rotate(90 * RADIANS); ctx.translate(0, -height); break; case 7: // horizontal flip + 90 rotate right - ctx.rotate(0.5 * Math.PI); + ctx.rotate(90 * RADIANS); ctx.translate(width, -height); ctx.scale(-1, 1); break; case 8: // 90 rotate left - ctx.rotate(-0.5 * Math.PI); + ctx.rotate(-90 * RADIANS); ctx.translate(-width, 0); break; } + + ctx.drawImage(img, 0, 0, width, height); + return canvas; } @@ -9181,6 +9719,7 @@ define("moxie/runtime/html5/image/Image", [ _imgInfo.purge(); _imgInfo = null; } + _binStr = _img = _canvas = _blob = null; _modified = false; } @@ -9189,22 +9728,1308 @@ define("moxie/runtime/html5/image/Image", [ return (extensions.Image = HTML5Image); }); -/** - * Stub for moxie/runtime/flash/Runtime - * @private - */ -define("moxie/runtime/flash/Runtime", [ -], function() { - return {}; -}); +// Included from: src/javascript/runtime/flash/Runtime.js /** - * Stub for moxie/runtime/silverlight/Runtime - * @private + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Flash runtime. + +@class moxie/runtime/flash/Runtime +@private +*/ +define("moxie/runtime/flash/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = 'flash', extensions = {}; + + /** + Get the version of the Flash Player + + @method getShimVersion + @private + @return {Number} Flash Player version + */ + function getShimVersion() { + var version; + + try { + version = navigator.plugins['Shockwave Flash']; + version = version.description; + } catch (e1) { + try { + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch (e2) { + version = '0.0'; + } + } + version = version.match(/\d+/g); + return parseFloat(version[0] + '.' + version[1]); + } + + + /** + Cross-browser SWF removal + - Especially needed to safely and completely remove a SWF in Internet Explorer + + Originated from SWFObject v2.2 + */ + function removeSWF(id) { + var obj = Dom.get(id); + if (obj && obj.nodeName == "OBJECT") { + if (Env.browser === 'IE') { + obj.style.display = "none"; + (function onInit(){ + // http://msdn.microsoft.com/en-us/library/ie/ms534360(v=vs.85).aspx + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(onInit, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + + function removeObjectInIE(id) { + var obj = Dom.get(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + /** + Constructor for the Flash Runtime + */ + function FlashRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ swf_url: Env.swf_url }, options); + + Runtime.call(this, options, type, { + access_binary: function(value) { + return value && I.mode === 'browser'; + }, + access_image_binary: function(value) { + return value && I.mode === 'browser'; + }, + display_media: Runtime.capTest(defined('moxie/image/Image')), + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: function() { + return I.mode === 'client'; + }, + resize_image: Runtime.capTrue, + return_response_headers: false, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { + return true; + } + return !Basic.arrayDiff(responseType, ['', 'text', 'document']) || I.mode === 'browser'; + }, + return_status_code: function(code) { + return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: function(value) { + return value && I.mode === 'browser'; + }, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'browser'; + }, + send_multipart: Runtime.capTrue, + slice_blob: function(value) { + return value && I.mode === 'browser'; + }, + stream_upload: function(value) { + return value && I.mode === 'browser'; + }, + summon_file_dialog: false, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client'; + }, + use_http_method: function(methods) { + return !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + access_binary: function(value) { + return value ? 'browser' : 'client'; + }, + access_image_binary: function(value) { + return value ? 'browser' : 'client'; + }, + report_upload_progress: function(value) { + return value ? 'browser' : 'client'; + }, + return_response_type: function(responseType) { + return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser']; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser']; + }, + send_binary_string: function(value) { + return value ? 'browser' : 'client'; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'browser' : 'client'; + }, + slice_blob: function(value) { + return value ? 'browser' : 'client'; + }, + stream_upload: function(value) { + return value ? 'client' : 'browser'; + }, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser'; + } + }, 'client'); + + + // minimal requirement for Flash Player version + if (getShimVersion() < 11.3) { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tFlash didn't meet minimal version requirement (11.3)."); + } + + this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before + } + + + Basic.extend(this, { + + getShim: function() { + return Dom.get(this.uid); + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init: function() { + var html, el, container; + + container = this.getShimContainer(); + + // if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) + Basic.extend(container.style, { + position: 'absolute', + top: '-8px', + left: '-8px', + width: '9px', + height: '9px', + overflow: 'hidden' + }); + + // insert flash object + html = '' + + '' + + '' + + '' + + ''; + + if (Env.browser === 'IE') { + el = document.createElement('div'); + container.appendChild(el); + el.outerHTML = html; + el = container = null; // just in case + } else { + container.innerHTML = html; + } + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tFlash failed to initialize within a specified period of time (typically 5s)."); + } + } + }, 5000); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + removeSWF(I.uid); // SWF removal requires special care in IE + + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, FlashRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/flash/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/Blob +@private +*/ +define("moxie/runtime/flash/file/Blob", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var FlashBlob = { + slice: function(blob, start, end, type) { + var self = this.getRuntime(); + + if (start < 0) { + start = Math.max(blob.size + start, 0); + } else if (start > 0) { + start = Math.min(start, blob.size); + } + + if (end < 0) { + end = Math.max(blob.size + end, 0); + } else if (end > 0) { + end = Math.min(end, blob.size); + } + + blob = self.shimExec.call(this, 'Blob', 'slice', start, end, type || ''); + + if (blob) { + blob = new Blob(self.uid, blob); + } + return blob; + } + }; + + return (extensions.Blob = FlashBlob); +}); + +// Included from: src/javascript/runtime/flash/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileInput +@private +*/ +define("moxie/runtime/flash/file/FileInput", [ + "moxie/runtime/flash/Runtime", + "moxie/file/File", + "moxie/core/utils/Dom", + "moxie/core/utils/Basic" +], function(extensions, File, Dom, Basic) { + + var FileInput = { + init: function(options) { + var comp = this, I = this.getRuntime(); + var browseButton = Dom.get(options.browse_button); + + if (browseButton) { + browseButton.setAttribute('tabindex', -1); + browseButton = null; + } + + this.bind("Change", function() { + var files = I.shimExec.call(comp, 'FileInput', 'getFiles'); + comp.files = []; + Basic.each(files, function(file) { + comp.files.push(new File(I.uid, file)); + }); + }, 999); + + this.getRuntime().shimExec.call(this, 'FileInput', 'init', { + accept: options.accept, + multiple: options.multiple + }); + + this.trigger('ready'); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/flash/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReader +@private +*/ +define("moxie/runtime/flash/file/FileReader", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReader = { + read: function(op, blob) { + var comp = this; + + comp.result = ''; + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + comp.result = 'data:' + (blob.type || '') + ';base64,'; + } + + comp.bind('Progress', function(e, data) { + if (data) { + comp.result += _formatData(data, op); + } + }, 999); + + return comp.getRuntime().shimExec.call(this, 'FileReader', 'readAsBase64', blob.uid); + } + }; + + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/flash/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReaderSync +@private +*/ +define("moxie/runtime/flash/file/FileReaderSync", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReaderSync = { + read: function(op, blob) { + var result, self = this.getRuntime(); + + result = self.shimExec.call(this, 'FileReaderSync', 'readAsBase64', blob.uid); + if (!result) { + return null; // or throw ex + } + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + result = 'data:' + (blob.type || '') + ';base64,' + result; + } + + return _formatData(result, op, blob.type); + } + }; + + return (extensions.FileReaderSync = FileReaderSync); +}); + +// Included from: src/javascript/runtime/flash/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/runtime/Transporter +@private +*/ +define("moxie/runtime/flash/runtime/Transporter", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var Transporter = { + getAsBlob: function(type) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Transporter', 'getAsBlob', type) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + } + }; + + return (extensions.Transporter = Transporter); +}); + +// Included from: src/javascript/runtime/flash/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/flash/xhr/XMLHttpRequest", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/file/Blob", + "moxie/file/File", + "moxie/file/FileReaderSync", + "moxie/runtime/flash/file/FileReaderSync", + "moxie/xhr/FormData", + "moxie/runtime/Transporter", + "moxie/runtime/flash/runtime/Transporter" +], function(extensions, Basic, Blob, File, FileReaderSync, FileReaderSyncFlash, FormData, Transporter, TransporterFlash) { + + var XMLHttpRequest = { + + send: function(meta, data) { + var target = this, self = target.getRuntime(); + + function send() { + meta.transport = self.mode; + self.shimExec.call(target, 'XMLHttpRequest', 'send', meta, data); + } + + + function appendBlob(name, blob) { + self.shimExec.call(target, 'XMLHttpRequest', 'appendBlob', name, blob.uid); + data = null; + send(); + } + + + function attachBlob(blob, cb) { + var tr = new Transporter(); + + tr.bind("TransportingComplete", function() { + cb(this.result); + }); + + tr.transport(blob.getSource(), blob.type, { + ruid: self.uid + }); + } + + // copy over the headers if any + if (!Basic.isEmptyObj(meta.headers)) { + Basic.each(meta.headers, function(value, header) { + self.shimExec.call(target, 'XMLHttpRequest', 'setRequestHeader', header, value.toString()); // Silverlight doesn't accept integers into the arguments of type object + }); + } + + // transfer over multipart params and blob itself + if (data instanceof FormData) { + var blobField; + data.each(function(value, name) { + if (value instanceof Blob) { + blobField = name; + } else { + self.shimExec.call(target, 'XMLHttpRequest', 'append', name, value); + } + }); + + if (!data.hasBlob()) { + data = null; + send(); + } else { + var blob = data.getBlob(); + if (blob.isDetached()) { + attachBlob(blob, function(attachedBlob) { + blob.destroy(); + appendBlob(blobField, attachedBlob); + }); + } else { + appendBlob(blobField, blob); + } + } + } else if (data instanceof Blob) { + if (data.isDetached()) { + attachBlob(data, function(attachedBlob) { + data.destroy(); + data = attachedBlob.uid; + send(); + }); + } else { + data = data.uid; + send(); + } + } else { + send(); + } + }, + + getResponse: function(responseType) { + var frs, blob, self = this.getRuntime(); + + blob = self.shimExec.call(this, 'XMLHttpRequest', 'getResponseAsBlob'); + + if (blob) { + blob = new File(self.uid, blob); + + if ('blob' === responseType) { + return blob; + } + + try { + frs = new FileReaderSync(); + + if (!!~Basic.inArray(responseType, ["", "text"])) { + return frs.readAsText(blob); + } else if ('json' === responseType && !!window.JSON) { + return JSON.parse(frs.readAsText(blob)); + } + } finally { + blob.destroy(); + } + } + return null; + }, + + abort: function(upload_complete_flag) { + var self = this.getRuntime(); + + self.shimExec.call(this, 'XMLHttpRequest', 'abort'); + + this.dispatchEvent('readystatechange'); + // this.dispatchEvent('progress'); + this.dispatchEvent('abort'); + + //if (!upload_complete_flag) { + // this.dispatchEvent('uploadprogress'); + //} + } + }; + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/flash/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/image/Image +@private +*/ +define("moxie/runtime/flash/image/Image", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/Transporter", + "moxie/file/Blob", + "moxie/file/FileReaderSync" +], function(extensions, Basic, Transporter, Blob, FileReaderSync) { + + var Image = { + loadFromBlob: function(blob) { + var comp = this, self = comp.getRuntime(); + + function exec(srcBlob) { + self.shimExec.call(comp, 'Image', 'loadFromBlob', srcBlob.uid); + comp = self = null; + } + + if (blob.isDetached()) { // binary string + var tr = new Transporter(); + tr.bind("TransportingComplete", function() { + exec(tr.result.getSource()); + }); + tr.transport(blob.getSource(), blob.type, { ruid: self.uid }); + } else { + exec(blob.getSource()); + } + }, + + loadFromImage: function(img) { + var self = this.getRuntime(); + return self.shimExec.call(this, 'Image', 'loadFromImage', img.uid); + }, + + getInfo: function() { + var self = this.getRuntime() + , info = self.shimExec.call(this, 'Image', 'getInfo') + ; + + if (info.meta && info.meta.thumb && info.meta.thumb.data && !(self.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(self.uid, info.meta.thumb.data); + } + return info; + }, + + getAsBlob: function(type, quality) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Image', 'getAsBlob', type, quality) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + }, + + getAsDataURL: function() { + var self = this.getRuntime() + , blob = self.Image.getAsBlob.apply(this, arguments) + , frs + ; + if (!blob) { + return null; + } + frs = new FileReaderSync(); + return frs.readAsDataURL(blob); + } + }; + + return (extensions.Image = Image); +}); + +// Included from: src/javascript/runtime/silverlight/Runtime.js + +/** + * RunTime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Silverlight runtime. + +@class moxie/runtime/silverlight/Runtime +@private +*/ define("moxie/runtime/silverlight/Runtime", [ -], function() { - return {}; + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = "silverlight", extensions = {}; + + function isInstalled(version) { + var isVersionSupported = false, control = null, actualVer, + actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0; + + try { + try { + control = new ActiveXObject('AgControl.AgControl'); + + if (control.IsVersionSupported(version)) { + isVersionSupported = true; + } + + control = null; + } catch (e) { + var plugin = navigator.plugins["Silverlight Plug-In"]; + + if (plugin) { + actualVer = plugin.description; + + if (actualVer === "1.0.30226.2") { + actualVer = "2.0.30226.2"; + } + + actualVerArray = actualVer.split("."); + + while (actualVerArray.length > 3) { + actualVerArray.pop(); + } + + while ( actualVerArray.length < 4) { + actualVerArray.push(0); + } + + reqVerArray = version.split("."); + + while (reqVerArray.length > 4) { + reqVerArray.pop(); + } + + do { + requiredVersionPart = parseInt(reqVerArray[index], 10); + actualVersionPart = parseInt(actualVerArray[index], 10); + index++; + } while (index < reqVerArray.length && requiredVersionPart === actualVersionPart); + + if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) { + isVersionSupported = true; + } + } + } + } catch (e2) { + isVersionSupported = false; + } + + return isVersionSupported; + } + + /** + Constructor for the Silverlight Runtime + */ + function SilverlightRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ xap_url: Env.xap_url }, options); + + Runtime.call(this, options, type, { + access_binary: Runtime.capTrue, + access_image_binary: Runtime.capTrue, + display_media: Runtime.capTest(defined('moxie/image/Image')), + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: Runtime.capTrue, + resize_image: Runtime.capTrue, + return_response_headers: function(value) { + return value && I.mode === 'client'; + }, + return_response_type: function(responseType) { + if (responseType !== 'json') { + return true; + } else { + return !!window.JSON; + } + }, + return_status_code: function(code) { + return I.mode === 'client' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: Runtime.capTrue, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'client'; + }, + send_multipart: Runtime.capTrue, + slice_blob: Runtime.capTrue, + stream_upload: true, + summon_file_dialog: false, + upload_filesize: Runtime.capTrue, + use_http_method: function(methods) { + return I.mode === 'client' || !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + return_response_headers: function(value) { + return value ? 'client' : 'browser'; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'client' : ['client', 'browser']; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'client' : 'browser'; + }, + use_http_method: function(methods) { + return Basic.arrayDiff(methods, ['GET', 'POST']) ? 'client' : ['client', 'browser']; + } + }); + + + // minimal requirement + if (!isInstalled('2.0.31005.0') || Env.browser === 'Opera') { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tSilverlight is not installed or minimal version (2.0.31005.0) requirement not met (not likely)."); + } + + this.mode = false; + } + + + Basic.extend(this, { + getShim: function() { + return Dom.get(this.uid).content.Moxie; + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init : function() { + var container; + + container = this.getShimContainer(); + + container.innerHTML = '' + + '' + + '' + + '' + + '' + + '' + + ''; + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\Silverlight failed to initialize within a specified period of time (5-10s)."); + } + } + }, Env.OS !== 'Windows'? 10000 : 5000); // give it more time to initialize in non Windows OS (like Mac) + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, SilverlightRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/silverlight/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/Blob +@private +*/ +define("moxie/runtime/silverlight/file/Blob", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/Blob" +], function(extensions, Basic, Blob) { + return (extensions.Blob = Basic.extend({}, Blob)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileInput +@private +*/ +define("moxie/runtime/silverlight/file/FileInput", [ + "moxie/runtime/silverlight/Runtime", + "moxie/file/File", + "moxie/core/utils/Dom", + "moxie/core/utils/Basic" +], function(extensions, File, Dom, Basic) { + + function toFilters(accept) { + var filter = ''; + for (var i = 0; i < accept.length; i++) { + filter += (filter !== '' ? '|' : '') + accept[i].title + " | *." + accept[i].extensions.replace(/,/g, ';*.'); + } + return filter; + } + + + var FileInput = { + init: function(options) { + var comp = this, I = this.getRuntime(); + var browseButton = Dom.get(options.browse_button); + + if (browseButton) { + browseButton.setAttribute('tabindex', -1); + browseButton = null; + } + + this.bind("Change", function() { + var files = I.shimExec.call(comp, 'FileInput', 'getFiles'); + comp.files = []; + Basic.each(files, function(file) { + comp.files.push(new File(I.uid, file)); + }); + }, 999); + + I.shimExec.call(this, 'FileInput', 'init', toFilters(options.accept), options.multiple); + this.trigger('ready'); + }, + + setOption: function(name, value) { + if (name == 'accept') { + value = toFilters(value); + } + this.getRuntime().shimExec.call(this, 'FileInput', 'setOption', name, value); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileDrop +@private +*/ +define("moxie/runtime/silverlight/file/FileDrop", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Dom", + "moxie/core/utils/Events" +], function(extensions, Dom, Events) { + + // not exactly useful, since works only in safari (...crickets...) + var FileDrop = { + init: function() { + var comp = this, self = comp.getRuntime(), dropZone; + + dropZone = self.getShimContainer(); + + Events.addEvent(dropZone, 'dragover', function(e) { + e.preventDefault(); + e.stopPropagation(); + e.dataTransfer.dropEffect = 'copy'; + }, comp.uid); + + Events.addEvent(dropZone, 'dragenter', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragEnter(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + Events.addEvent(dropZone, 'drop', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragDrop(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + return self.shimExec.call(this, 'FileDrop', 'init'); + } + }; + + return (extensions.FileDrop = FileDrop); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReader +@private +*/ +define("moxie/runtime/silverlight/file/FileReader", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReader" +], function(extensions, Basic, FileReader) { + return (extensions.FileReader = Basic.extend({}, FileReader)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReaderSync +@private +*/ +define("moxie/runtime/silverlight/file/FileReaderSync", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReaderSync" +], function(extensions, Basic, FileReaderSync) { + return (extensions.FileReaderSync = Basic.extend({}, FileReaderSync)); +}); + +// Included from: src/javascript/runtime/silverlight/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/runtime/Transporter +@private +*/ +define("moxie/runtime/silverlight/runtime/Transporter", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/runtime/Transporter" +], function(extensions, Basic, Transporter) { + return (extensions.Transporter = Basic.extend({}, Transporter)); +}); + +// Included from: src/javascript/runtime/silverlight/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/silverlight/xhr/XMLHttpRequest", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/xhr/XMLHttpRequest", + "moxie/runtime/silverlight/file/FileReaderSync", + "moxie/runtime/silverlight/runtime/Transporter" +], function(extensions, Basic, XMLHttpRequest, FileReaderSyncSilverlight, TransporterSilverlight) { + return (extensions.XMLHttpRequest = Basic.extend({}, XMLHttpRequest)); +}); + +// Included from: src/javascript/runtime/silverlight/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/image/Image +@private +*/ +define("moxie/runtime/silverlight/image/Image", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/file/Blob", + "moxie/runtime/flash/image/Image" +], function(extensions, Basic, Blob, Image) { + return (extensions.Image = Basic.extend({}, Image, { + + getInfo: function() { + var self = this.getRuntime() + , grps = ['tiff', 'exif', 'gps', 'thumb'] + , info = { meta: {} } + , rawInfo = self.shimExec.call(this, 'Image', 'getInfo') + ; + + if (rawInfo.meta) { + Basic.each(grps, function(grp) { + var meta = rawInfo.meta[grp] + , tag + , i + , length + , value + ; + if (meta && meta.keys) { + info.meta[grp] = {}; + for (i = 0, length = meta.keys.length; i < length; i++) { + tag = meta.keys[i]; + value = meta[tag]; + if (value) { + // convert numbers + if (/^(\d|[1-9]\d+)$/.test(value)) { // integer (make sure doesn't start with zero) + value = parseInt(value, 10); + } else if (/^\d*\.\d+$/.test(value)) { // double + value = parseFloat(value); + } + info.meta[grp][tag] = value; + } + } + } + }); + + // save thumb data as blob + if (info.meta && info.meta.thumb && info.meta.thumb.data && !(self.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(self.uid, info.meta.thumb.data); + } + } + + info.width = parseInt(rawInfo.width, 10); + info.height = parseInt(rawInfo.height, 10); + info.size = parseInt(rawInfo.size, 10); + info.type = rawInfo.type; + info.name = rawInfo.name; + + return info; + }, + + resize: function(rect, ratio, opts) { + this.getRuntime().shimExec.call(this, 'Image', 'resize', rect.x, rect.y, rect.width, rect.height, ratio, opts.preserveHeaders, opts.resample); + } + })); }); // Included from: src/javascript/runtime/html4/Runtime.js @@ -9245,13 +11070,19 @@ define("moxie/runtime/html4/Runtime", [ Runtime.call(this, options, type, { access_binary: Test(window.FileReader || window.File && File.getAsDataURL), access_image_binary: false, - display_media: Test(extensions.Image && (Env.can('create_canvas') || Env.can('use_data_uri_over32kb'))), + display_media: Test( + (Env.can('create_canvas') || Env.can('use_data_uri_over32kb')) && + defined('moxie/image/Image') + ), do_cors: false, drag_and_drop: false, filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest - return (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '>=')) || - (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || - (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '>=')); + return !( + (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) || + (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '<')) || + (Env.browser === 'Firefox' && Env.verComp(Env.version, 37, '<')) + ); }()), resize_image: function() { return extensions.Image && I.can('access_binary') && Env.can('create_canvas'); @@ -9279,11 +11110,10 @@ define("moxie/runtime/html4/Runtime", [ return I.can('select_file'); }, summon_file_dialog: function() { // yeah... some dirty sniffing here... - return I.can('select_file') && ( - (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '>=')) || - (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '>=')) || - (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || - !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']) + return I.can('select_file') && !( + (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '<')) || + (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) ); }, upload_filesize: True, @@ -9341,19 +11171,21 @@ define("moxie/runtime/html4/file/FileInput", [ ], function(extensions, File, Basic, Dom, Events, Mime, Env) { function FileInput() { - var _uid, _mimes = [], _options; + var _uid, _mimes = [], _options, _browseBtnZIndex; // save original z-index; function addInput() { var comp = this, I = comp.getRuntime(), shimContainer, browseButton, currForm, form, input, uid; uid = Basic.guid('uid_'); - shimContainer = I.getShimContainer(); // we get new ref everytime to avoid memory leaks in IE + shimContainer = I.getShimContainer(); // we get new ref every time to avoid memory leaks in IE if (_uid) { // move previous form out of the view currForm = Dom.get(_uid + '_form'); if (currForm) { Basic.extend(currForm.style, { top: '100%' }); + // it shouldn't be possible to tab into the hidden element + currForm.firstChild.setAttribute('tabindex', -1); } } @@ -9376,9 +11208,12 @@ define("moxie/runtime/html4/file/FileInput", [ input = document.createElement('input'); input.setAttribute('id', uid); input.setAttribute('type', 'file'); - input.setAttribute('name', _options.name || 'Filedata'); input.setAttribute('accept', _mimes.join(',')); + if (I.can('summon_file_dialog')) { + input.setAttribute('tabindex', -1); + } + Basic.extend(input.style, { fontSize: '999px', opacity: 0 @@ -9411,12 +11246,6 @@ define("moxie/runtime/html4/file/FileInput", [ if (this.files) { // check if browser is fresh enough file = this.files[0]; - - // ignore empty files (IE10 for example hangs if you try to send them via XHR) - if (file.size === 0) { - form.parentNode.removeChild(form); - return; - } } else { file = { name: this.value @@ -9464,7 +11293,7 @@ define("moxie/runtime/html4/file/FileInput", [ // figure out accept string _options = options; - _mimes = options.accept.mimes || Mime.extList2mimes(options.accept, I.can('filter_by_extension')); + _mimes = Mime.extList2mimes(options.accept, I.can('filter_by_extension')); shimContainer = I.getShimContainer(); @@ -9472,17 +11301,23 @@ define("moxie/runtime/html4/file/FileInput", [ var browseButton, zIndex, top; browseButton = Dom.get(options.browse_button); + _browseBtnZIndex = Dom.getStyle(browseButton, 'z-index') || 'auto'; // Route click event to the input[type=file] element for browsers that support such behavior if (I.can('summon_file_dialog')) { if (Dom.getStyle(browseButton, 'position') === 'static') { browseButton.style.position = 'relative'; - } + } - zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 1; + comp.bind('Refresh', function() { + zIndex = parseInt(_browseBtnZIndex, 10) || 1; - browseButton.style.zIndex = zIndex; - shimContainer.style.zIndex = zIndex - 1; + Dom.get(_options.browse_button).style.zIndex = zIndex; + this.getRuntime().getShimContainer().style.zIndex = zIndex - 1; + }); + } else { + // it shouldn't be possible to tab into the hidden element + browseButton.setAttribute('tabindex', -1); } /* Since we have to place input[type=file] on top of the browse_button for some browsers, @@ -9519,6 +11354,21 @@ define("moxie/runtime/html4/file/FileInput", [ }); }, + setOption: function(name, value) { + var I = this.getRuntime(); + var input; + + if (name == 'accept') { + _mimes = value.mimes || Mime.extList2mimes(value, I.can('filter_by_extension')); + } + + // update current input + input = Dom.get(_uid) + if (input) { + input.setAttribute('accept', _mimes.join(',')); + } + }, + disable: function(state) { var input; @@ -9532,19 +11382,27 @@ define("moxie/runtime/html4/file/FileInput", [ var I = this.getRuntime() , shim = I.getShim() , shimContainer = I.getShimContainer() + , container = _options && Dom.get(_options.container) + , browseButton = _options && Dom.get(_options.browse_button) ; - Events.removeAllEvents(shimContainer, this.uid); - Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); - Events.removeAllEvents(_options && Dom.get(_options.browse_button), this.uid); + if (container) { + Events.removeAllEvents(container, this.uid); + } + + if (browseButton) { + Events.removeAllEvents(browseButton, this.uid); + browseButton.style.zIndex = _browseBtnZIndex; // reset to original value + } if (shimContainer) { + Events.removeAllEvents(shimContainer, this.uid); shimContainer.innerHTML = ''; } shim.removeInstance(this.uid); - _uid = _mimes = _options = shimContainer = shim = null; + _uid = _mimes = _options = shimContainer = container = browseButton = shim = null; } }); } @@ -9817,6 +11675,10 @@ define("moxie/runtime/html4/xhr/XMLHttpRequest", [ // target.dispatchEvent('readystatechange'); target.dispatchEvent('abort'); }); + }, + + destroy: function() { + this.getRuntime().getShim().removeInstance(this.uid); } }); } @@ -9847,55 +11709,6 @@ define("moxie/runtime/html4/image/Image", [ return (extensions.Image = Image); }); -expose(["moxie/core/utils/Basic","moxie/core/utils/Env","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/FileInput","moxie/core/utils/Encode","moxie/file/Blob","moxie/file/File","moxie/file/FileDrop","moxie/file/FileReader","moxie/core/utils/Url","moxie/runtime/RuntimeTarget","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/image/Image","moxie/core/utils/Events"]); -})(this); -/** - * o.js - * - * Copyright 2013, Moxiecode Systems AB - * Released under GPL License. - * - * License: http://www.plupload.com/license - * Contributing: http://www.plupload.com/contributing - */ - -/*global moxie:true */ - -/** -Globally exposed namespace with the most frequently used public classes and handy methods. - -@class o -@static -@private -*/ -(function(exports) { - "use strict"; - - var o = {}, inArray = exports.moxie.core.utils.Basic.inArray; - - // directly add some public classes - // (we do it dynamically here, since for custom builds we cannot know beforehand what modules were included) - (function addAlias(ns) { - var name, itemType; - for (name in ns) { - itemType = typeof(ns[name]); - if (itemType === 'object' && !~inArray(name, ['Exceptions', 'Env', 'Mime'])) { - addAlias(ns[name]); - } else if (itemType === 'function') { - o[name] = ns[name]; - } - } - })(exports.moxie); - - // add some manually - o.Env = exports.moxie.core.utils.Env; - o.Mime = exports.moxie.core.utils.Mime; - o.Exceptions = exports.moxie.core.Exceptions; - - // expose globally - exports.mOxie = o; - if (!exports.o) { - exports.o = o; - } - return o; +expose(["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Dom","moxie/core/EventTarget","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/core/I18n","moxie/core/utils/Mime","moxie/file/FileInput","moxie/file/File","moxie/file/FileDrop","moxie/file/FileReader","moxie/core/utils/Url","moxie/runtime/RuntimeTarget","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/image/Image","moxie/core/utils/Events","moxie/runtime/html5/image/ResizerCanvas"]); })(this); +})); \ No newline at end of file diff --git a/wp-includes/js/plupload/moxie.min.js b/wp-includes/js/plupload/moxie.min.js index c1680c87a6..6cc398bc2f 100644 --- a/wp-includes/js/plupload/moxie.min.js +++ b/wp-includes/js/plupload/moxie.min.js @@ -1 +1 @@ -var MXI_DEBUG=!1;!function(a,v){"use strict";var s={};function e(e,t,i){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(t===v)throw"invalid module definition, dependencies must be specified";if(i===v)throw"invalid module definition, definition function must be specified";!function(e,t){for(var i,n=[],r=0;rt[a]){s=1;break}}if(!i)return s;switch(i){case">":case"gt":return 0=":case"ge":return 0<=s;case"<=":case"le":return s<=0;case"==":case"=":case"eq":return 0===s;case"<>":case"!=":case"ne":return 0!==s;case"":case"<":case"lt":return s<0;default:return null}},global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return g.OS=g.os,MXI_DEBUG&&(g.debug={runtime:!0,events:!1},g.log=function(){var e,t=arguments[0];if("string"===n.typeOf(t)&&(t=n.sprintf.apply(this,arguments)),window&&window.console&&window.console.log)window.console.log(t);else if(document){var i=document.getElementById("moxie-console");i||((i=document.createElement("pre")).id="moxie-console",document.body.appendChild(i)),-1!==n.inArray(n.typeOf(t),["object","array"])?(e=t,i.appendChild(document.createTextNode(e+"\n"))):i.appendChild(document.createTextNode(t+"\n"))}}),g}),e("moxie/core/I18n",["moxie/core/utils/Basic"],function(i){var t={};return{addI18n:function(e){return i.extend(t,e)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(e){var t=[].slice.call(arguments,1);return e.replace(/%[a-z]/g,function(){var e=t.shift();return"undefined"!==i.typeOf(e)?e:""})}}}),e("moxie/core/utils/Mime",["moxie/core/utils/Basic","moxie/core/I18n"],function(s,n){var e={mimes:{},extensions:{},addMimeType:function(e){var t,i,n,r=e.split(/,/);for(t=0;t>16&255,n=s>>8&255,r=255&s,h[d++]=64==o?String.fromCharCode(i):64==a?String.fromCharCode(i,n):String.fromCharCode(i,n,r),l>18&63,n=a>>12&63,r=a>>6&63,o=63&a,d[c++]=s.charAt(i)+s.charAt(n)+s.charAt(r)+s.charAt(o),ug.MAX_RESIZE_WIDTH||this.height>g.MAX_RESIZE_HEIGHT)throw new l.ImageError(l.ImageError.MAX_RESOLUTION_ERR);this.exec("Image","downsize",e.width,e.height,e.crop,e.preserveHeaders)}catch(e){this.trigger("error",e.code)}},crop:function(e,t,i){this.downsize(e,t,!0,i)},getAsCanvas:function(){if(!h.can("create_canvas"))throw new l.RuntimeError(l.RuntimeError.NOT_SUPPORTED_ERR);return this.connectRuntime(this.ruid).exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new l.DOMException(l.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsBlob",e||"image/jpeg",t||90)},getAsDataURL:function(e,t){if(!this.size)throw new l.DOMException(l.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsDataURL",e||"image/jpeg",t||90)},getAsBinaryString:function(e,t){var i=this.getAsDataURL(e,t);return f.atob(i.substring(i.indexOf("base64,")+7))},embed:function(a,e){var s,u=this;e=c.extend({width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90},e||{});try{if(!(a=i.get(a)))throw new l.DOMException(l.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new l.DOMException(l.DOMException.INVALID_STATE_ERR);this.width>g.MAX_RESIZE_WIDTH||this.height;var t=new g;return t.bind("Resize",function(){(function(e,t){var i=this;if(h.can("create_canvas")){var n=i.getAsCanvas();if(n)return a.appendChild(n),n=null,i.destroy(),void u.trigger("embedded")}var r=i.getAsDataURL(e,t);if(!r)throw new l.ImageError(l.ImageError.WRONG_FORMAT);if(h.can("use_data_uri_of",r.length))a.innerHTML='',i.destroy(),u.trigger("embedded");else{var o=new d;o.bind("TransportingComplete",function(){s=u.connectRuntime(this.result.ruid),u.bind("Embedded",function(){c.extend(s.getShimContainer().style,{top:"0px",left:"0px",width:i.width+"px",height:i.height+"px"}),s=null},999),s.exec.call(u,"ImageView","display",this.result.uid,width,height),i.destroy()}),o.transport(f.atob(r.substring(r.indexOf("base64,")+7)),e,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:a})}}).call(this,e.type,e.quality)}),t.bind("Load",function(){t.downsize(e)}),this.meta.thumb&&this.meta.thumb.width>=e.width&&this.meta.thumb.height>=e.height?t.load(this.meta.thumb.data):t.clone(this,!1),t}catch(e){this.trigger("error",e.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}}),this.handleEventProps(p),this.bind("Load Resize",function(){(function(e){e=e||this.exec("Image","getInfo");this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}).call(this)},999)}return g.MAX_RESIZE_WIDTH=8192,g.MAX_RESIZE_HEIGHT=8192,g.prototype=n.instance,g}),e("moxie/runtime/html5/Runtime",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/Runtime","moxie/core/utils/Env"],function(s,e,u,c){var l={};return u.addConstructor("html5",function(e){var t,i,n=this,r=u.capTest,o=u.capTrue,a=s.extend({access_binary:r(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return n.can("access_binary")&&!!l.Image},display_media:r(c.can("create_canvas")||c.can("use_data_uri_over32kb")),do_cors:r(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:r((t=document.createElement("div"),("draggable"in t||"ondragstart"in t&&"ondrop"in t)&&("IE"!==c.browser||c.verComp(c.version,9,">")))),filter_by_extension:r("Chrome"===c.browser&&c.verComp(c.version,28,">=")||"IE"===c.browser&&c.verComp(c.version,10,">=")||"Safari"===c.browser&&c.verComp(c.version,7,">=")),return_response_headers:o,return_response_type:function(e){return!("json"!==e||!window.JSON)||c.can("return_response_type",e)},return_status_code:o,report_upload_progress:r(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return n.can("access_binary")&&c.can("create_canvas")},select_file:function(){return c.can("use_fileinput")&&window.File},select_folder:function(){return n.can("select_file")&&"Chrome"===c.browser&&c.verComp(c.version,21,">=")},select_multiple:function(){return n.can("select_file")&&!("Safari"===c.browser&&"Windows"===c.os)&&!("iOS"===c.os&&c.verComp(c.osVersion,"7.0.0",">")&&c.verComp(c.osVersion,"8.0.0","<"))},send_binary_string:r(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:r(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||n.can("send_binary_string")},slice_blob:r(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return n.can("slice_blob")&&n.can("send_multipart")},summon_file_dialog:function(){return n.can("select_file")&&("Firefox"===c.browser&&c.verComp(c.version,4,">=")||"Opera"===c.browser&&c.verComp(c.version,12,">=")||"IE"===c.browser&&c.verComp(c.version,10,">=")||!!~s.inArray(c.browser,["Chrome","Safari"]))},upload_filesize:o},arguments[2]);u.call(this,e,arguments[1]||"html5",a),s.extend(this,{init:function(){this.trigger("Init")},destroy:(i=this.destroy,function(){i.call(n),i=n=null})}),s.extend(this.getShim(),l)}),l}),e("moxie/core/utils/Events",["moxie/core/utils/Basic"],function(a){var s={},u="moxie_"+a.guid();function c(){this.returnValue=!1}function l(){this.cancelBubble=!0}function r(t,e,i){var n;if(e=e.toLowerCase(),t[u]&&s[t[u]]&&s[t[u]][e]){for(var r=(n=s[t[u]][e]).length-1;0<=r&&(n[r].orig!==i&&n[r].key!==i||(t.removeEventListener?t.removeEventListener(e,n[r].func,!1):t.detachEvent&&t.detachEvent("on"+e,n[r].func),n[r].orig=null,n[r].func=null,n.splice(r,1),void 0===i));r--);if(n.length||delete s[t[u]][e],a.isEmptyObj(s[t[u]])){delete s[t[u]];try{delete t[u]}catch(e){t[u]=void 0}}}}return{addEvent:function(e,t,i,n){var r,o;t=t.toLowerCase(),e.addEventListener?(r=i,e.addEventListener(t,r,!1)):e.attachEvent&&(r=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=c,e.stopPropagation=l,i(e)},e.attachEvent("on"+t,r)),e[u]||(e[u]=a.guid()),s.hasOwnProperty(e[u])||(s[e[u]]={}),(o=s[e[u]]).hasOwnProperty(t)||(o[t]=[]),o[t].push({func:r,orig:i,key:n})},removeEvent:r,removeAllEvents:function(i,n){i&&i[u]&&a.each(s[i[u]],function(e,t){r(i,t,n)})}}}),e("moxie/runtime/html5/file/FileInput",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,l,d,h,m,f,p){return e.FileInput=function(){var c;d.extend(this,{init:function(e){var t,i,n,r,o,a,s=this,u=s.getRuntime();n=(c=e).accept.mimes||f.extList2mimes(c.accept,u.can("filter_by_extension")),(i=u.getShimContainer()).innerHTML='",t=h.get(u.uid),d.extend(t.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),r=h.get(c.browse_button),u.can("summon_file_dialog")&&("static"===h.getStyle(r,"position")&&(r.style.position="relative"),o=parseInt(h.getStyle(r,"z-index"),10)||1,r.style.zIndex=o,i.style.zIndex=o-1,m.addEvent(r,"click",function(e){var t=h.get(u.uid);t&&!t.disabled&&t.click(),e.preventDefault()},s.uid)),a=u.can("summon_file_dialog")?r:i,m.addEvent(a,"mouseover",function(){s.trigger("mouseenter")},s.uid),m.addEvent(a,"mouseout",function(){s.trigger("mouseleave")},s.uid),m.addEvent(a,"mousedown",function(){s.trigger("mousedown")},s.uid),m.addEvent(h.get(c.container),"mouseup",function(){s.trigger("mouseup")},s.uid),t.onchange=function e(t){if(s.files=[],d.each(this.files,function(e){var t="";if(c.directory&&"."==e.name)return!0;e.webkitRelativePath&&(t="/"+e.webkitRelativePath.replace(/^\//,"")),(e=new l(u.uid,e)).relativePath=t,s.files.push(e)}),"IE"!==p.browser&&"IEMobile"!==p.browser)this.value="";else{var i=this.cloneNode(!0);this.parentNode.replaceChild(i,this),i.onchange=e}s.files.length&&s.trigger("change")},s.trigger({type:"ready",async:!0}),i=null},disable:function(e){var t,i=this.getRuntime();(t=h.get(i.uid))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),i=e.getShimContainer();m.removeAllEvents(i,this.uid),m.removeAllEvents(c&&h.get(c.container),this.uid),m.removeAllEvents(c&&h.get(c.browse_button),this.uid),i&&(i.innerHTML=""),t.removeInstance(this.uid),c=i=t=null}})}}),e("moxie/runtime/html5/file/Blob",["moxie/runtime/html5/Runtime","moxie/file/Blob"],function(e,t){return e.Blob=function(){this.slice=function(){return new t(this.getRuntime().uid,function(t,i,n){var e;if(!window.File.prototype.slice)return(e=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?e.call(t,i,n):null;try{return t.slice(),t.slice(i,n)}catch(e){return t.slice(i,n-i)}}.apply(this,arguments))}}}),e("moxie/runtime/html5/file/FileDrop",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime"],function(e,l,d,t,h,m){return e.FileDrop=function(){var n,r,o=[],a=[];function s(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var t=d.toArray(e.dataTransfer.types||[]);return-1!==d.inArray("Files",t)||-1!==d.inArray("public.file-url",t)||-1!==d.inArray("application/x-moz-file",t)}function u(e,t){if(function(e){if(!a.length)return!0;var t=m.getFileExtension(e.name);return!t||-1!==d.inArray(t,a)}(e)){var i=new l(r,e);i.relativePath=t||"",o.push(i)}}function c(e,t){var i=[];d.each(e,function(t){i.push(function(e){!function(t,i){t.isFile?t.file(function(e){u(e,t.fullPath),i()},function(){i()}):t.isDirectory?function(e,t){var n=[],r=e.createReader();!function t(i){r.readEntries(function(e){e.length?([].push.apply(n,e),t(i)):i()},i)}(function(){c(n,t)})}(t,i):i()}(t,e)})}),d.inSeries(i,function(){t()})}d.extend(this,{init:function(e){var t,i=this;n=e,r=i.ruid,a=function(e){for(var t=[],i=0;i=")&&p.verComp(p.version,7,"<"),r="Android Browser"===p.browser,o=!1;if(u=e.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),(s=!window.XMLHttpRequest||"IE"===p.browser&&p.verComp(p.version,8,"<")?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;tthis.length())throw new Error("You are trying to read outside the source boundaries.");for(n=this.littleEndian?0:-8*(t-1),i=r=0;rthis.length())throw new Error("You are trying to write outside the source boundaries.");for(n=this.littleEndian?0:-8*(i-1),r=0;r>Math.abs(n+8*r)&255)},BYTE:function(e){return this.read(e,1)},SHORT:function(e){return this.read(e,2)},LONG:function(e){return this.read(e,4)},SLONG:function(e){var t=this.read(e,4);return 2147483647=o.length));i++);},purge:function(){this.headers=a=[]}}}}),e("moxie/runtime/html5/image/ExifParser",["moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(x,a,E){function s(e){var t,l,p,g,i,n;if(a.call(this,e),l={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"},thumb:{513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength"}},p={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},i=(g={tiffHeader:10}).tiffHeader,t={clear:this.clear},x.extend(this,{read:function(){try{return s.prototype.read.apply(this,arguments)}catch(e){throw new E.ImageError(E.ImageError.INVALID_META_ERR)}},write:function(){try{return s.prototype.write.apply(this,arguments)}catch(e){throw new E.ImageError(E.ImageError.INVALID_META_ERR)}},UNDEFINED:function(){return this.BYTE.apply(this,arguments)},RATIONAL:function(e){return this.LONG(e)/this.LONG(e+4)},SRATIONAL:function(e){return this.SLONG(e)/this.SLONG(e+4)},ASCII:function(e){return this.CHAR(e)},TIFF:function(){return n||null},EXIF:function(){var e=null;if(g.exifIFD){try{e=o.call(this,g.exifIFD,l.exif)}catch(e){return null}if(e.ExifVersion&&"array"===x.typeOf(e.ExifVersion)){for(var t=0,i="";t=this.length())throw new E.ImageError(E.ImageError.INVALID_META_ERR);"ASCII"!==o?(d=l.asArray(o,u,a),c=1==a?d[0]:d,p.hasOwnProperty(r)&&"object"!=typeof c?h[r]=p[r][c]:h[r]=c):h[r]=x.trim(l.STRING(u,a).replace(/\0$/,""))}return h}r&&(g.IFD1=g.tiffHeader+r)}return s.prototype=a.prototype,s}),e("moxie/runtime/html5/image/JPEG",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/html5/image/JPEGHeaders","moxie/runtime/html5/utils/BinaryReader","moxie/runtime/html5/image/ExifParser"],function(a,s,u,c,l){return function(e){var r,i,n,t;if(65496!==(r=new c(e)).SHORT(0))throw new s.ImageError(s.ImageError.WRONG_FORMAT);i=new u(e);try{n=new l(i.get("app1")[0])}catch(e){}function o(e){var t,i,n=0;for(e=e||r;n<=e.length();){if(65472<=(t=e.SHORT(n+=2))&&t<=65475)return n+=5,{height:e.SHORT(n),width:e.SHORT(n+=2)};i=e.SHORT(n+=2),n+=i-2}return null}t=o.call(this),a.extend(this,{type:"image/jpeg",size:r.length(),width:t&&t.width||0,height:t&&t.height||0,setExif:function(e,t){if(!n)return!1;"object"===a.typeOf(e)?a.each(e,function(e,t){n.setExif(t,e)}):n.setExif(e,t),i.set("app1",n.SEGMENT())},writeHeaders:function(){return arguments.length?i.restore(arguments[0]):i.restore(e)},stripHeaders:function(e){return i.strip(e)},purge:function(){(function(){if(!n||!i||!r)return;n.clear(),i.purge(),r.clear(),t=i=n=r=null}).call(this)}}),n&&(this.meta={tiff:n.TIFF(),exif:n.EXIF(),gps:n.GPS(),thumb:function(){var e,t,i=n.thumb();if(i&&(e=new c(i),t=o(e),e.clear(),t))return t.data=i,t;return null}()})}}),e("moxie/runtime/html5/image/PNG",["moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader"],function(n,r,a){return function(e){var o,t;function i(){o&&(o.clear(),e=t=o=null)}o=new a(e),function(){var e=0,t=0,i=[35152,20039,3338,6666];for(t=0;t>1}n=null;var c=u/i;return 0==c?1:c}(e,0,r),f=0;f=")||"IE"===s.browser&&s.verComp(s.version,10,">=")||"Safari"===s.browser&&s.verComp(s.version,7,">=")),resize_image:function(){return u.Image&&i.can("access_binary")&&s.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(e){return!("json"!==e||!window.JSON)||!!~o.inArray(e,["text","document",""])},return_status_code:function(e){return!o.arrayDiff(e,[200,404])},select_file:function(){return s.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return i.can("select_file")},summon_file_dialog:function(){return i.can("select_file")&&("Firefox"===s.browser&&s.verComp(s.version,4,">=")||"Opera"===s.browser&&s.verComp(s.version,12,">=")||"IE"===s.browser&&s.verComp(s.version,10,">=")||!!~o.inArray(s.browser,["Chrome","Safari"]))},upload_filesize:r,use_http_method:function(e){return!o.arrayDiff(e,["GET","POST"])}}),o.extend(this,{init:function(){this.trigger("Init")},destroy:(t=this.destroy,function(){t.call(i),t=i=null})}),o.extend(this.getShim(),u)}),u}),e("moxie/runtime/html4/file/FileInput",["moxie/runtime/html4/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,h,m,f,p,s,g){return e.FileInput=function(){var c,l,d=[];m.extend(this,{init:function(e){var t,i,n,r,o=this,a=o.getRuntime();d=(l=e).accept.mimes||s.extList2mimes(e.accept,a.can("filter_by_extension")),t=a.getShimContainer(),i=f.get(e.browse_button),a.can("summon_file_dialog")&&("static"===f.getStyle(i,"position")&&(i.style.position="relative"),n=parseInt(f.getStyle(i,"z-index"),10)||1,i.style.zIndex=n,t.style.zIndex=n-1),r=a.can("summon_file_dialog")?i:t,p.addEvent(r,"mouseover",function(){o.trigger("mouseenter")},o.uid),p.addEvent(r,"mouseout",function(){o.trigger("mouseleave")},o.uid),p.addEvent(r,"mousedown",function(){o.trigger("mousedown")},o.uid),p.addEvent(f.get(e.container),"mouseup",function(){o.trigger("mouseup")},o.uid),i=null,function t(){var e,i,n,r,o,a,s=this,u=s.getRuntime();a=m.guid("uid_"),e=u.getShimContainer(),c&&(n=f.get(c+"_form"))&&m.extend(n.style,{top:"100%"}),(r=document.createElement("form")).setAttribute("id",a+"_form"),r.setAttribute("method","post"),r.setAttribute("enctype","multipart/form-data"),r.setAttribute("encoding","multipart/form-data"),m.extend(r.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),(o=document.createElement("input")).setAttribute("id",a),o.setAttribute("type","file"),o.setAttribute("name",l.name||"Filedata"),o.setAttribute("accept",d.join(",")),m.extend(o.style,{fontSize:"999px",opacity:0}),r.appendChild(o),e.appendChild(r),m.extend(o.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===g.browser&&g.verComp(g.version,10,"<")&&m.extend(o.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),o.onchange=function(){var e;if(this.value){if(this.files){if(0===(e=this.files[0]).size)return void r.parentNode.removeChild(r)}else e={name:this.value};e=new h(u.uid,e),this.onchange=function(){},t.call(s),s.files=[e],o.setAttribute("id",e.uid),r.setAttribute("id",e.uid+"_form"),s.trigger("change"),o=r=null}},u.can("summon_file_dialog")&&(i=f.get(l.browse_button),p.removeEvent(i,"click",s.uid),p.addEvent(i,"click",function(e){o&&!o.disabled&&o.click(),e.preventDefault()},s.uid)),c=a,e=n=i=null}.call(this),t=null,o.trigger({type:"ready",async:!0})},disable:function(e){var t;(t=f.get(c))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),i=e.getShimContainer();p.removeAllEvents(i,this.uid),p.removeAllEvents(l&&f.get(l.container),this.uid),p.removeAllEvents(l&&f.get(l.browse_button),this.uid),i&&(i.innerHTML=""),t.removeInstance(this.uid),c=d=l=i=t=null}})}}),e("moxie/runtime/html4/file/FileReader",["moxie/runtime/html4/Runtime","moxie/runtime/html5/file/FileReader"],function(e,t){return e.FileReader=t}),e("moxie/runtime/html4/xhr/XMLHttpRequest",["moxie/runtime/html4/Runtime","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Url","moxie/core/Exceptions","moxie/core/utils/Events","moxie/file/Blob","moxie/xhr/FormData"],function(e,f,p,g,x,E,v,y){return e.XMLHttpRequest=function(){var l,d,h;function m(t){var e,i,n,r,o=this,a=!1;if(h){if(e=h.id.replace(/_iframe$/,""),i=p.get(e+"_form")){for(r=(n=i.getElementsByTagName("input")).length;r--;)switch(n[r].getAttribute("type")){case"hidden":n[r].parentNode.removeChild(n[r]);break;case"file":a=!0}n=[],a||i.parentNode.removeChild(i),i=null}setTimeout(function(){E.removeEvent(h,"load",o.uid),h.parentNode&&h.parentNode.removeChild(h);var e=o.getRuntime().getShimContainer();e.children.length||e.parentNode.removeChild(e),e=h=null,t()},1)}}f.extend(this,{send:function(t,e){var i,n,r,o,a,s,u=this,c=u.getRuntime();if(l=d=null,e instanceof y&&e.hasBlob()){if(o=e.getBlob(),i=o.uid,r=p.get(i),!(n=p.get(i+"_form")))throw new x.DOMException(x.DOMException.NOT_FOUND_ERR)}else i=f.guid("uid_"),(n=document.createElement("form")).setAttribute("id",i+"_form"),n.setAttribute("method",t.method),n.setAttribute("enctype","multipart/form-data"),n.setAttribute("encoding","multipart/form-data"),c.getShimContainer().appendChild(n);n.setAttribute("target",i+"_iframe"),e instanceof y&&e.each(function(e,t){if(e instanceof v)r&&r.setAttribute("name",t);else{var i=document.createElement("input");f.extend(i,{type:"hidden",name:t,value:e}),r?n.insertBefore(i,r):n.appendChild(i)}}),n.setAttribute("action",t.url),a=c.getShimContainer()||document.body,(s=document.createElement("div")).innerHTML='',h=s.firstChild,a.appendChild(h),E.addEvent(h,"load",function(){var e;try{e=h.contentWindow.document||h.contentDocument||window.frames[h.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(e.title)?l=e.title.replace(/^(\d+).*$/,"$1"):(l=200,d=f.trim(e.body.innerHTML),u.trigger({type:"progress",loaded:d.length,total:d.length}),o&&u.trigger({type:"uploadprogress",loaded:o.size||1025,total:o.size||1025}))}catch(e){if(!g.hasSameOrigin(t.url))return void m.call(u,function(){u.trigger("error")});l=404}m.call(u,function(){u.trigger("load")})},u.uid),n.submit(),u.trigger("loadstart")},getStatus:function(){return l},getResponse:function(e){if("json"===e&&"string"===f.typeOf(d)&&window.JSON)try{return JSON.parse(d.replace(/^\s*]*>/,"").replace(/<\/pre>\s*$/,""))}catch(e){return null}return d},abort:function(){var e=this;h&&h.contentWindow&&(h.contentWindow.stop?h.contentWindow.stop():h.contentWindow.document.execCommand?h.contentWindow.document.execCommand("Stop"):h.src="about:blank"),m.call(this,function(){e.dispatchEvent("abort")})}})}}),e("moxie/runtime/html4/image/Image",["moxie/runtime/html4/Runtime","moxie/runtime/html5/image/Image"],function(e,t){return e.Image=t}),function(e){for(var t=0;t0){c(e,function(e,t){var i=m(s(e),["array","object"])!==-1;if(e===o||n&&a[t]===o){return true}if(i&&r){e=u(e)}if(s(a[t])===s(e)&&i){l(n,r,[a[t],e])}else{a[t]=e}})}});return a}function o(t,e){for(var i in e){if({}.hasOwnProperty.call(e,i)){t[i]=e[i]}}function n(){this.constructor=t;if(MXI_DEBUG){var e=function(e){var t=e.toString().match(/^function\s([^\(\s]+)/);return t?t[1]:false};this.ctorName=e(t)}}n.prototype=e.prototype;t.prototype=new n;t.parent=e.prototype;return t}function c(e,t){var i,n,r,o;if(e){try{i=e.length}catch(e){i=o}if(i===o||typeof i!=="number"){for(n in e){if(e.hasOwnProperty(n)){if(t(e[n],n)===false){return}}}}else{for(r=0;r>16&255;r=c>>8&255;o=c&255;if(u==64){h[d++]=String.fromCharCode(n)}else if(l==64){h[d++]=String.fromCharCode(n,r)}else{h[d++]=String.fromCharCode(n,r,o)}}while(f>18&63;s=c>>12&63;u=c>>6&63;l=c&63;h[d++]=i.charAt(a)+i.charAt(s)+i.charAt(u)+i.charAt(l)}while(f0){if(o.length==2){if(typeof o[1]==d){e[o[0]]=o[1].call(this,s)}else{e[o[0]]=o[1]}}else if(o.length==3){if(typeof o[1]===d&&!(o[1].exec&&o[1].test)){e[o[0]]=s?o[1].call(this,s,o[2]):f}else{e[o[0]]=s?s.replace(o[1],o[2]):f}}else if(o.length==4){e[o[0]]=s?o[3].call(this,s.replace(o[1],o[2])):f}}else{e[o]=s?s:f}}break}}if(!!a)break}return e},str:function(e,t){for(var i in t){if(typeof t[i]===h&&t[i].length>0){for(var n=0;nt[n]){o=1;break}}if(!i){return o}switch(i){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return o<=0;case"==":case"=":case"eq":return o===0;case"<>":case"!=":case"ne":return o!==0;case"":case"<":case"lt":return o<0;default:return null}}var i=function(){var n={access_global_ns:function(){return!!window.moxie},define_property:function(){return false}(),create_canvas:function(){var e=document.createElement("canvas");var t=!!(e.getContext&&e.getContext("2d"));n.create_canvas=t;return t},return_response_type:function(e){try{if(r.inArray(e,["","text","document"])!==-1){return true}else if(window.XMLHttpRequest){var t=new XMLHttpRequest;t.open("get","/");if("responseType"in t){t.responseType=e;if(t.responseType!==e){return false}return true}}}catch(e){}return false},use_blob_uri:function(){var e=window.URL;n.use_blob_uri=e&&"createObjectURL"in e&&"revokeObjectURL"in e&&(o.browser!=="IE"||o.verComp(o.version,"11.0.46",">="));return n.use_blob_uri},use_data_uri:function(){var e=new Image;e.onload=function(){n.use_data_uri=e.width===1&&e.height===1};setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1);return false}(),use_data_uri_over32kb:function(){return n.use_data_uri&&(o.browser!=="IE"||o.version>=9)},use_data_uri_of:function(e){return n.use_data_uri&&e<33e3||n.use_data_uri_over32kb()},use_fileinput:function(){if(navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)){return false}var e=document.createElement("input");e.setAttribute("type","file");return n.use_fileinput=!e.disabled},use_webgl:function(){var e=document.createElement("canvas");var t=null,i;try{t=e.getContext("webgl")||e.getContext("experimental-webgl")}catch(e){}if(!t){t=null}i=!!t;n.use_webgl=i;e=w;return i}};return function(e){var t=[].slice.call(arguments);t.shift();return r.typeOf(n[e])==="function"?n[e].apply(this,t):!!n[e]}}();var n=(new e).getResult();var o={can:i,uaParser:e,browser:n.browser.name,version:n.browser.version,os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};o.OS=o.os;if(MXI_DEBUG){o.debug={runtime:true,events:false};o.log=function(){function e(e){t.appendChild(document.createTextNode(e+"\n"))}if(window&&window.console&&window.console.log&&window.console.log.apply){window.console.log.apply(window.console,arguments)}else if(document){var t=document.getElementById("moxie-console");if(!t){t=document.createElement("pre");t.id="moxie-console";document.body.appendChild(t)}var i=arguments[0];if(r.typeOf(i)==="string"){i=r.sprintf.apply(this,arguments)}else if(r.inArray(r.typeOf(i),["object","array"])!==-1){e(i);return}t.appendChild(document.createTextNode(i+"\n"))}}}return o});e("moxie/core/Exceptions",["moxie/core/utils/Basic"],function(n){function r(e,t){var i;for(i in e){if(e[i]===t){return i}}return null}return{RuntimeError:function(){var i={NOT_INIT_ERR:1,EXCEPTION_ERR:3,NOT_SUPPORTED_ERR:9,JS_ERR:4};function e(e,t){this.code=e;this.name=r(i,e);this.message=this.name+(t||": RuntimeError "+this.code)}n.extend(e,i);e.prototype=Error.prototype;return e}(),OperationNotAllowedException:function(){function e(e){this.code=e;this.name="OperationNotAllowedException"}n.extend(e,{NOT_ALLOWED_ERR:1});e.prototype=Error.prototype;return e}(),ImageError:function(){var t={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2,INVALID_META_ERR:3};function e(e){this.code=e;this.name=r(t,e);this.message=this.name+": ImageError "+this.code}n.extend(e,t);e.prototype=Error.prototype;return e}(),FileException:function(){var t={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};function e(e){this.code=e;this.name=r(t,e);this.message=this.name+": FileException "+this.code}n.extend(e,t);e.prototype=Error.prototype;return e}(),DOMException:function(){var t={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};function e(e){this.code=e;this.name=r(t,e);this.message=this.name+": DOMException "+this.code}n.extend(e,t);e.prototype=Error.prototype;return e}(),EventException:function(){function e(e){this.code=e;this.name="EventException"}n.extend(e,{UNSPECIFIED_EVENT_TYPE_ERR:0});e.prototype=Error.prototype;return e}()}});e("moxie/core/utils/Dom",["moxie/core/utils/Env"],function(l){var e=function(e){if(typeof e!=="string"){return e}return document.getElementById(e)};var i=function(e,t){if(!e.className){return false}var i=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return i.test(e.className)};var t=function(e,t){if(!i(e,t)){e.className=!e.className?t:e.className.replace(/\s+$/,"")+" "+t}};var n=function(e,t){if(e.className){var i=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(i,function(e,t,i){return t===" "&&i===" "?" ":""})}};var r=function(e,t){if(e.currentStyle){return e.currentStyle[t]}else if(window.getComputedStyle){return window.getComputedStyle(e,null)[t]}};var o=function(e,t){var i=0,n=0,r,o=document,a,s;e=e;t=t||o.body;function u(e){var t,i,n=0,r=0;if(e){i=e.getBoundingClientRect();t=o.compatMode==="CSS1Compat"?o.documentElement:o.body;n=i.left+t.scrollLeft;r=i.top+t.scrollTop}return{x:n,y:r}}if(e&&e.getBoundingClientRect&&l.browser==="IE"&&(!o.documentMode||o.documentMode<8)){a=u(e);s=u(t);return{x:a.x-s.x,y:a.y-s.y}}r=e;while(r&&r!=t&&r.nodeType){i+=r.offsetLeft||0;n+=r.offsetTop||0;r=r.offsetParent}r=e.parentNode;while(r&&r!=t&&r.nodeType){i-=r.scrollLeft||0;n-=r.scrollTop||0;r=r.parentNode}return{x:i,y:n}};var a=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:e,hasClass:i,addClass:t,removeClass:n,getStyle:r,getPos:o,getSize:a}});e("moxie/core/EventTarget",["moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Basic"],function(l,c,f){var d={};function e(){this.uid=f.guid()}f.extend(e.prototype,{init:function(){if(!this.uid){this.uid=f.guid("uid_")}},addEventListener:function(e,t,i,n){var r=this,o;if(!this.hasOwnProperty("uid")){this.uid=f.guid("uid_")}e=f.trim(e);if(/\s/.test(e)){f.each(e.split(/\s+/),function(e){r.addEventListener(e,t,i,n)});return}e=e.toLowerCase();i=parseInt(i,10)||0;o=d[this.uid]&&d[this.uid][e]||[];o.push({fn:t,priority:i,scope:n||this});if(!d[this.uid]){d[this.uid]={}}d[this.uid][e]=o},hasEventListener:function(e){var t;if(e){e=e.toLowerCase();t=d[this.uid]&&d[this.uid][e]}else{t=d[this.uid]}return t?t:false},removeEventListener:function(e,t){var i=this,n,r;e=e.toLowerCase();if(/\s/.test(e)){f.each(e.split(/\s+/),function(e){i.removeEventListener(e,t)});return}n=d[this.uid]&&d[this.uid][e];if(n){if(t){for(r=n.length-1;r>=0;r--){if(n[r].fn===t){n.splice(r,1);break}}}else{n=[]}if(!n.length){delete d[this.uid][e];if(f.isEmptyObj(d[this.uid])){delete d[this.uid]}}}},removeAllEventListeners:function(){if(d[this.uid]){delete d[this.uid]}},dispatchEvent:function(t){var i,e,n,r,o={},a=true,s;if(f.typeOf(t)!=="string"){r=t;if(f.typeOf(r.type)==="string"){t=r.type;if(r.total!==s&&r.loaded!==s){o.total=r.total;o.loaded=r.loaded}o.async=r.async||false}else{throw new c.EventException(c.EventException.UNSPECIFIED_EVENT_TYPE_ERR)}}if(t.indexOf("::")!==-1){(function(e){i=e[0];t=e[1]})(t.split("::"))}else{i=this.uid}t=t.toLowerCase();e=d[i]&&d[i][t];if(e){e.sort(function(e,t){return t.priority-e.priority});n=[].slice.call(arguments);n.shift();o.type=t;n.unshift(o);if(MXI_DEBUG&&l.debug.events){l.log("%cEvent '%s' fired on %s","color: #999;",o.type,(this.ctorName?this.ctorName+"::":"")+i)}var u=[];f.each(e,function(t){n[0].target=t.scope;if(o.async){u.push(function(e){setTimeout(function(){e(t.fn.apply(t.scope,n)===false)},1)})}else{u.push(function(e){e(t.fn.apply(t.scope,n)===false)})}});if(u.length){f.inSeries(u,function(e){a=!e})}}return a},bindOnce:function(t,i,e,n){var r=this;r.bind.call(this,t,function e(){r.unbind(t,e);return i.apply(this,arguments)},e,n)},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},handleEventProps:function(e){var t=this;this.bind(e.join(" "),function(e){var t="on"+e.type.toLowerCase();if(f.typeOf(this[t])==="function"){this[t].apply(this,arguments)}});f.each(e,function(e){e="on"+e.toLowerCase(e);if(f.typeOf(t[e])==="undefined"){t[e]=null}})}});e.instance=new e;return e});e("moxie/runtime/Runtime",["moxie/core/utils/Env","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/EventTarget"],function(l,c,f,i){var n={},d={};function m(e,t,r,i,n){var o=this,a,s=c.guid(t+"_"),u=n||"browser";e=e||{};d[s]=this;r=c.extend({access_binary:false,access_image_binary:false,display_media:false,do_cors:false,drag_and_drop:false,filter_by_extension:true,resize_image:false,report_upload_progress:false,return_response_headers:false,return_response_type:false,return_status_code:true,send_custom_headers:false,select_file:false,select_folder:false,select_multiple:true,send_binary_string:false,send_browser_cookies:true,send_multipart:true,slice_blob:false,stream_upload:false,summon_file_dialog:false,upload_filesize:true,use_http_method:true},r);if(e.preferred_caps){u=m.getMode(i,e.preferred_caps,u)}if(MXI_DEBUG&&l.debug.runtime){l.log("\tdefault mode: %s",u)}a=function(){var r={};return{exec:function(e,t,i,n){if(a[t]){if(!r[e]){r[e]={context:this,instance:new a[t]}}if(r[e].instance[i]){return r[e].instance[i].apply(this,n)}}},removeInstance:function(e){delete r[e]},removeAllInstances:function(){var i=this;c.each(r,function(e,t){if(c.typeOf(e.instance.destroy)==="function"){e.instance.destroy.call(e.context)}i.removeInstance(t)})}}}();c.extend(this,{initialized:false,uid:s,type:t,mode:m.getMode(i,e.required_caps,u),shimid:s+"_container",clients:0,options:e,can:function(e,t){var i=arguments[2]||r;if(c.typeOf(e)==="string"&&c.typeOf(t)==="undefined"){e=m.parseCaps(e)}if(c.typeOf(e)==="object"){for(var n in e){if(!this.can(n,e[n],i)){return false}}return true}if(c.typeOf(i[e])==="function"){return i[e].call(this,t)}else{return t===i[e]}},getShimContainer:function(){var e,t=f.get(this.shimid);if(!t){e=f.get(this.options.container)||document.body;t=document.createElement("div");t.id=this.shimid;t.className="moxie-shim moxie-shim-"+this.type;c.extend(t.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"});e.appendChild(t);e=null}return t},getShim:function(){return a},shimExec:function(e,t){var i=[].slice.call(arguments,2);return o.getShim().exec.call(this,this.uid,e,t,i)},exec:function(e,t){var i=[].slice.call(arguments,2);if(o[e]&&o[e][t]){return o[e][t].apply(this,i)}return o.shimExec.apply(this,arguments)},destroy:function(){if(!o){return}var e=f.get(this.shimid);if(e){e.parentNode.removeChild(e)}if(a){a.removeAllInstances()}this.unbindAll();delete d[this.uid];this.uid=null;s=o=a=e=null}});if(this.mode&&e.required_caps&&!this.can(e.required_caps)){this.mode=false}}m.order="html5,flash,silverlight,html4";m.getRuntime=function(e){return d[e]?d[e]:false};m.addConstructor=function(e,t){t.prototype=i.instance;n[e]=t};m.getConstructor=function(e){return n[e]||null};m.getInfo=function(e){var t=m.getRuntime(e);if(t){return{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}}return null};m.parseCaps=function(e){var t={};if(c.typeOf(e)!=="string"){return e||{}}c.each(e.split(","),function(e){t[e]=true});return t};m.can=function(e,t){var i,n=m.getConstructor(e),r;if(n){i=new n({required_caps:t});r=i.mode;i.destroy();return!!r}return false};m.thatCan=function(e,t){var i=(t||m.order).split(/\s*,\s*/);for(var n in i){if(m.can(i[n],e)){return i[n]}}return null};m.getMode=function(n,e,t){var r=null;if(c.typeOf(t)==="undefined"){t="browser"}if(e&&!c.isEmptyObj(n)){c.each(e,function(e,t){if(n.hasOwnProperty(t)){var i=n[t](e);if(typeof i==="string"){i=[i]}if(!r){r=i}else if(!(r=c.arrayIntersect(r,i))){if(MXI_DEBUG&&l.debug.runtime){l.log("\t\t%s: %s (conflicting mode requested: %s)",t,e,i)}return r=false}}if(MXI_DEBUG&&l.debug.runtime){l.log("\t\t%s: %s (compatible modes: %s)",t,e,r)}});if(r){return c.inArray(t,r)!==-1?t:r[0]}else if(r===false){return false}}return t};m.getGlobalEventTarget=function(){if(/^moxie\./.test(l.global_event_dispatcher)&&!l.can("access_global_ns")){var e=c.guid("moxie_event_target_");window[e]=function(e,t){i.instance.dispatchEvent(e,t)};l.global_event_dispatcher=e}return l.global_event_dispatcher};m.capTrue=function(){return true};m.capFalse=function(){return false};m.capTest=function(e){return function(){return!!e}};return m});e("moxie/runtime/RuntimeClient",["moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/Runtime"],function(s,u,t,l){return function e(){var a;t.extend(this,{connectRuntime:function(n){var r=this,e;function o(e){var t,i;if(!e.length){r.trigger("RuntimeError",new u.RuntimeError(u.RuntimeError.NOT_INIT_ERR));a=null;return}t=e.shift().toLowerCase();i=l.getConstructor(t);if(!i){if(MXI_DEBUG&&s.debug.runtime){s.log("Constructor for '%s' runtime is not available.",t)}o(e);return}if(MXI_DEBUG&&s.debug.runtime){s.log("Trying runtime: %s",t);s.log(n)}a=new i(n);a.bind("Init",function(){a.initialized=true;if(MXI_DEBUG&&s.debug.runtime){s.log("Runtime '%s' initialized",a.type)}setTimeout(function(){a.clients++;r.ruid=a.uid;r.trigger("RuntimeInit",a)},1)});a.bind("Error",function(){if(MXI_DEBUG&&s.debug.runtime){s.log("Runtime '%s' failed to initialize",a.type)}a.destroy();o(e)});a.bind("Exception",function(e,t){var i=t.name+"(#"+t.code+")"+(t.message?", from: "+t.message:"");if(MXI_DEBUG&&s.debug.runtime){s.log("Runtime '%s' has thrown an exception: %s",this.type,i)}r.trigger("RuntimeError",new u.RuntimeError(u.RuntimeError.EXCEPTION_ERR,i))});if(MXI_DEBUG&&s.debug.runtime){s.log("\tselected mode: %s",a.mode)}if(!a.mode){a.trigger("Error");return}a.init()}if(t.typeOf(n)==="string"){e=n}else if(t.typeOf(n.ruid)==="string"){e=n.ruid}if(e){a=l.getRuntime(e);if(a){r.ruid=e;a.clients++;return a}else{throw new u.RuntimeError(u.RuntimeError.NOT_INIT_ERR)}}o((n.runtime_order||l.order).split(/\s*,\s*/))},disconnectRuntime:function(){if(a&&--a.clients<=0){a.destroy()}a=null},getRuntime:function(){if(a&&a.uid){return a}return a=null},exec:function(){return a?a.exec.apply(this,arguments):null},can:function(e){return a?a.can(e):false}})}});e("moxie/file/Blob",["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/runtime/RuntimeClient"],function(o,i,r){var a={};function s(e,t){function n(e,t,i){var n,r=a[this.uid];if(o.typeOf(r)!=="string"||!r.length){return null}n=new s(null,{type:i,size:t-e});n.detach(r.substr(e,n.size));return n}r.call(this);if(e){this.connectRuntime(e)}if(!t){t={}}else if(o.typeOf(t)==="string"){t={data:t}}o.extend(this,{uid:t.uid||o.guid("uid_"),ruid:e,size:t.size||0,type:t.type||"",slice:function(e,t,i){if(this.isDetached()){return n.apply(this,arguments)}return this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,i)},getSource:function(){if(!a[this.uid]){return null}return a[this.uid]},detach:function(e){if(this.ruid){this.getRuntime().exec.call(this,"Blob","destroy");this.disconnectRuntime();this.ruid=null}e=e||"";if(e.substr(0,5)=="data:"){var t=e.indexOf(";base64,");this.type=e.substring(5,t);e=i.atob(e.substring(t+8))}this.size=e.length;a[this.uid]=e},isDetached:function(){return!this.ruid&&o.typeOf(a[this.uid])==="string"},destroy:function(){this.detach();delete a[this.uid]}});if(t.data){this.detach(t.data)}else{a[this.uid]=t}}return s});e("moxie/core/I18n",["moxie/core/utils/Basic"],function(i){var t={};return{addI18n:function(e){return i.extend(t,e)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(e){var t=[].slice.call(arguments,1);return e.replace(/%[a-z]/g,function(){var e=t.shift();return i.typeOf(e)!=="undefined"?e:""})}}});e("moxie/core/utils/Mime",["moxie/core/utils/Basic","moxie/core/I18n"],function(s,n){var e=""+"application/msword,doc dot,"+"application/pdf,pdf,"+"application/pgp-signature,pgp,"+"application/postscript,ps ai eps,"+"application/rtf,rtf,"+"application/vnd.ms-excel,xls xlb xlt xla,"+"application/vnd.ms-powerpoint,ppt pps pot ppa,"+"application/zip,zip,"+"application/x-shockwave-flash,swf swfl,"+"application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,"+"application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,"+"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,"+"application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,"+"application/vnd.openxmlformats-officedocument.presentationml.template,potx,"+"application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,"+"application/x-javascript,js,"+"application/json,json,"+"audio/mpeg,mp3 mpga mpega mp2,"+"audio/x-wav,wav,"+"audio/x-m4a,m4a,"+"audio/ogg,oga ogg,"+"audio/aiff,aiff aif,"+"audio/flac,flac,"+"audio/aac,aac,"+"audio/ac3,ac3,"+"audio/x-ms-wma,wma,"+"image/bmp,bmp,"+"image/gif,gif,"+"image/jpeg,jpg jpeg jpe,"+"image/photoshop,psd,"+"image/png,png,"+"image/svg+xml,svg svgz,"+"image/tiff,tiff tif,"+"text/plain,asc txt text diff log,"+"text/html,htm html xhtml,"+"text/css,css,"+"text/csv,csv,"+"text/rtf,rtf,"+"video/mpeg,mpeg mpg mpe m2v,"+"video/quicktime,qt mov,"+"video/mp4,mp4,"+"video/x-m4v,m4v,"+"video/x-flv,flv,"+"video/x-ms-wmv,wmv,"+"video/avi,avi,"+"video/webm,webm,"+"video/3gpp,3gpp 3gp,"+"video/3gpp2,3g2,"+"video/vnd.rn-realvideo,rv,"+"video/ogg,ogv,"+"video/x-matroska,mkv,"+"application/vnd.oasis.opendocument.formula-template,otf,"+"application/octet-stream,exe";var o={};var a={};var t=function(e){var t=e.split(/,/),i,n,r;for(i=0;i0){if(p){i.upload.dispatchEvent(e)}i.dispatchEvent(e)}else{v=true;i.dispatchEvent("error")}n()});E.bind("Abort",function(e){i.dispatchEvent(e);n()});E.bind("Error",function(e){v=true;R("readyState",k.DONE);i.dispatchEvent("readystatechange");g=true;i.dispatchEvent(e);n()});t.exec.call(E,"XMLHttpRequest","send",{url:s,method:u,async:a,user:c,password:f,headers:l,mimeType:d,encoding:o,responseType:i.responseType,withCredentials:i.withCredentials,options:y},e)}if(typeof y.required_caps==="string"){y.required_caps=N.parseCaps(y.required_caps)}y.required_caps=T.extend({},y.required_caps,{return_response_type:i.responseType});if(e instanceof M){y.required_caps.send_multipart=true}if(!T.isEmptyObj(l)){y.required_caps.send_custom_headers=true}if(!x){y.required_caps.do_cors=true}if(y.ruid){r(E.connectRuntime(y))}else{E.bind("RuntimeInit",function(e,t){r(t)});E.bind("RuntimeError",function(e,t){i.dispatchEvent("RuntimeError",t)});E.connectRuntime(y)}}function A(){R("responseText","");R("responseXML",null);R("response",null);R("status",0);R("statusText","");t=e=null}}k.UNSENT=0;k.OPENED=1;k.HEADERS_RECEIVED=2;k.LOADING=3;k.DONE=4;k.prototype=e.instance;return k});e("moxie/runtime/Transporter",["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/runtime/RuntimeClient","moxie/core/EventTarget"],function(d,m,e,t){function h(){var o,n,a,s,r,u;e.call(this);d.extend(this,{uid:d.guid("uid_"),state:h.IDLE,result:null,transport:function(e,i,t){var n=this;t=d.extend({chunk_size:204798},t);if(o=t.chunk_size%3){t.chunk_size+=3-o}u=t.chunk_size;l.call(this);a=e;s=e.length;if(d.typeOf(t)==="string"||t.ruid){c.call(n,i,this.connectRuntime(t))}else{var r=function(e,t){n.unbind("RuntimeInit",r);c.call(n,i,t)};this.bind("RuntimeInit",r);this.connectRuntime(t)}},abort:function(){var e=this;e.state=h.IDLE;if(n){n.exec.call(e,"Transporter","clear");e.trigger("TransportingAborted")}l.call(e)},destroy:function(){this.unbindAll();n=null;this.disconnectRuntime();l.call(this)}});function l(){s=r=0;a=this.result=null}function c(e,t){var i=this;n=t;i.bind("TransportingProgress",function(e){r=e.loaded;if(ri){u=i}t=m.btoa(a.substr(r,u));n.exec.call(e,"Transporter","receive",t,s)}}h.IDLE=0;h.BUSY=1;h.DONE=2;h.prototype=t.instance;return h});e("moxie/image/Image",["moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/file/FileReaderSync","moxie/xhr/XMLHttpRequest","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/runtime/Transporter","moxie/core/utils/Env","moxie/core/EventTarget","moxie/file/Blob","moxie/file/File","moxie/core/utils/Encode"],function(l,c,f,e,a,s,t,d,m,i,u,h,p){var g=["progress","load","error","resize","embedded"];function v(){t.call(this);l.extend(this,{uid:l.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){i.apply(this,arguments)},resize:function(e){var t=this;var i;var n;var r={x:0,y:0,width:t.width,height:t.height};var o=l.extendIf({width:t.width,height:t.height,type:t.type||"image/jpeg",quality:90,crop:false,fit:true,preserveHeaders:true,resample:"default",multipass:true},e);try{if(!t.size){throw new f.DOMException(f.DOMException.INVALID_STATE_ERR)}if(t.width>v.MAX_RESIZE_WIDTH||t.height>v.MAX_RESIZE_HEIGHT){throw new f.ImageError(f.ImageError.MAX_RESOLUTION_ERR)}i=t.meta&&t.meta.tiff&&t.meta.tiff.Orientation||1;if(l.inArray(i,[5,6,7,8])!==-1){var a=o.width;o.width=o.height;o.height=a}if(o.crop){n=Math.max(o.width/t.width,o.height/t.height);if(e.fit){r.width=Math.min(Math.ceil(o.width/n),t.width);r.height=Math.min(Math.ceil(o.height/n),t.height);n=o.width/r.width}else{r.width=Math.min(o.width,t.width);r.height=Math.min(o.height,t.height);n=1}if(typeof o.crop==="boolean"){o.crop="cc"}switch(o.crop.toLowerCase().replace(/_/,"-")){case"rb":case"right-bottom":r.x=t.width-r.width;r.y=t.height-r.height;break;case"cb":case"center-bottom":r.x=Math.floor((t.width-r.width)/2);r.y=t.height-r.height;break;case"lb":case"left-bottom":r.x=0;r.y=t.height-r.height;break;case"lt":case"left-top":r.x=0;r.y=0;break;case"ct":case"center-top":r.x=Math.floor((t.width-r.width)/2);r.y=0;break;case"rt":case"right-top":r.x=t.width-r.width;r.y=0;break;case"rc":case"right-center":case"right-middle":r.x=t.width-r.width;r.y=Math.floor((t.height-r.height)/2);break;case"lc":case"left-center":case"left-middle":r.x=0;r.y=Math.floor((t.height-r.height)/2);break;case"cc":case"center-center":case"center-middle":default:r.x=Math.floor((t.width-r.width)/2);r.y=Math.floor((t.height-r.height)/2)}r.x=Math.max(r.x,0);r.y=Math.max(r.y,0)}else{n=Math.min(o.width/t.width,o.height/t.height);if(n>1&&!o.fit){n=1}}this.exec("Image","resize",r,n,o)}catch(e){t.trigger("error",e.code)}},downsize:function(e){var t={width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90,crop:false,fit:false,preserveHeaders:true,resample:"default"},i;if(typeof e==="object"){i=l.extend(t,e)}else{i=l.extend(t,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]})}this.resize(i)},crop:function(e,t,i){this.downsize(e,t,true,i)},getAsCanvas:function(){if(!m.can("create_canvas")){throw new f.RuntimeError(f.RuntimeError.NOT_SUPPORTED_ERR)}return this.exec("Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size){throw new f.DOMException(f.DOMException.INVALID_STATE_ERR)}return this.exec("Image","getAsBlob",e||"image/jpeg",t||90)},getAsDataURL:function(e,t){if(!this.size){throw new f.DOMException(f.DOMException.INVALID_STATE_ERR)}return this.exec("Image","getAsDataURL",e||"image/jpeg",t||90)},getAsBinaryString:function(e,t){var i=this.getAsDataURL(e,t);return p.atob(i.substring(i.indexOf("base64,")+7))},embed:function(a,e){var s=this,u;var t=l.extend({width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90,fit:true,resample:"nearest"},e);function i(e,t){var i=this;if(m.can("create_canvas")){var n=i.getAsCanvas();if(n){a.appendChild(n);n=null;i.destroy();s.trigger("embedded");return}}var r=i.getAsDataURL(e,t);if(!r){throw new f.ImageError(f.ImageError.WRONG_FORMAT)}if(m.can("use_data_uri_of",r.length)){a.innerHTML='';i.destroy();s.trigger("embedded")}else{var o=new d;o.bind("TransportingComplete",function(){u=s.connectRuntime(this.result.ruid);s.bind("Embedded",function(){l.extend(u.getShimContainer().style,{top:"0px",left:"0px",width:i.width+"px",height:i.height+"px"});u=null},999);u.exec.call(s,"ImageView","display",this.result.uid,width,height);i.destroy()});o.transport(p.atob(r.substring(r.indexOf("base64,")+7)),e,{required_caps:{display_media:true},runtime_order:"flash,silverlight",container:a})}}try{if(!(a=c.get(a))){throw new f.DOMException(f.DOMException.INVALID_NODE_TYPE_ERR)}if(!this.size){throw new f.DOMException(f.DOMException.INVALID_STATE_ERR)}if(this.width>v.MAX_RESIZE_WIDTH||this.height>v.MAX_RESIZE_HEIGHT){}var n=new v;n.bind("Resize",function(){i.call(this,t.type,t.quality)});n.bind("Load",function(){this.downsize(t)});if(this.meta.thumb&&this.meta.thumb.width>=t.width&&this.meta.thumb.height>=t.height){n.load(this.meta.thumb.data)}else{n.clone(this,false)}return n}catch(e){this.trigger("error",e.code)}},destroy:function(){if(this.ruid){this.getRuntime().exec.call(this,"Image","destroy");this.disconnectRuntime()}if(this.meta&&this.meta.thumb){this.meta.thumb.data.destroy()}this.unbindAll()}});this.handleEventProps(g);this.bind("Load Resize",function(){return e.call(this)},999);function e(e){try{if(!e){e=this.exec("Image","getInfo")}this.size=e.size;this.width=e.width;this.height=e.height;this.type=e.type;this.meta=e.meta;if(this.name===""){this.name=e.name}return true}catch(e){this.trigger("error",e.code);return false}}function i(e){var t=l.typeOf(e);try{if(e instanceof v){if(!e.size){throw new f.DOMException(f.DOMException.INVALID_STATE_ERR)}n.apply(this,arguments)}else if(e instanceof u){if(!~l.inArray(e.type,["image/jpeg","image/png"])){throw new f.ImageError(f.ImageError.WRONG_FORMAT)}r.apply(this,arguments)}else if(l.inArray(t,["blob","file"])!==-1){i.call(this,new h(null,e),arguments[1])}else if(t==="string"){if(e.substr(0,5)==="data:"){i.call(this,new u(null,{data:e}),arguments[1])}else{o.apply(this,arguments)}}else if(t==="node"&&e.nodeName.toLowerCase()==="img"){i.call(this,e.src,arguments[1])}else{throw new f.DOMException(f.DOMException.TYPE_MISMATCH_ERR)}}catch(e){this.trigger("error",e.code)}}function n(e,t){var i=this.connectRuntime(e.ruid);this.ruid=i.uid;i.exec.call(this,"Image","loadFromImage",e,l.typeOf(t)==="undefined"?true:t)}function r(t,e){var i=this;i.name=t.name||"";function n(e){i.ruid=e.uid;e.exec.call(i,"Image","loadFromBlob",t)}if(t.isDetached()){this.bind("RuntimeInit",function(e,t){n(t)});if(e&&typeof e.required_caps==="string"){e.required_caps=s.parseCaps(e.required_caps)}this.connectRuntime(l.extend({required_caps:{access_image_binary:true,resize_image:true}},e))}else{n(this.connectRuntime(t.ruid))}}function o(e,t){var i=this,n;n=new a;n.open("get",e);n.responseType="blob";n.onprogress=function(e){i.trigger(e)};n.onload=function(){r.call(i,n.response,true)};n.onerror=function(e){i.trigger(e)};n.onloadend=function(){n.destroy()};n.bind("RuntimeError",function(e,t){i.trigger("RuntimeError",t)});n.send(null,t)}}v.MAX_RESIZE_WIDTH=8192;v.MAX_RESIZE_HEIGHT=8192;v.prototype=i.instance;return v});e("moxie/runtime/html5/Runtime",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/Runtime","moxie/core/utils/Env"],function(o,e,a,s){var u="html5",l={};function t(e){var t=this,i=a.capTest,n=a.capTrue;var r=o.extend({access_binary:i(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return t.can("access_binary")&&!!l.Image},display_media:i((s.can("create_canvas")||s.can("use_data_uri_over32kb"))&&d("moxie/image/Image")),do_cors:i(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:i(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&(s.browser!=="IE"||s.verComp(s.version,9,">"))}()),filter_by_extension:i(function(){return!(s.browser==="Chrome"&&s.verComp(s.version,28,"<")||s.browser==="IE"&&s.verComp(s.version,10,"<")||s.browser==="Safari"&&s.verComp(s.version,7,"<")||s.browser==="Firefox"&&s.verComp(s.version,37,"<"))}()),return_response_headers:n,return_response_type:function(e){if(e==="json"&&!!window.JSON){return true}return s.can("return_response_type",e)},return_status_code:n,report_upload_progress:i(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return t.can("access_binary")&&s.can("create_canvas")},select_file:function(){return s.can("use_fileinput")&&window.File},select_folder:function(){return t.can("select_file")&&(s.browser==="Chrome"&&s.verComp(s.version,21,">=")||s.browser==="Firefox"&&s.verComp(s.version,42,">="))},select_multiple:function(){return t.can("select_file")&&!(s.browser==="Safari"&&s.os==="Windows")&&!(s.os==="iOS"&&s.verComp(s.osVersion,"7.0.0",">")&&s.verComp(s.osVersion,"8.0.0","<"))},send_binary_string:i(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:i(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||t.can("send_binary_string")},slice_blob:i(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return t.can("slice_blob")&&t.can("send_multipart")},summon_file_dialog:function(){return t.can("select_file")&&!(s.browser==="Firefox"&&s.verComp(s.version,4,"<")||s.browser==="Opera"&&s.verComp(s.version,12,"<")||s.browser==="IE"&&s.verComp(s.version,10,"<"))},upload_filesize:n,use_http_method:n},arguments[2]);a.call(this,e,arguments[1]||u,r);o.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(t);e=t=null}}(this.destroy)});o.extend(this.getShim(),l)}a.addConstructor(u,t);return l});e("moxie/runtime/html5/file/Blob",["moxie/runtime/html5/Runtime","moxie/file/Blob"],function(e,t){function i(){function e(t,i,n){var e;if(window.File.prototype.slice){try{t.slice();return t.slice(i,n)}catch(e){return t.slice(i,n-i)}}else if(e=window.File.prototype.webkitSlice||window.File.prototype.mozSlice){return e.call(t,i,n)}else{return null}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))};this.destroy=function(){this.getRuntime().getShim().removeInstance(this.uid)}}return e.Blob=i});e("moxie/core/utils/Events",["moxie/core/utils/Basic"],function(a){var s={},u="moxie_"+a.guid();function l(){this.returnValue=false}function c(){this.cancelBubble=true}var e=function(e,t,i,n){var r,o;t=t.toLowerCase();if(e.addEventListener){r=i;e.addEventListener(t,r,false)}else if(e.attachEvent){r=function(){var e=window.event;if(!e.target){e.target=e.srcElement}e.preventDefault=l;e.stopPropagation=c;i(e)};e.attachEvent("on"+t,r)}if(!e[u]){e[u]=a.guid()}if(!s.hasOwnProperty(e[u])){s[e[u]]={}}o=s[e[u]];if(!o.hasOwnProperty(t)){o[t]=[]}o[t].push({func:r,orig:i,key:n})};var r=function(t,e,i){var n,r;e=e.toLowerCase();if(t[u]&&s[t[u]]&&s[t[u]][e]){n=s[t[u]][e]}else{return}for(var o=n.length-1;o>=0;o--){if(n[o].orig===i||n[o].key===i){if(t.removeEventListener){t.removeEventListener(e,n[o].func,false)}else if(t.detachEvent){t.detachEvent("on"+e,n[o].func)}n[o].orig=null;n[o].func=null;n.splice(o,1);if(i!==r){break}}}if(!n.length){delete s[t[u]][e]}if(a.isEmptyObj(s[t[u]])){delete s[t[u]];try{delete t[u]}catch(e){t[u]=r}}};var t=function(i,n){if(!i||!i[u]){return}a.each(s[i[u]],function(e,t){r(i,t,n)})};return{addEvent:e,removeEvent:r,removeAllEvents:t}});e("moxie/runtime/html5/file/FileInput",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,f,d,m,h,p,g){function t(){var l,c;d.extend(this,{init:function(e){var i=this,n=i.getRuntime(),t,r,o,a,s,u;l=e;o=p.extList2mimes(l.accept,n.can("filter_by_extension"));r=n.getShimContainer();r.innerHTML='";t=m.get(n.uid);d.extend(t.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"});a=m.get(l.browse_button);c=m.getStyle(a,"z-index")||"auto";if(n.can("summon_file_dialog")){if(m.getStyle(a,"position")==="static"){a.style.position="relative"}h.addEvent(a,"click",function(e){var t=m.get(n.uid);if(t&&!t.disabled){t.click()}e.preventDefault()},i.uid);i.bind("Refresh",function(){s=parseInt(c,10)||1;m.get(l.browse_button).style.zIndex=s;this.getRuntime().getShimContainer().style.zIndex=s-1})}u=n.can("summon_file_dialog")?a:r;h.addEvent(u,"mouseover",function(){i.trigger("mouseenter")},i.uid);h.addEvent(u,"mouseout",function(){i.trigger("mouseleave")},i.uid);h.addEvent(u,"mousedown",function(){i.trigger("mousedown")},i.uid);h.addEvent(m.get(l.container),"mouseup",function(){i.trigger("mouseup")},i.uid);(n.can("summon_file_dialog")?t:a).setAttribute("tabindex",-1);t.onchange=function e(){i.files=[];d.each(this.files,function(e){var t="";if(l.directory){if(e.name=="."){return true}}if(e.webkitRelativePath){t="/"+e.webkitRelativePath.replace(/^\//,"")}e=new f(n.uid,e);e.relativePath=t;i.files.push(e)});if(g.browser!=="IE"&&g.browser!=="IEMobile"){this.value=""}else{var t=this.cloneNode(true);this.parentNode.replaceChild(t,this);t.onchange=e}if(i.files.length){i.trigger("change")}};i.trigger({type:"ready",async:true});r=null},setOption:function(e,t){var i=this.getRuntime();var n=m.get(i.uid);switch(e){case"accept":if(t){var r=t.mimes||p.extList2mimes(t,i.can("filter_by_extension"));n.setAttribute("accept",r.join(","))}else{n.removeAttribute("accept")}break;case"directory":if(t&&i.can("select_folder")){n.setAttribute("directory","");n.setAttribute("webkitdirectory","")}else{n.removeAttribute("directory");n.removeAttribute("webkitdirectory")}break;case"multiple":if(t&&i.can("select_multiple")){n.setAttribute("multiple","")}else{n.removeAttribute("multiple")}}},disable:function(e){var t=this.getRuntime(),i;if(i=m.get(t.uid)){i.disabled=!!e}},destroy:function(){var e=this.getRuntime(),t=e.getShim(),i=e.getShimContainer(),n=l&&m.get(l.container),r=l&&m.get(l.browse_button);if(n){h.removeAllEvents(n,this.uid)}if(r){h.removeAllEvents(r,this.uid);r.style.zIndex=c}if(i){h.removeAllEvents(i,this.uid);i.innerHTML=""}t.removeInstance(this.uid);l=i=n=r=t=null}})}return e.FileInput=t});e("moxie/runtime/html5/file/FileDrop",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime"],function(e,h,p,t,g,i){function n(){var n=[],r=[],o,a;p.extend(this,{init:function(e){var t=this,i;o=e;a=t.ruid;r=l(o.accept);i=o.container;g.addEvent(i,"dragover",function(e){if(!s(e)){return}e.preventDefault();e.dataTransfer.dropEffect="copy"},t.uid);g.addEvent(i,"drop",function(e){if(!s(e)){return}e.preventDefault();n=[];if(e.dataTransfer.items&&e.dataTransfer.items[0].webkitGetAsEntry){f(e.dataTransfer.items,function(){t.files=n;t.trigger("drop")})}else{p.each(e.dataTransfer.files,function(e){u(e)});t.files=n;t.trigger("drop")}},t.uid);g.addEvent(i,"dragenter",function(e){t.trigger("dragenter")},t.uid);g.addEvent(i,"dragleave",function(e){t.trigger("dragleave")},t.uid)},destroy:function(){g.removeAllEvents(o&&t.get(o.container),this.uid);a=n=r=o=null;this.getRuntime().getShim().removeInstance(this.uid)}});function s(e){if(!e.dataTransfer||!e.dataTransfer.types){return false}var t=p.toArray(e.dataTransfer.types||[]);return p.inArray("Files",t)!==-1||p.inArray("public.file-url",t)!==-1||p.inArray("application/x-moz-file",t)!==-1}function u(e,t){if(c(e)){var i=new h(a,e);i.relativePath=t||"";n.push(i)}}function l(e){var t=[];for(var i=0;i=")&&w.verComp(w.version,7,"<"),t=w.browser==="Android Browser",o=false;u=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase();s=c();s.open(n.method,n.url,n.async,n.user,n.password);if(i instanceof g){if(i.isDetached()){o=true}i=i.getSource()}else if(i instanceof v){if(i.hasBlob()){if(i.getBlob().isDetached()){i=f.call(r,i);o=true}else if((e||t)&&d.typeOf(i.getBlob().getSource())==="blob"&&window.FileReader){l.call(r,n,i);return}}if(i instanceof v){var a=new window.FormData;i.each(function(e,t){if(e instanceof g){a.append(t,e.getSource())}else{a.append(t,e)}});i=a}}if(s.upload){if(n.withCredentials){s.withCredentials=true}s.addEventListener("load",function(e){r.trigger(e)});s.addEventListener("error",function(e){r.trigger(e)});s.addEventListener("progress",function(e){r.trigger(e)});s.upload.addEventListener("progress",function(e){r.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})}else{s.onreadystatechange=function e(){switch(s.readyState){case 1:break;case 2:break;case 3:var t,i;try{if(h.hasSameOrigin(n.url)){t=s.getResponseHeader("Content-Length")||0}if(s.responseText){i=s.responseText.length}}catch(e){t=i=0}r.trigger({type:"progress",lengthComputable:!!t,total:parseInt(t,10),loaded:i});break;case 4:s.onreadystatechange=function(){};try{if(s.status>=200&&s.status<400){r.trigger("load");break}}catch(e){}r.trigger("error");break}}}if(!d.isEmptyObj(n.headers)){d.each(n.headers,function(e,t){s.setRequestHeader(t,e)})}if(""!==n.responseType&&"responseType"in s){if("json"===n.responseType&&!w.can("return_response_type","json")){s.responseType="text"}else{s.responseType=n.responseType}}if(!o){s.send(i)}else{if(s.sendAsBinary){s.sendAsBinary(i)}else{(function(){var e=new Uint8Array(i.length);for(var t=0;tthis.length()){throw new Error("You are trying to read outside the source boundaries.")}n=this.littleEndian?0:-8*(t-1);for(r=0,i=0;rthis.length()){throw new Error("You are trying to write outside the source boundaries.")}n=this.littleEndian?0:-8*(i-1);for(r=0;r>Math.abs(n+r*8)&255)}},BYTE:function(e){return this.read(e,1)},SHORT:function(e){return this.read(e,2)},LONG:function(e){return this.read(e,4)},SLONG:function(e){var t=this.read(e,4);return t>2147483647?t-4294967296:t},CHAR:function(e){return String.fromCharCode(this.read(e,1))},STRING:function(e,t){return this.asArray("CHAR",e,t).join("")},asArray:function(e,t,i){var n=[];for(var r=0;r0){n.set(new Uint8Array(r.slice(0,e)),0)}n.set(new Uint8Array(i),e);n.set(new Uint8Array(r.slice(e+t)),e+i.byteLength);this.clear();r=n.buffer;o=new DataView(r);break}default:return r}},length:function(){return r?r.byteLength:0},clear:function(){o=r=null}})}function n(n){e.extend(this,{readByteAt:function(e){return n.charCodeAt(e)},writeByteAt:function(e,t){r(String.fromCharCode(t),e,1)},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return n.substr(e);case 2:return n.substr(e,t);case 3:r(i!==null?i:"",e,t);break;default:return n}},length:function(){return n?n.length:0},clear:function(){n=null}});function r(e,t,i){i=arguments.length===3?i:n.length-t-1;n=n.substr(0,t)+e+n.substr(i+t)}}return t});e("moxie/runtime/html5/image/JPEGHeaders",["moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(s,u){return function o(e){var a=[],t,r,i,n=0;t=new s(e);if(t.SHORT(0)!==65496){t.clear();throw new u.ImageError(u.ImageError.WRONG_FORMAT)}r=2;while(r<=t.length()){i=t.SHORT(r);if(i>=65488&&i<=65495){r+=2;continue}if(i===65498||i===65497){break}n=t.SHORT(r+2)+2;if(i>=65505&&i<=65519){a.push({hex:i,name:"APP"+(i&15),start:r,length:n,segment:t.SEGMENT(r,n)})}r+=n}t.clear();return{headers:a,restore:function(e){var t,i,n;n=new s(e);r=n.SHORT(2)==65504?4+n.SHORT(4):2;for(i=0,t=a.length;i=i.length){break}}},purge:function(){this.headers=a=[]}}}});e("moxie/runtime/html5/image/ExifParser",["moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(v,s,x){function u(e){var t,c,p,g,i,n;s.call(this,e);c={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"},thumb:{513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength"}};p={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}};g={tiffHeader:10};i=g.tiffHeader;t={clear:this.clear};v.extend(this,{read:function(){try{return u.prototype.read.apply(this,arguments)}catch(e){throw new x.ImageError(x.ImageError.INVALID_META_ERR)}},write:function(){try{return u.prototype.write.apply(this,arguments)}catch(e){throw new x.ImageError(x.ImageError.INVALID_META_ERR)}},UNDEFINED:function(){return this.BYTE.apply(this,arguments)},RATIONAL:function(e){return this.LONG(e)/this.LONG(e+4)},SRATIONAL:function(e){return this.SLONG(e)/this.SLONG(e+4)},ASCII:function(e){return this.CHAR(e)},TIFF:function(){return n||null},EXIF:function(){var e=null;if(g.exifIFD){try{e=o.call(this,g.exifIFD,c.exif)}catch(e){return null}if(e.ExifVersion&&v.typeOf(e.ExifVersion)==="array"){for(var t=0,i="";t4){l=i.LONG(l)+g.tiffHeader}if(l+u*s>=this.length()){throw new x.ImageError(x.ImageError.INVALID_META_ERR)}if(a==="ASCII"){d[o]=v.trim(i.STRING(l,s).replace(/\0$/,""));continue}else{f=i.asArray(a,l,s);c=s==1?f[0]:f;if(p.hasOwnProperty(o)&&typeof c!="object"){d[o]=p[o][c]}else{d[o]=c}}}return d}function a(e,t,i){var n,r,o,a=0;if(typeof t==="string"){var s=c[e.toLowerCase()];for(var u in s){if(s[u]===t){t=u;break}}}n=g[e.toLowerCase()+"IFD"];r=this.SHORT(n);for(var l=0;l=65472&&i<=65475){t+=5;return{height:e.SHORT(t),width:e.SHORT(t+=2)}}n=e.SHORT(t+=2);t+=n-2}return null}function a(){var e=n.thumb(),t,i;if(e){t=new f(e);i=o(t);t.clear();if(i){i.data=e;return i}}return null}function s(){if(!n||!i||!r){return}n.clear();i.purge();r.clear();t=i=n=r=null}}return e});e("moxie/runtime/html5/image/PNG",["moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader"],function(u,l,c){function e(e){var o,t,i,n;o=new c(e);(function(){var e=0,t=0,i=[35152,20039,3338,6666];for(t=0;te.height?"width":"height";var r=Math.round(e[n]*t);var o=false;if(i!=="nearest"&&(t<.5||t>2)){t=t<.5?.5:2;o=true}var a=u(e,t);if(o){return s(a,r/a[n],i)}else{return a}}function u(e,t){var i=e.width;var n=e.height;var r=Math.round(i*t);var o=Math.round(n*t);var a=document.createElement("canvas");a.width=r;a.height=o;a.getContext("2d").drawImage(e,0,0,i,n,0,0,r,o);e=null;return a}return{scale:s}});e("moxie/runtime/html5/image/Image",["moxie/runtime/html5/Runtime","moxie/core/utils/Basic","moxie/core/Exceptions","moxie/core/utils/Encode","moxie/file/Blob","moxie/file/File","moxie/runtime/html5/image/ImageInfo","moxie/runtime/html5/image/ResizerCanvas","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,x,w,y,E,b,_,R,I,t){function i(){var n=this,i,r,o,a,s,u=false,l=true;x.extend(this,{loadFromBlob:function(e){var t=this.getRuntime(),i=arguments.length>1?arguments[1]:true;if(!t.can("access_binary")){throw new w.RuntimeError(w.RuntimeError.NOT_SUPPORTED_ERR)}s=e;if(e.isDetached()){a=e.getSource();h.call(this,a);return}else{p.call(this,e.getSource(),function(e){if(i){a=d(e)}h.call(this,e)})}},loadFromImage:function(e,t){this.meta=e.meta;s=new b(null,{name:e.name,size:e.size,type:e.type});h.call(this,t?a=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var e=this.getRuntime(),t;if(!r&&a&&e.can("access_image_binary")){r=new _(a)}t={width:c().width||0,height:c().height||0,type:s.type||I.getFileMime(s.name),size:a&&a.length||s.size||0,name:s.name||"",meta:null};if(l){t.meta=r&&r.meta||this.meta||{};if(t.meta&&t.meta.thumb&&!(t.meta.thumb.data instanceof E)){t.meta.thumb.data=new E(null,{type:"image/jpeg",data:t.meta.thumb.data})}}return t},resize:function(e,t,i){var n=document.createElement("canvas");n.width=e.width;n.height=e.height;n.getContext("2d").drawImage(c(),e.x,e.y,e.width,e.height,0,0,n.width,n.height);o=R.scale(n,t);l=i.preserveHeaders;if(!l){var r=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1;o=g(o,r)}this.width=o.width;this.height=o.height;u=true;this.trigger("Resize")},getAsCanvas:function(){if(!o){o=f()}o.id=this.uid+"_canvas";return o},getAsBlob:function(e,t){if(e!==this.type){u=true;return new b(null,{name:s.name||"",type:e,data:n.getAsDataURL(e,t)})}return new b(null,{name:s.name||"",type:e,data:n.getAsBinaryString(e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!u){return i.src}f();if("image/jpeg"!==e){return o.toDataURL("image/png")}else{try{return o.toDataURL("image/jpeg",t/100)}catch(e){return o.toDataURL("image/jpeg")}}},getAsBinaryString:function(e,t){if(!u){if(!a){a=d(n.getAsDataURL(e,t))}return a}if("image/jpeg"!==e){a=d(n.getAsDataURL(e,t))}else{var i;if(!t){t=90}f();try{i=o.toDataURL("image/jpeg",t/100)}catch(e){i=o.toDataURL("image/jpeg")}a=d(i);if(r){a=r.stripHeaders(a);if(l){if(r.meta&&r.meta.exif){r.setExif({PixelXDimension:this.width,PixelYDimension:this.height})}a=r.writeHeaders(a)}r.purge();r=null}}u=false;return a},destroy:function(){n=null;v.call(this);this.getRuntime().getShim().removeInstance(this.uid)}});function c(){if(!o&&!i){throw new w.ImageError(w.DOMException.INVALID_STATE_ERR)}return o||i}function f(){var e=c();if(e.nodeName.toLowerCase()=="canvas"){return e}o=document.createElement("canvas");o.width=e.width;o.height=e.height;o.getContext("2d").drawImage(e,0,0);return o}function d(e){return y.atob(e.substring(e.indexOf("base64,")+7))}function m(e,t){return"data:"+(t||"")+";base64,"+y.btoa(e)}function h(e){var t=this;i=new Image;i.onerror=function(){v.call(this);t.trigger("error",w.ImageError.WRONG_FORMAT)};i.onload=function(){t.trigger("load")};i.src=e.substr(0,5)=="data:"?e:m(e,s.type)}function p(e,t){var i=this,n;if(window.FileReader){n=new FileReader;n.onload=function(){t.call(i,this.result)};n.onerror=function(){i.trigger("error",w.ImageError.WRONG_FORMAT)};n.readAsDataURL(e)}else{return t.call(this,e.getAsDataURL())}}function g(e,t){var i=Math.PI/180;var n=document.createElement("canvas");var r=n.getContext("2d");var o=e.width;var a=e.height;if(x.inArray(t,[5,6,7,8])>-1){n.width=a;n.height=o}else{n.width=o;n.height=a}switch(t){case 2:r.translate(o,0);r.scale(-1,1);break;case 3:r.translate(o,a);r.rotate(180*i);break;case 4:r.translate(0,a);r.scale(1,-1);break;case 5:r.rotate(90*i);r.scale(1,-1);break;case 6:r.rotate(90*i);r.translate(0,-a);break;case 7:r.rotate(90*i);r.translate(o,-a);r.scale(-1,1);break;case 8:r.rotate(-90*i);r.translate(-o,0);break}r.drawImage(e,0,0,o,a);return n}function v(){if(r){r.purge();r=null}a=i=o=s=null;u=false}}return e.Image=i});e("moxie/runtime/flash/Runtime",["moxie/core/utils/Basic","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/runtime/Runtime"],function(a,s,u,l,c){var e="flash",t={};function i(){var t;try{t=navigator.plugins["Shockwave Flash"];t=t.description}catch(e){try{t=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(e){t="0.0"}}t=t.match(/\d+/g);return parseFloat(t[0]+"."+t[1])}function f(t){var i=u.get(t);if(i&&i.nodeName=="OBJECT"){if(s.browser==="IE"){i.style.display="none";(function e(){if(i.readyState==4){n(t)}else{setTimeout(e,10)}})()}else{i.parentNode.removeChild(i)}}}function n(e){var t=u.get(e);if(t){for(var i in t){if(typeof t[i]=="function"){t[i]=null}}t.parentNode.removeChild(t)}}function r(n){var r=this,o;n=a.extend({swf_url:s.swf_url},n);c.call(this,n,e,{access_binary:function(e){return e&&r.mode==="browser"},access_image_binary:function(e){return e&&r.mode==="browser"},display_media:c.capTest(d("moxie/image/Image")),do_cors:c.capTrue,drag_and_drop:false,report_upload_progress:function(){return r.mode==="client"},resize_image:c.capTrue,return_response_headers:false,return_response_type:function(e){if(e==="json"&&!!window.JSON){return true}return!a.arrayDiff(e,["","text","document"])||r.mode==="browser"},return_status_code:function(e){return r.mode==="browser"||!a.arrayDiff(e,[200,404])},select_file:c.capTrue,select_multiple:c.capTrue,send_binary_string:function(e){return e&&r.mode==="browser"},send_browser_cookies:function(e){return e&&r.mode==="browser"},send_custom_headers:function(e){return e&&r.mode==="browser"},send_multipart:c.capTrue,slice_blob:function(e){return e&&r.mode==="browser"},stream_upload:function(e){return e&&r.mode==="browser"},summon_file_dialog:false,upload_filesize:function(e){return a.parseSizeStr(e)<=2097152||r.mode==="client"},use_http_method:function(e){return!a.arrayDiff(e,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(e){return a.arrayDiff(e,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(e){return a.arrayDiff(e,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},slice_blob:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(e){return a.parseSizeStr(e)>=2097152?"client":"browser"}},"client");if(i()<11.3){if(MXI_DEBUG&&s.debug.runtime){s.log("\tFlash didn't meet minimal version requirement (11.3).")}this.mode=false}a.extend(this,{getShim:function(){return u.get(this.uid)},shimExec:function(e,t){var i=[].slice.call(arguments,2);return r.getShim().exec(this.uid,e,t,i)},init:function(){var e,t,i;i=this.getShimContainer();a.extend(i.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"});e=''+''+''+''+"";if(s.browser==="IE"){t=document.createElement("div");i.appendChild(t);t.outerHTML=e;t=i=null}else{i.innerHTML=e}o=setTimeout(function(){if(r&&!r.initialized){r.trigger("Error",new l.RuntimeError(l.RuntimeError.NOT_INIT_ERR));if(MXI_DEBUG&&s.debug.runtime){s.log("\tFlash failed to initialize within a specified period of time (typically 5s).")}}},5e3)},destroy:function(e){return function(){f(r.uid);e.call(r);clearTimeout(o);n=o=e=r=null}}(this.destroy)},t)}c.addConstructor(e,r);return t});e("moxie/runtime/flash/file/Blob",["moxie/runtime/flash/Runtime","moxie/file/Blob"],function(e,o){var t={slice:function(e,t,i,n){var r=this.getRuntime();if(t<0){t=Math.max(e.size+t,0)}else if(t>0){t=Math.min(t,e.size)}if(i<0){i=Math.max(e.size+i,0)}else if(i>0){i=Math.min(i,e.size)}e=r.shimExec.call(this,"Blob","slice",t,i,n||"");if(e){e=new o(r.uid,e)}return e}};return e.Blob=t});e("moxie/runtime/flash/file/FileInput",["moxie/runtime/flash/Runtime","moxie/file/File","moxie/core/utils/Dom","moxie/core/utils/Basic"],function(e,r,o,a){var t={init:function(e){var t=this,i=this.getRuntime();var n=o.get(e.browse_button);if(n){n.setAttribute("tabindex",-1);n=null}this.bind("Change",function(){var e=i.shimExec.call(t,"FileInput","getFiles");t.files=[];a.each(e,function(e){t.files.push(new r(i.uid,e))})},999);this.getRuntime().shimExec.call(this,"FileInput","init",{accept:e.accept,multiple:e.multiple});this.trigger("ready")}};return e.FileInput=t});e("moxie/runtime/flash/file/FileReader",["moxie/runtime/flash/Runtime","moxie/core/utils/Encode"],function(e,i){function r(e,t){switch(t){case"readAsText":return i.atob(e,"utf8");case"readAsBinaryString":return i.atob(e);case"readAsDataURL":return e}return null}var t={read:function(i,e){var n=this;n.result="";if(i==="readAsDataURL"){n.result="data:"+(e.type||"")+";base64,"}n.bind("Progress",function(e,t){if(t){n.result+=r(t,i)}},999);return n.getRuntime().shimExec.call(this,"FileReader","readAsBase64",e.uid)}};return e.FileReader=t});e("moxie/runtime/flash/file/FileReaderSync",["moxie/runtime/flash/Runtime","moxie/core/utils/Encode"],function(e,i){function r(e,t){switch(t){case"readAsText":return i.atob(e,"utf8");case"readAsBinaryString":return i.atob(e);case"readAsDataURL":return e}return null}var t={read:function(e,t){var i,n=this.getRuntime();i=n.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid);if(!i){return null}if(e==="readAsDataURL"){i="data:"+(t.type||"")+";base64,"+i}return r(i,e,t.type)}};return e.FileReaderSync=t});e("moxie/runtime/flash/runtime/Transporter",["moxie/runtime/flash/Runtime","moxie/file/Blob"],function(e,n){var t={getAsBlob:function(e){var t=this.getRuntime(),i=t.shimExec.call(this,"Transporter","getAsBlob",e);if(i){return new n(t.uid,i)}return null}};return e.Transporter=t});e("moxie/runtime/flash/xhr/XMLHttpRequest",["moxie/runtime/flash/Runtime","moxie/core/utils/Basic","moxie/file/Blob","moxie/file/File","moxie/file/FileReaderSync","moxie/runtime/flash/file/FileReaderSync","moxie/xhr/FormData","moxie/runtime/Transporter","moxie/runtime/flash/runtime/Transporter"],function(e,l,c,r,o,t,f,d,i){var n={send:function(e,i){var n=this,r=n.getRuntime();function o(){e.transport=r.mode;r.shimExec.call(n,"XMLHttpRequest","send",e,i)}function t(e,t){r.shimExec.call(n,"XMLHttpRequest","appendBlob",e,t.uid);i=null;o()}function a(e,t){var i=new d;i.bind("TransportingComplete",function(){t(this.result)});i.transport(e.getSource(),e.type,{ruid:r.uid})}if(!l.isEmptyObj(e.headers)){l.each(e.headers,function(e,t){r.shimExec.call(n,"XMLHttpRequest","setRequestHeader",t,e.toString())})}if(i instanceof f){var s;i.each(function(e,t){if(e instanceof c){s=t}else{r.shimExec.call(n,"XMLHttpRequest","append",t,e)}});if(!i.hasBlob()){i=null;o()}else{var u=i.getBlob();if(u.isDetached()){a(u,function(e){u.destroy();t(s,e)})}else{t(s,u)}}}else if(i instanceof c){if(i.isDetached()){a(i,function(e){i.destroy();i=e.uid;o()})}else{i=i.uid;o()}}else{o()}},getResponse:function(e){var t,i,n=this.getRuntime();i=n.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob");if(i){i=new r(n.uid,i);if("blob"===e){return i}try{t=new o;if(!!~l.inArray(e,["","text"])){return t.readAsText(i)}else if("json"===e&&!!window.JSON){return JSON.parse(t.readAsText(i))}}finally{i.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort");this.dispatchEvent("readystatechange");this.dispatchEvent("abort")}};return e.XMLHttpRequest=n});e("moxie/runtime/flash/image/Image",["moxie/runtime/flash/Runtime","moxie/core/utils/Basic","moxie/runtime/Transporter","moxie/file/Blob","moxie/file/FileReaderSync"],function(e,t,o,r,n){var i={loadFromBlob:function(e){var t=this,i=t.getRuntime();function n(e){i.shimExec.call(t,"Image","loadFromBlob",e.uid);t=i=null}if(e.isDetached()){var r=new o;r.bind("TransportingComplete",function(){n(r.result.getSource())});r.transport(e.getSource(),e.type,{ruid:i.uid})}else{n(e.getSource())}},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getInfo:function(){var e=this.getRuntime(),t=e.shimExec.call(this,"Image","getInfo");if(t.meta&&t.meta.thumb&&t.meta.thumb.data&&!(e.meta.thumb.data instanceof r)){t.meta.thumb.data=new r(e.uid,t.meta.thumb.data)}return t},getAsBlob:function(e,t){var i=this.getRuntime(),n=i.shimExec.call(this,"Image","getAsBlob",e,t);if(n){return new r(i.uid,n)}return null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),i;if(!t){return null}i=new n;return i.readAsDataURL(t)}};return e.Image=i});e("moxie/runtime/silverlight/Runtime",["moxie/core/utils/Basic","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/runtime/Runtime"],function(r,o,e,a,s){var u="silverlight",l={};function c(t){var i=false,e=null,n,r,o,a,s,u=0;try{try{e=new ActiveXObject("AgControl.AgControl");if(e.IsVersionSupported(t)){i=true}e=null}catch(e){var l=navigator.plugins["Silverlight Plug-In"];if(l){n=l.description;if(n==="1.0.30226.2"){n="2.0.30226.2"}r=n.split(".");while(r.length>3){r.pop()}while(r.length<4){r.push(0)}o=t.split(".");while(o.length>4){o.pop()}do{a=parseInt(o[u],10);s=parseInt(r[u],10);u++}while(u'+''+''+''+''+''+"";i=setTimeout(function(){if(n&&!n.initialized){n.trigger("Error",new a.RuntimeError(a.RuntimeError.NOT_INIT_ERR));if(MXI_DEBUG&&o.debug.runtime){o.log("Silverlight failed to initialize within a specified period of time (5-10s).")}}},o.OS!=="Windows"?1e4:5e3)},destroy:function(e){return function(){e.call(n);clearTimeout(i);t=i=e=n=null}}(this.destroy)},l)}s.addConstructor(u,t);return l});e("moxie/runtime/silverlight/file/Blob",["moxie/runtime/silverlight/Runtime","moxie/core/utils/Basic","moxie/runtime/flash/file/Blob"],function(e,t,i){return e.Blob=t.extend({},i)});e("moxie/runtime/silverlight/file/FileInput",["moxie/runtime/silverlight/Runtime","moxie/file/File","moxie/core/utils/Dom","moxie/core/utils/Basic"],function(e,r,o,a){function s(e){var t="";for(var i=0;i