2 * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
4 * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/
6 * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
7 * http://www.opensource.org/licenses/mit-license.php
9 * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
10 * http://www.opensource.org/licenses/mit-license.php
12 * SWFObject v2.2 <http://code.google.com/p/swfobject/>
13 * is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
18 /* ******************* */
19 /* Constructor & Init */
20 /* ******************* */
24 if (SWFUpload == undefined) {
25 SWFUpload = function (settings) {
26 this.initSWFUpload(settings);
30 SWFUpload.prototype.initSWFUpload = function (userSettings) {
32 this.customSettings = {}; // A container where developers can place their own settings associated with this instance.
35 this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
36 this.movieElement = null;
39 // Setup global control tracking
40 SWFUpload.instances[this.movieName] = this;
42 // Load the settings. Load the Flash movie.
43 this.initSettings(userSettings);
45 if (this.swfuploadPreload()) {
49 this.displayDebugInfo();
51 delete SWFUpload.instances[this.movieName];
59 SWFUpload.instances = {};
60 SWFUpload.movieCount = 0;
61 SWFUpload.version = "2.5.0 2010-01-15 Beta 2";
62 SWFUpload.QUEUE_ERROR = {
63 QUEUE_LIMIT_EXCEEDED : -100,
64 FILE_EXCEEDS_SIZE_LIMIT : -110,
65 ZERO_BYTE_FILE : -120,
66 INVALID_FILETYPE : -130
68 SWFUpload.UPLOAD_ERROR = {
70 MISSING_UPLOAD_URL : -210,
72 SECURITY_ERROR : -230,
73 UPLOAD_LIMIT_EXCEEDED : -240,
75 SPECIFIED_FILE_ID_NOT_FOUND : -260,
76 FILE_VALIDATION_FAILED : -270,
77 FILE_CANCELLED : -280,
78 UPLOAD_STOPPED : -290,
81 SWFUpload.FILE_STATUS = {
88 SWFUpload.UPLOAD_TYPE = {
93 SWFUpload.BUTTON_ACTION = {
97 JAVASCRIPT : -130, // DEPRECATED
104 SWFUpload.WINDOW_MODE = {
106 TRANSPARENT : "transparent",
110 SWFUpload.RESIZE_ENCODING = {
115 // Private: takes a URL, determines if it is relative and converts to an absolute URL
116 // using the current site. Only processes the URL if it can, otherwise returns the URL untouched
117 SWFUpload.completeURL = function (url) {
119 var path = "", indexSlash = -1;
120 if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//) || url === "") {
124 indexSlash = window.location.pathname.lastIndexOf("/");
125 if (indexSlash <= 0) {
128 path = window.location.pathname.substr(0, indexSlash) + "/";
137 // Public: assign a new function to onload to use swfobject's domLoad functionality
138 SWFUpload.onload = function () {};
141 /* ******************** */
142 /* Instance Members */
143 /* ******************** */
145 // Private: initSettings ensures that all the
146 // settings are set, getting a default value if one was not assigned.
147 SWFUpload.prototype.initSettings = function (userSettings) {
148 this.ensureDefault = function (settingName, defaultValue) {
149 var setting = userSettings[settingName];
150 if (setting != undefined) {
151 this.settings[settingName] = setting;
153 this.settings[settingName] = defaultValue;
157 // Upload backend settings
158 this.ensureDefault("upload_url", "");
159 this.ensureDefault("preserve_relative_urls", false);
160 this.ensureDefault("file_post_name", "Filedata");
161 this.ensureDefault("post_params", {});
162 this.ensureDefault("use_query_string", false);
163 this.ensureDefault("requeue_on_error", false);
164 this.ensureDefault("http_success", []);
165 this.ensureDefault("assume_success_timeout", 0);
168 this.ensureDefault("file_types", "*.*");
169 this.ensureDefault("file_types_description", "All Files");
170 this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited"
171 this.ensureDefault("file_upload_limit", 0);
172 this.ensureDefault("file_queue_limit", 0);
175 this.ensureDefault("flash_url", "swfupload.swf");
176 this.ensureDefault("flash9_url", "swfupload_fp9.swf");
177 this.ensureDefault("prevent_swf_caching", true);
180 this.ensureDefault("button_image_url", "");
181 this.ensureDefault("button_width", 1);
182 this.ensureDefault("button_height", 1);
183 this.ensureDefault("button_text", "");
184 this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
185 this.ensureDefault("button_text_top_padding", 0);
186 this.ensureDefault("button_text_left_padding", 0);
187 this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
188 this.ensureDefault("button_disabled", false);
189 this.ensureDefault("button_placeholder_id", "");
190 this.ensureDefault("button_placeholder", null);
191 this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
192 this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
195 this.ensureDefault("debug", false);
196 this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API
199 this.settings.return_upload_start_handler = this.returnUploadStart;
200 this.ensureDefault("swfupload_preload_handler", null);
201 this.ensureDefault("swfupload_load_failed_handler", null);
202 this.ensureDefault("swfupload_loaded_handler", null);
203 this.ensureDefault("file_dialog_start_handler", null);
204 this.ensureDefault("file_queued_handler", null);
205 this.ensureDefault("file_queue_error_handler", null);
206 this.ensureDefault("file_dialog_complete_handler", null);
208 this.ensureDefault("upload_resize_start_handler", null);
209 this.ensureDefault("upload_start_handler", null);
210 this.ensureDefault("upload_progress_handler", null);
211 this.ensureDefault("upload_error_handler", null);
212 this.ensureDefault("upload_success_handler", null);
213 this.ensureDefault("upload_complete_handler", null);
215 this.ensureDefault("mouse_click_handler", null);
216 this.ensureDefault("mouse_out_handler", null);
217 this.ensureDefault("mouse_over_handler", null);
219 this.ensureDefault("debug_handler", this.debugMessage);
221 this.ensureDefault("custom_settings", {});
224 this.customSettings = this.settings.custom_settings;
226 // Update the flash url if needed
227 if (!!this.settings.prevent_swf_caching) {
228 this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
229 this.settings.flash9_url = this.settings.flash9_url + (this.settings.flash9_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
232 if (!this.settings.preserve_relative_urls) {
233 this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
234 this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
237 delete this.ensureDefault;
240 // Initializes the supported functionality based the Flash Player version, state, and event that occur during initialization
241 SWFUpload.prototype.loadSupport = function () {
243 loading : swfobject.hasFlashPlayerVersion("9.0.28"),
244 imageResize : swfobject.hasFlashPlayerVersion("10.0.0")
249 // Private: loadFlash replaces the button_placeholder element with the flash movie.
250 SWFUpload.prototype.loadFlash = function () {
251 var targetElement, tempParent, wrapperType, flashHTML, els;
253 if (!this.support.loading) {
254 this.queueEvent("swfupload_load_failed_handler", ["Flash Player doesn't support SWFUpload"]);
258 // Make sure an element with the ID we are going to use doesn't already exist
259 if (document.getElementById(this.movieName) !== null) {
260 this.support.loading = false;
261 this.queueEvent("swfupload_load_failed_handler", ["Element ID already in use"]);
265 // Get the element where we will be placing the flash movie
266 targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
268 if (targetElement == undefined) {
269 this.support.loading = false;
270 this.queueEvent("swfupload_load_failed_handler", ["button place holder not found"]);
274 wrapperType = (targetElement.currentStyle && targetElement.currentStyle["display"] || window.getComputedStyle && document.defaultView.getComputedStyle(targetElement, null).getPropertyValue("display")) !== "block" ? "span" : "div";
276 // Append the container and load the flash
277 tempParent = document.createElement(wrapperType);
279 flashHTML = this.getFlashHTML();
282 tempParent.innerHTML = flashHTML; // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
284 this.support.loading = false;
285 this.queueEvent("swfupload_load_failed_handler", ["Exception loading Flash HTML into placeholder"]);
289 // Try to get the movie element immediately
290 els = tempParent.getElementsByTagName("object");
291 if (!els || els.length > 1 || els.length === 0) {
292 this.support.loading = false;
293 this.queueEvent("swfupload_load_failed_handler", ["Unable to find movie after adding to DOM"]);
295 } else if (els.length === 1) {
296 this.movieElement = els[0];
299 targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
301 // Fix IE Flash/Form bug
302 if (window[this.movieName] == undefined) {
303 window[this.movieName] = this.getMovieElement();
307 // Private: getFlashHTML generates the object tag needed to embed the flash in to the document
308 SWFUpload.prototype.getFlashHTML = function (flashVersion) {
309 // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
310 return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', (this.support.imageResize ? this.settings.flash_url : this.settings.flash9_url), '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
311 '<param name="wmode" value="', this.settings.button_window_mode, '" />',
312 '<param name="movie" value="', (this.support.imageResize ? this.settings.flash_url : this.settings.flash9_url), '" />',
313 '<param name="quality" value="high" />',
314 '<param name="allowScriptAccess" value="always" />',
315 '<param name="flashvars" value="' + this.getFlashVars() + '" />',
316 '</object>'].join("");
319 // Private: getFlashVars builds the parameter string that will be passed
320 // to flash in the flashvars param.
321 SWFUpload.prototype.getFlashVars = function () {
322 // Build a string from the post param object
323 var httpSuccessString, paramString;
325 paramString = this.buildParamString();
326 httpSuccessString = this.settings.http_success.join(",");
328 // Build the parameter string
329 return ["movieName=", encodeURIComponent(this.movieName),
330 "&uploadURL=", encodeURIComponent(this.settings.upload_url),
331 "&useQueryString=", encodeURIComponent(this.settings.use_query_string),
332 "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
333 "&httpSuccess=", encodeURIComponent(httpSuccessString),
334 "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
335 "&params=", encodeURIComponent(paramString),
336 "&filePostName=", encodeURIComponent(this.settings.file_post_name),
337 "&fileTypes=", encodeURIComponent(this.settings.file_types),
338 "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
339 "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
340 "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
341 "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
342 "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
343 "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
344 "&buttonWidth=", encodeURIComponent(this.settings.button_width),
345 "&buttonHeight=", encodeURIComponent(this.settings.button_height),
346 "&buttonText=", encodeURIComponent(this.settings.button_text),
347 "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
348 "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
349 "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
350 "&buttonAction=", encodeURIComponent(this.settings.button_action),
351 "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
352 "&buttonCursor=", encodeURIComponent(this.settings.button_cursor)
356 // Public: get retrieves the DOM reference to the Flash element added by SWFUpload
357 // The element is cached after the first lookup
358 SWFUpload.prototype.getMovieElement = function () {
359 if (this.movieElement == undefined) {
360 this.movieElement = document.getElementById(this.movieName);
363 if (this.movieElement === null) {
364 throw "Could not find Flash element";
367 return this.movieElement;
370 // Private: buildParamString takes the name/value pairs in the post_params setting object
371 // and joins them up in to a string formatted "name=value&name=value"
372 SWFUpload.prototype.buildParamString = function () {
373 var name, postParams, paramStringPairs = [];
375 postParams = this.settings.post_params;
377 if (typeof(postParams) === "object") {
378 for (name in postParams) {
379 if (postParams.hasOwnProperty(name)) {
380 paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
385 return paramStringPairs.join("&");
388 // Public: Used to remove a SWFUpload instance from the page. This method strives to remove
389 // all references to the SWF, and other objects so memory is properly freed.
390 // Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
391 // Credits: Major improvements provided by steffen
392 SWFUpload.prototype.destroy = function () {
396 // Make sure Flash is done before we try to remove it
397 this.cancelUpload(null, false);
399 movieElement = this.cleanUp();
401 // Remove the SWFUpload DOM nodes
403 // Remove the Movie Element from the page
405 movieElement.parentNode.removeChild(movieElement);
409 // Remove IE form fix reference
410 window[this.movieName] = null;
412 // Destroy other references
413 SWFUpload.instances[this.movieName] = null;
414 delete SWFUpload.instances[this.movieName];
416 this.movieElement = null;
417 this.settings = null;
418 this.customSettings = null;
419 this.eventQueue = null;
420 this.movieName = null;
430 // Public: displayDebugInfo prints out settings and configuration
431 // information about this SWFUpload instance.
432 // This function (and any references to it) can be deleted when placing
433 // SWFUpload in production.
434 SWFUpload.prototype.displayDebugInfo = function () {
437 "---SWFUpload Instance Info---\n",
438 "Version: ", SWFUpload.version, "\n",
439 "Movie Name: ", this.movieName, "\n",
441 "\t", "upload_url: ", this.settings.upload_url, "\n",
442 "\t", "flash_url: ", this.settings.flash_url, "\n",
443 "\t", "flash9_url: ", this.settings.flash9_url, "\n",
444 "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n",
445 "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n",
446 "\t", "http_success: ", this.settings.http_success.join(", "), "\n",
447 "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n",
448 "\t", "file_post_name: ", this.settings.file_post_name, "\n",
449 "\t", "post_params: ", this.settings.post_params.toString(), "\n",
450 "\t", "file_types: ", this.settings.file_types, "\n",
451 "\t", "file_types_description: ", this.settings.file_types_description, "\n",
452 "\t", "file_size_limit: ", this.settings.file_size_limit, "\n",
453 "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n",
454 "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n",
455 "\t", "debug: ", this.settings.debug.toString(), "\n",
457 "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n",
459 "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n",
460 "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
461 "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n",
462 "\t", "button_width: ", this.settings.button_width.toString(), "\n",
463 "\t", "button_height: ", this.settings.button_height.toString(), "\n",
464 "\t", "button_text: ", this.settings.button_text.toString(), "\n",
465 "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n",
466 "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n",
467 "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
468 "\t", "button_action: ", this.settings.button_action.toString(), "\n",
469 "\t", "button_cursor: ", this.settings.button_cursor.toString(), "\n",
470 "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n",
472 "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n",
474 "\t", "swfupload_preload_handler assigned: ", (typeof this.settings.swfupload_preload_handler === "function").toString(), "\n",
475 "\t", "swfupload_load_failed_handler assigned: ", (typeof this.settings.swfupload_load_failed_handler === "function").toString(), "\n",
476 "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
477 "\t", "mouse_click_handler assigned: ", (typeof this.settings.mouse_click_handler === "function").toString(), "\n",
478 "\t", "mouse_over_handler assigned: ", (typeof this.settings.mouse_over_handler === "function").toString(), "\n",
479 "\t", "mouse_out_handler assigned: ", (typeof this.settings.mouse_out_handler === "function").toString(), "\n",
480 "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
481 "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
482 "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
483 "\t", "upload_resize_start_handler assigned: ", (typeof this.settings.upload_resize_start_handler === "function").toString(), "\n",
484 "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
485 "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
486 "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
487 "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
488 "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
489 "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n",
492 "\t", "Load: ", (this.support.loading ? "Yes" : "No"), "\n",
493 "\t", "Image Resize: ", (this.support.imageResize ? "Yes" : "No"), "\n"
499 /* Note: addSetting and getSetting are no longer used by SWFUpload but are included
500 the maintain v2 API compatibility
502 // Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
503 SWFUpload.prototype.addSetting = function (name, value, default_value) {
504 if (value == undefined) {
505 return (this.settings[name] = default_value);
507 return (this.settings[name] = value);
511 // Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
512 SWFUpload.prototype.getSetting = function (name) {
513 if (this.settings[name] != undefined) {
514 return this.settings[name];
522 // Private: callFlash handles function calls made to the Flash element.
523 // Calls are made with a setTimeout for some functions to work around
524 // bugs in the ExternalInterface library.
525 SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
526 var movieElement, returnValue, returnString;
528 argumentArray = argumentArray || [];
529 movieElement = this.getMovieElement();
531 // Flash's method if calling ExternalInterface methods (code adapted from MooTools).
533 if (movieElement != undefined) {
534 returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
535 returnValue = eval(returnString);
537 this.debug("Can't call flash because the movie wasn't found.");
540 this.debug("Exception calling flash function '" + functionName + "': " + ex.message);
543 // Unescape file post param values
544 if (returnValue != undefined && typeof returnValue.post === "object") {
545 returnValue = this.unescapeFilePostParams(returnValue);
551 /* *****************************
552 -- Flash control methods --
553 Your UI should use these
555 ***************************** */
557 // WARNING: this function does not work in Flash Player 10
558 // Public: selectFile causes a File Selection Dialog window to appear. This
559 // dialog only allows 1 file to be selected.
560 SWFUpload.prototype.selectFile = function () {
561 this.callFlash("SelectFile");
564 // WARNING: this function does not work in Flash Player 10
565 // Public: selectFiles causes a File Selection Dialog window to appear/ This
566 // dialog allows the user to select any number of files
567 // Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
568 // If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around
570 SWFUpload.prototype.selectFiles = function () {
571 this.callFlash("SelectFiles");
575 // Public: startUpload starts uploading the first file in the queue unless
576 // the optional parameter 'fileID' specifies the ID
577 SWFUpload.prototype.startUpload = function (fileID) {
578 this.callFlash("StartUpload", [fileID]);
581 // Public: startUpload starts uploading the first file in the queue unless
582 // the optional parameter 'fileID' specifies the ID
583 SWFUpload.prototype.startResizedUpload = function (fileID, width, height, encoding, quality, allowEnlarging) {
584 this.callFlash("StartUpload", [fileID, { "width": width, "height" : height, "encoding" : encoding, "quality" : quality, "allowEnlarging" : allowEnlarging }]);
587 // Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index.
588 // If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
589 // If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
590 SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
591 if (triggerErrorEvent !== false) {
592 triggerErrorEvent = true;
594 this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
597 // Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
598 // If nothing is currently uploading then nothing happens.
599 SWFUpload.prototype.stopUpload = function () {
600 this.callFlash("StopUpload");
604 // Public: requeueUpload requeues any file. If the file is requeued or already queued true is returned.
605 // If the file is not found or is currently uploading false is returned. Requeuing a file bypasses the
606 // file size, queue size, upload limit and other queue checks. Certain files can't be requeued (e.g, invalid or zero bytes files).
607 SWFUpload.prototype.requeueUpload = function (indexOrFileID) {
608 return this.callFlash("RequeueUpload", [indexOrFileID]);
612 /* ************************
614 * These methods change the SWFUpload settings.
615 * SWFUpload settings should not be changed directly on the settings object
616 * since many of the settings need to be passed to Flash in order to take
618 * *********************** */
620 // Public: getStats gets the file statistics object.
621 SWFUpload.prototype.getStats = function () {
622 return this.callFlash("GetStats");
625 // Public: setStats changes the SWFUpload statistics. You shouldn't need to
626 // change the statistics but you can. Changing the statistics does not
627 // affect SWFUpload accept for the successful_uploads count which is used
628 // by the upload_limit setting to determine how many files the user may upload.
629 SWFUpload.prototype.setStats = function (statsObject) {
630 this.callFlash("SetStats", [statsObject]);
633 // Public: getFile retrieves a File object by ID or Index. If the file is
634 // not found then 'null' is returned.
635 SWFUpload.prototype.getFile = function (fileID) {
636 if (typeof(fileID) === "number") {
637 return this.callFlash("GetFileByIndex", [fileID]);
639 return this.callFlash("GetFile", [fileID]);
643 // Public: getFileFromQueue retrieves a File object by ID or Index. If the file is
644 // not found then 'null' is returned.
645 SWFUpload.prototype.getQueueFile = function (fileID) {
646 if (typeof(fileID) === "number") {
647 return this.callFlash("GetFileByQueueIndex", [fileID]);
649 return this.callFlash("GetFile", [fileID]);
654 // Public: addFileParam sets a name/value pair that will be posted with the
655 // file specified by the Files ID. If the name already exists then the
656 // exiting value will be overwritten.
657 SWFUpload.prototype.addFileParam = function (fileID, name, value) {
658 return this.callFlash("AddFileParam", [fileID, name, value]);
661 // Public: removeFileParam removes a previously set (by addFileParam) name/value
662 // pair from the specified file.
663 SWFUpload.prototype.removeFileParam = function (fileID, name) {
664 this.callFlash("RemoveFileParam", [fileID, name]);
667 // Public: setUploadUrl changes the upload_url setting.
668 SWFUpload.prototype.setUploadURL = function (url) {
669 this.settings.upload_url = url.toString();
670 this.callFlash("SetUploadURL", [url]);
673 // Public: setPostParams changes the post_params setting
674 SWFUpload.prototype.setPostParams = function (paramsObject) {
675 this.settings.post_params = paramsObject;
676 this.callFlash("SetPostParams", [paramsObject]);
679 // Public: addPostParam adds post name/value pair. Each name can have only one value.
680 SWFUpload.prototype.addPostParam = function (name, value) {
681 this.settings.post_params[name] = value;
682 this.callFlash("SetPostParams", [this.settings.post_params]);
685 // Public: removePostParam deletes post name/value pair.
686 SWFUpload.prototype.removePostParam = function (name) {
687 delete this.settings.post_params[name];
688 this.callFlash("SetPostParams", [this.settings.post_params]);
691 // Public: setFileTypes changes the file_types setting and the file_types_description setting
692 SWFUpload.prototype.setFileTypes = function (types, description) {
693 this.settings.file_types = types;
694 this.settings.file_types_description = description;
695 this.callFlash("SetFileTypes", [types, description]);
698 // Public: setFileSizeLimit changes the file_size_limit setting
699 SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
700 this.settings.file_size_limit = fileSizeLimit;
701 this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
704 // Public: setFileUploadLimit changes the file_upload_limit setting
705 SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
706 this.settings.file_upload_limit = fileUploadLimit;
707 this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
710 // Public: setFileQueueLimit changes the file_queue_limit setting
711 SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
712 this.settings.file_queue_limit = fileQueueLimit;
713 this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
716 // Public: setFilePostName changes the file_post_name setting
717 SWFUpload.prototype.setFilePostName = function (filePostName) {
718 this.settings.file_post_name = filePostName;
719 this.callFlash("SetFilePostName", [filePostName]);
722 // Public: setUseQueryString changes the use_query_string setting
723 SWFUpload.prototype.setUseQueryString = function (useQueryString) {
724 this.settings.use_query_string = useQueryString;
725 this.callFlash("SetUseQueryString", [useQueryString]);
728 // Public: setRequeueOnError changes the requeue_on_error setting
729 SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
730 this.settings.requeue_on_error = requeueOnError;
731 this.callFlash("SetRequeueOnError", [requeueOnError]);
734 // Public: setHTTPSuccess changes the http_success setting
735 SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
736 if (typeof http_status_codes === "string") {
737 http_status_codes = http_status_codes.replace(" ", "").split(",");
740 this.settings.http_success = http_status_codes;
741 this.callFlash("SetHTTPSuccess", [http_status_codes]);
744 // Public: setHTTPSuccess changes the http_success setting
745 SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
746 this.settings.assume_success_timeout = timeout_seconds;
747 this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
750 // Public: setDebugEnabled changes the debug_enabled setting
751 SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
752 this.settings.debug_enabled = debugEnabled;
753 this.callFlash("SetDebugEnabled", [debugEnabled]);
756 // Public: setButtonImageURL loads a button image sprite
757 SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
758 if (buttonImageURL == undefined) {
762 this.settings.button_image_url = buttonImageURL;
763 this.callFlash("SetButtonImageURL", [buttonImageURL]);
766 // Public: setButtonDimensions resizes the Flash Movie and button
767 SWFUpload.prototype.setButtonDimensions = function (width, height) {
768 this.settings.button_width = width;
769 this.settings.button_height = height;
771 var movie = this.getMovieElement();
772 if (movie != undefined) {
773 movie.style.width = width + "px";
774 movie.style.height = height + "px";
777 this.callFlash("SetButtonDimensions", [width, height]);
779 // Public: setButtonText Changes the text overlaid on the button
780 SWFUpload.prototype.setButtonText = function (html) {
781 this.settings.button_text = html;
782 this.callFlash("SetButtonText", [html]);
784 // Public: setButtonTextPadding changes the top and left padding of the text overlay
785 SWFUpload.prototype.setButtonTextPadding = function (left, top) {
786 this.settings.button_text_top_padding = top;
787 this.settings.button_text_left_padding = left;
788 this.callFlash("SetButtonTextPadding", [left, top]);
791 // Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
792 SWFUpload.prototype.setButtonTextStyle = function (css) {
793 this.settings.button_text_style = css;
794 this.callFlash("SetButtonTextStyle", [css]);
796 // Public: setButtonDisabled disables/enables the button
797 SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
798 this.settings.button_disabled = isDisabled;
799 this.callFlash("SetButtonDisabled", [isDisabled]);
801 // Public: setButtonAction sets the action that occurs when the button is clicked
802 SWFUpload.prototype.setButtonAction = function (buttonAction) {
803 this.settings.button_action = buttonAction;
804 this.callFlash("SetButtonAction", [buttonAction]);
807 // Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
808 SWFUpload.prototype.setButtonCursor = function (cursor) {
809 this.settings.button_cursor = cursor;
810 this.callFlash("SetButtonCursor", [cursor]);
813 /* *******************************
814 Flash Event Interfaces
815 These functions are used by Flash to trigger the various
818 All these functions a Private.
820 Because the ExternalInterface library is buggy the event calls
821 are added to a queue and the queue then executed by a setTimeout.
822 This ensures that events are executed in a determinate order and that
823 the ExternalInterface bugs are avoided.
824 ******************************* */
826 SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
827 // Warning: Don't call this.debug inside here or you'll create an infinite loop
830 if (argumentArray == undefined) {
832 } else if (!(argumentArray instanceof Array)) {
833 argumentArray = [argumentArray];
836 if (typeof this.settings[handlerName] === "function") {
838 this.eventQueue.push(function () {
839 this.settings[handlerName].apply(this, argumentArray);
842 // Execute the next queued event
843 setTimeout(function () {
844 self.executeNextEvent();
847 } else if (this.settings[handlerName] !== null) {
848 throw "Event handler " + handlerName + " is unknown or is not a function";
852 // Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout
853 // we must queue them in order to garentee that they are executed in order.
854 SWFUpload.prototype.executeNextEvent = function () {
855 // Warning: Don't call this.debug inside here or you'll create an infinite loop
857 var f = this.eventQueue ? this.eventQueue.shift() : null;
858 if (typeof(f) === "function") {
863 // Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
864 // properties that contain characters that are not valid for JavaScript identifiers. To work around this
865 // the Flash Component escapes the parameter names and we must unescape again before passing them along.
866 SWFUpload.prototype.unescapeFilePostParams = function (file) {
867 var reg = /[$]([0-9a-f]{4})/i, unescapedPost = {}, uk, k, match;
869 if (file != undefined) {
870 for (k in file.post) {
871 if (file.post.hasOwnProperty(k)) {
873 while ((match = reg.exec(uk)) !== null) {
874 uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
876 unescapedPost[uk] = file.post[k];
880 file.post = unescapedPost;
886 // Private: This event is called by SWFUpload Init after we've determined what the user's Flash Player supports.
887 // Use the swfupload_preload_handler event setting to execute custom code when SWFUpload has loaded.
888 // Return false to prevent SWFUpload from loading and allow your script to do something else if your required feature is
890 SWFUpload.prototype.swfuploadPreload = function () {
892 if (typeof this.settings.swfupload_preload_handler === "function") {
893 returnValue = this.settings.swfupload_preload_handler.call(this);
894 } else if (this.settings.swfupload_preload_handler != undefined) {
895 throw "upload_start_handler must be a function";
898 // Convert undefined to true so if nothing is returned from the upload_start_handler it is
899 // interpretted as 'true'.
900 if (returnValue === undefined) {
904 return !!returnValue;
907 // Private: This event is called by Flash when it has finished loading. Don't modify this.
908 // Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
909 SWFUpload.prototype.flashReady = function () {
910 // Check that the movie element is loaded correctly with its ExternalInterface methods defined
911 var movieElement = this.cleanUp();
914 this.debug("Flash called back ready but the flash movie can't be found.");
918 this.queueEvent("swfupload_loaded_handler");
921 // Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
922 // This function is called by Flash each time the ExternalInterface functions are created.
923 SWFUpload.prototype.cleanUp = function () {
924 var key, movieElement = this.getMovieElement();
926 // Pro-actively unhook all the Flash functions
928 if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
929 this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
930 for (key in movieElement) {
932 if (typeof(movieElement[key]) === "function") {
933 movieElement[key] = null;
943 // Fix Flashes own cleanup code so if the SWF Movie was removed from the page
944 // it doesn't display errors.
945 window["__flash__removeCallback"] = function (instance, name) {
948 instance[name] = null;
958 /* When the button_action is set to None this event gets fired and executes the mouse_click_handler */
959 SWFUpload.prototype.mouseClick = function () {
960 this.queueEvent("mouse_click_handler");
962 SWFUpload.prototype.mouseOver = function () {
963 this.queueEvent("mouse_over_handler");
965 SWFUpload.prototype.mouseOut = function () {
966 this.queueEvent("mouse_out_handler");
969 /* This is a chance to do something before the browse window opens */
970 SWFUpload.prototype.fileDialogStart = function () {
971 this.queueEvent("file_dialog_start_handler");
975 /* Called when a file is successfully added to the queue. */
976 SWFUpload.prototype.fileQueued = function (file) {
977 file = this.unescapeFilePostParams(file);
978 this.queueEvent("file_queued_handler", file);
982 /* Handle errors that occur when an attempt to queue a file fails. */
983 SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
984 file = this.unescapeFilePostParams(file);
985 this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
988 /* Called after the file dialog has closed and the selected files have been queued.
989 You could call startUpload here if you want the queued files to begin uploading immediately. */
990 SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
991 this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
994 SWFUpload.prototype.uploadResizeStart = function (file, resizeSettings) {
995 file = this.unescapeFilePostParams(file);
996 this.queueEvent("upload_resize_start_handler", [file, resizeSettings.width, resizeSettings.height, resizeSettings.encoding, resizeSettings.quality]);
999 SWFUpload.prototype.uploadStart = function (file) {
1000 file = this.unescapeFilePostParams(file);
1001 this.queueEvent("return_upload_start_handler", file);
1004 SWFUpload.prototype.returnUploadStart = function (file) {
1006 if (typeof this.settings.upload_start_handler === "function") {
1007 file = this.unescapeFilePostParams(file);
1008 returnValue = this.settings.upload_start_handler.call(this, file);
1009 } else if (this.settings.upload_start_handler != undefined) {
1010 throw "upload_start_handler must be a function";
1013 // Convert undefined to true so if nothing is returned from the upload_start_handler it is
1014 // interpretted as 'true'.
1015 if (returnValue === undefined) {
1019 returnValue = !!returnValue;
1021 this.callFlash("ReturnUploadStart", [returnValue]);
1026 SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
1027 file = this.unescapeFilePostParams(file);
1028 this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
1031 SWFUpload.prototype.uploadError = function (file, errorCode, message) {
1032 file = this.unescapeFilePostParams(file);
1033 this.queueEvent("upload_error_handler", [file, errorCode, message]);
1036 SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
1037 file = this.unescapeFilePostParams(file);
1038 this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
1041 SWFUpload.prototype.uploadComplete = function (file) {
1042 file = this.unescapeFilePostParams(file);
1043 this.queueEvent("upload_complete_handler", file);
1046 /* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
1047 internal debug console. You can override this event and have messages written where you want. */
1048 SWFUpload.prototype.debug = function (message) {
1049 this.queueEvent("debug_handler", message);
1053 /* **********************************
1055 The debug console is a self contained, in page location
1056 for debug message to be sent. The Debug Console adds
1057 itself to the body if necessary.
1059 The console is automatically scrolled as messages appear.
1061 If you are using your own debug handler or when you deploy to production and
1062 have debug disabled you can remove these functions to reduce the file size
1064 ********************************** */
1066 // Private: debugMessage is the default debug_handler. If you want to print debug messages
1067 // call the debug() function. When overriding the function your own function should
1068 // check to see if the debug setting is true before outputting debug information.
1069 SWFUpload.prototype.debugMessage = function (message) {
1070 var exceptionMessage, exceptionValues, key;
1072 if (this.settings.debug) {
1073 exceptionValues = [];
1075 // Check for an exception object and print it nicely
1076 if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
1077 for (key in message) {
1078 if (message.hasOwnProperty(key)) {
1079 exceptionValues.push(key + ": " + message[key]);
1082 exceptionMessage = exceptionValues.join("\n") || "";
1083 exceptionValues = exceptionMessage.split("\n");
1084 exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
1085 SWFUpload.Console.writeLine(exceptionMessage);
1087 SWFUpload.Console.writeLine(message);
1092 SWFUpload.Console = {};
1093 SWFUpload.Console.writeLine = function (message) {
1094 var console, documentForm;
1097 console = document.getElementById("SWFUpload_Console");
1100 documentForm = document.createElement("form");
1101 document.getElementsByTagName("body")[0].appendChild(documentForm);
1103 console = document.createElement("textarea");
1104 console.id = "SWFUpload_Console";
1105 console.style.fontFamily = "monospace";
1106 console.setAttribute("wrap", "off");
1107 console.wrap = "off";
1108 console.style.overflow = "auto";
1109 console.style.width = "700px";
1110 console.style.height = "350px";
1111 console.style.margin = "5px";
1112 documentForm.appendChild(console);
1115 console.value += message + "\n";
1117 console.scrollTop = console.scrollHeight - console.clientHeight;
1119 alert("Exception: " + ex.name + " Message: " + ex.message);
1124 /* SWFObject v2.2 <http://code.google.com/p/swfobject/>
1125 is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
1127 swfobject = function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
1128 swfobject.addDomLoadEvent(function () {
1129 if (typeof(SWFUpload.onload) === "function") {
1130 SWFUpload.onload.call(window);